public async void KubernetesPlannerPlanFailsWithNonDockerModules() { var edgeDefinition = new EdgeDeploymentDefinition("v1", "EdgeDeployment", new V1ObjectMeta(name: ResourceName), new List <KubernetesModule>(), null); bool getCrdCalled = false; using (var server = new KubernetesApiServer( resp: string.Empty, shouldNext: async httpContext => { string pathStr = httpContext.Request.Path.Value; string method = httpContext.Request.Method; if (string.Equals(method, "GET", StringComparison.OrdinalIgnoreCase)) { if (pathStr.Contains($"namespaces/{Namespace}/{Constants.EdgeDeployment.Plural}/{ResourceName}")) { getCrdCalled = true; await httpContext.Response.Body.WriteAsync(JsonConvert.SerializeObject(edgeDefinition).ToBody()); } } return(false); })) { IModule m1 = new NonDockerModule("module1", "v1", "unknown", ModuleStatus.Running, global::Microsoft.Azure.Devices.Edge.Agent.Core.RestartPolicy.Always, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars, string.Empty); ModuleSet addRunning = ModuleSet.Create(m1); var client = new Kubernetes(new KubernetesClientConfiguration { Host = server.Uri }); var planner = new KubernetesPlanner(Namespace, ResourceName, client, DefaultCommandFactory, ConfigProvider, EdgeletModuleOwner); await Assert.ThrowsAsync <InvalidModuleException>(() => planner.PlanAsync(addRunning, ModuleSet.Empty, RuntimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty)); Assert.True(getCrdCalled); } }
public async void KubernetesPlannerNoModulesNoPlan() { var planner = new KubernetesPlanner(Namespace, ResourceName, DefaultClient, DefaultCommandFactory, ConfigProvider); Plan addPlan = await planner.PlanAsync(ModuleSet.Empty, ModuleSet.Empty, RuntimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty); Assert.Equal(Plan.Empty, addPlan); }
public async void KubernetesPlannerNoModulesNoPlan() { var planner = new KubernetesPlanner <CombinedDockerConfig>(Ns, Hostname, DeviceId, DefaultClient, DefaultCommandFactory, DefaultConfigProvider); Plan addPlan = await planner.PlanAsync(ModuleSet.Empty, ModuleSet.Empty, RuntimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty); Assert.Equal(Plan.Empty, addPlan); }
public async void KubernetesPlannerPlanFailsWithNonDockerModules() { IModule m1 = new NonDockerModule("module1", "v1", "unknown", ModuleStatus.Running, RestartPolicy.Always, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars, string.Empty); ModuleSet addRunning = ModuleSet.Create(m1); var planner = new KubernetesPlanner(Namespace, ResourceName, DefaultClient, DefaultCommandFactory, ConfigProvider); await Assert.ThrowsAsync <InvalidModuleException>(() => planner.PlanAsync(addRunning, ModuleSet.Empty, RuntimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty)); }
public async void KubernetesPlannerShutdownTest() { IModule m1 = new DockerModule("module1", "v1", ModuleStatus.Running, global::Microsoft.Azure.Devices.Edge.Agent.Core.RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); ModuleSet current = ModuleSet.Create(m1); var planner = new KubernetesPlanner(Namespace, ResourceName, DefaultClient, DefaultCommandFactory, ConfigProvider, EdgeletModuleOwner); var plan = await planner.CreateShutdownPlanAsync(current); Assert.Equal(Plan.Empty, plan); }
public async void KubernetesPlannerPlanFailsWithNonDistinctModules() { IModule m1 = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); IModule m2 = new DockerModule("Module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); ModuleSet addRunning = ModuleSet.Create(m1, m2); var planner = new KubernetesPlanner <CombinedDockerConfig>(Ns, Hostname, DeviceId, DefaultClient, DefaultCommandFactory, DefaultConfigProvider); await Assert.ThrowsAsync <InvalidIdentityException>(() => planner.PlanAsync(addRunning, ModuleSet.Empty, RuntimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty)); }
public async void KubernetesPlannerShutdownTest() { IModule m1 = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); ModuleSet current = ModuleSet.Create(m1); var planner = new KubernetesPlanner <CombinedDockerConfig>(Ns, Hostname, DeviceId, DefaultClient, DefaultCommandFactory, DefaultConfigProvider); var plan = await planner.CreateShutdownPlanAsync(current); Assert.Equal(Plan.Empty, plan); }
public async void KubernetesPlannerEmptyPlanWhenNoChanges() { IModule m1 = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); IModule m2 = new DockerModule("module2", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); ModuleSet desired = ModuleSet.Create(m1, m2); ModuleSet current = ModuleSet.Create(m1, m2); var planner = new KubernetesPlanner(Namespace, ResourceName, DefaultClient, DefaultCommandFactory, ConfigProvider); var plan = await planner.PlanAsync(desired, current, RuntimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty); Assert.Equal(Plan.Empty, plan); }
public async void KubernetesPlannerPlanExistsWhenChangesMade() { IModule m1 = new DockerModule("module1", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); IModule m2 = new DockerModule("module2", "v1", ModuleStatus.Running, RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); ModuleSet desired = ModuleSet.Create(m1); ModuleSet current = ModuleSet.Create(m2); var planner = new KubernetesPlanner(Namespace, ResourceName, DefaultClient, DefaultCommandFactory, ConfigProvider); var plan = await planner.PlanAsync(desired, current, RuntimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty); Assert.Single(plan.Commands); Assert.True(plan.Commands.First() is EdgeDeploymentCommand); }
public async void KubernetesPlannerPlanExistsWhenNoChanges() { IModule m1 = new DockerModule("module1", "v1", ModuleStatus.Running, global::Microsoft.Azure.Devices.Edge.Agent.Core.RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); IModule m2 = new DockerModule("module2", "v1", ModuleStatus.Running, global::Microsoft.Azure.Devices.Edge.Agent.Core.RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); KubernetesConfig kc1 = new KubernetesConfig("image1", CreatePodParameters.Create(), Option.None <AuthConfig>()); KubernetesConfig kc2 = new KubernetesConfig("image2", CreatePodParameters.Create(), Option.None <AuthConfig>()); var edgeDefinition = new EdgeDeploymentDefinition("v1", "EdgeDeployment", new V1ObjectMeta(name: ResourceName), new List <KubernetesModule>() { new KubernetesModule(m1, kc1, EdgeletModuleOwner), new KubernetesModule(m2, kc2, EdgeletModuleOwner) }, null); bool getCrdCalled = false; using (var server = new KubernetesApiServer( resp: string.Empty, shouldNext: async httpContext => { string pathStr = httpContext.Request.Path.Value; string method = httpContext.Request.Method; if (string.Equals(method, "GET", StringComparison.OrdinalIgnoreCase)) { if (pathStr.Contains($"namespaces/{Namespace}/{Constants.EdgeDeployment.Plural}/{ResourceName}")) { getCrdCalled = true; await httpContext.Response.Body.WriteAsync(JsonConvert.SerializeObject(edgeDefinition, EdgeDeploymentSerialization.SerializerSettings).ToBody()); } } return(false); })) { ModuleSet desired = ModuleSet.Create(m1, m2); ModuleSet current = ModuleSet.Create(m1, m2); var client = new Kubernetes(new KubernetesClientConfiguration { Host = server.Uri }); var planner = new KubernetesPlanner(Namespace, ResourceName, client, DefaultCommandFactory, ConfigProvider, EdgeletModuleOwner); var plan = await planner.PlanAsync(desired, current, RuntimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty); Assert.True(getCrdCalled); Assert.Single(plan.Commands); Assert.True(plan.Commands.First() is EdgeDeploymentCommand); } }
public async void KubernetesPlannerPlanExistsWhenDeploymentsQueryFails() { bool getCrdCalled = false; using (var server = new KubernetesApiServer( resp: string.Empty, shouldNext: httpContext => { string pathStr = httpContext.Request.Path.Value; string method = httpContext.Request.Method; if (string.Equals(method, "GET", StringComparison.OrdinalIgnoreCase)) { if (pathStr.Contains($"namespaces/{Namespace}/{Constants.EdgeDeployment.Plural}/{ResourceName}")) { getCrdCalled = true; httpContext.Response.StatusCode = 404; } } return(Task.FromResult(false)); })) { IModule m1 = new DockerModule("module1", "v1", ModuleStatus.Running, global::Microsoft.Azure.Devices.Edge.Agent.Core.RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); IModule m2 = new DockerModule("module2", "v1", ModuleStatus.Running, global::Microsoft.Azure.Devices.Edge.Agent.Core.RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); ModuleSet desired = ModuleSet.Create(m1); ModuleSet current = ModuleSet.Create(m2); var client = new Kubernetes(new KubernetesClientConfiguration { Host = server.Uri }); var planner = new KubernetesPlanner(Namespace, ResourceName, client, DefaultCommandFactory, ConfigProvider, EdgeletModuleOwner); var plan = await planner.PlanAsync(desired, current, RuntimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty); Assert.True(getCrdCalled); Assert.Single(plan.Commands); Assert.True(plan.Commands.First() is EdgeDeploymentCommand); } }
public async void KubernetesPlannerNoModulesNoPlan() { Option <EdgeDeploymentStatus> reportedStatus = Option.None <EdgeDeploymentStatus>(); var edgeDefinition = new EdgeDeploymentDefinition("v1", "EdgeDeployment", new V1ObjectMeta(name: ResourceName), new List <KubernetesModule>(), null); bool getCrdCalled = false; using (var server = new KubernetesApiServer( resp: string.Empty, shouldNext: async httpContext => { string pathStr = httpContext.Request.Path.Value; string method = httpContext.Request.Method; if (string.Equals(method, "GET", StringComparison.OrdinalIgnoreCase)) { if (pathStr.Contains($"namespaces/{Namespace}/{Constants.EdgeDeployment.Plural}/{ResourceName}")) { getCrdCalled = true; await httpContext.Response.Body.WriteAsync(JsonConvert.SerializeObject(edgeDefinition).ToBody()); } } return(false); })) { var client = new Kubernetes(new KubernetesClientConfiguration { Host = server.Uri }); var planner = new KubernetesPlanner(Namespace, ResourceName, client, DefaultCommandFactory, ConfigProvider, EdgeletModuleOwner); Plan addPlan = await planner.PlanAsync(ModuleSet.Empty, ModuleSet.Empty, RuntimeInfo, ImmutableDictionary <string, IModuleIdentity> .Empty); Assert.True(getCrdCalled); Assert.Equal(Plan.Empty, addPlan); Assert.False(reportedStatus.HasValue); } }
protected override void Load(ContainerBuilder builder) { // IKubernetesClient builder.Register( c => { if (this.enableServiceCallTracing) { // enable tracing of k8s requests made by the client var loggerFactory = c.Resolve <ILoggerFactory>(); ILogger logger = loggerFactory.CreateLogger(typeof(Kubernetes)); ServiceClientTracing.IsEnabled = true; ServiceClientTracing.AddTracingInterceptor(new DebugTracer(logger)); } // load the k8s config from KUBECONFIG or $HOME/.kube/config or in-cluster if its available KubernetesClientConfiguration kubeConfig = Option.Maybe(Environment.GetEnvironmentVariable("KUBECONFIG")) .Else(() => Option.Maybe(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".kube", "config"))) .Filter(File.Exists) .Map(path => KubernetesClientConfiguration.BuildConfigFromConfigFile(path)) .GetOrElse(KubernetesClientConfiguration.InClusterConfig); return(new Kubernetes(kubeConfig)); }) .As <IKubernetes>() .SingleInstance(); // IModuleClientProvider builder.Register( c => new ModuleClientProvider( c.Resolve <ISdkModuleClientProvider>(), this.upstreamProtocol, this.proxy, this.productInfo.OrDefault(), this.closeOnIdleTimeout, this.idleTimeout)) .As <IModuleClientProvider>() .SingleInstance(); // IModuleManager builder.Register(c => new ModuleManagementHttpClient(this.managementUri, this.apiVersion, Core.Constants.EdgeletClientApiVersion)) .As <IModuleManager>() .As <IIdentityManager>() .SingleInstance(); // IModuleIdentityLifecycleManager var identityBuilder = new ModuleIdentityProviderServiceBuilder(this.resourceName.Hostname, this.resourceName.DeviceId, this.edgeDeviceHostName); builder.Register(c => new KubernetesModuleIdentityLifecycleManager(c.Resolve <IIdentityManager>(), identityBuilder, this.workloadUri)) .As <IModuleIdentityLifecycleManager>() .SingleInstance(); // CombinedKubernetesConfigProvider builder.Register( c => { bool enableKubernetesExtensions = this.experimentalFeatures.Enabled && this.experimentalFeatures.EnableExtensions; return(new CombinedKubernetesConfigProvider(this.dockerAuthConfig, this.workloadUri, this.managementUri, enableKubernetesExtensions)); }) .As <ICombinedConfigProvider <CombinedKubernetesConfig> >() .SingleInstance(); // ICommandFactory builder.Register( c => { var loggerFactory = c.Resolve <ILoggerFactory>(); var kubernetesCommandFactory = new KubernetesCommandFactory(); ICommandFactory factory = new LoggingCommandFactory(kubernetesCommandFactory, loggerFactory); return(Task.FromResult(factory)); }) .As <Task <ICommandFactory> >() .SingleInstance(); // IPlanner builder.Register( async c => { var configProvider = c.Resolve <ICombinedConfigProvider <CombinedKubernetesConfig> >(); ICommandFactory commandFactory = await c.Resolve <Task <ICommandFactory> >(); IPlanner planner = new KubernetesPlanner(this.deviceNamespace, this.resourceName, c.Resolve <IKubernetes>(), commandFactory, configProvider); return(planner); }) .As <Task <IPlanner> >() .SingleInstance(); // KubernetesRuntimeInfoProvider builder.Register(c => new KubernetesRuntimeInfoProvider(this.deviceNamespace, c.Resolve <IKubernetes>(), c.Resolve <IModuleManager>())) .As <IRuntimeInfoProvider>() .As <IRuntimeInfoSource>() .SingleInstance(); // KubernetesDeploymentProvider builder.Register( c => new KubernetesDeploymentMapper( this.deviceNamespace, this.edgeDeviceHostName, this.proxyImage, this.proxyConfigPath, this.proxyConfigVolumeName, this.proxyConfigMapName, this.proxyTrustBundlePath, this.proxyTrustBundleVolumeName, this.proxyTrustBundleConfigMapName, this.persistentVolumeName, this.storageClassName, this.apiVersion, this.workloadUri, this.managementUri)) .As <IKubernetesDeploymentMapper>(); // KubernetesServiceMapper builder.Register(c => new KubernetesServiceMapper(this.defaultMapServiceType)) .As <IKubernetesServiceMapper>(); // KubernetesPvcMapper builder.Register(c => new KubernetesPvcMapper(this.persistentVolumeName, this.storageClassName, this.persistentVolumeClaimSizeMb)) .As <IKubernetesPvcMapper>(); // KubernetesServiceAccountProvider builder.Register(c => new KubernetesServiceAccountMapper()) .As <IKubernetesServiceAccountMapper>(); // EdgeDeploymentController builder.Register( c => { var deploymentSelector = $"{Constants.K8sEdgeDeviceLabel}={KubeUtils.SanitizeK8sValue(this.resourceName.DeviceId)},{Constants.K8sEdgeHubNameLabel}={KubeUtils.SanitizeK8sValue(this.resourceName.Hostname)}"; IEdgeDeploymentController watchOperator = new EdgeDeploymentController( this.resourceName, deploymentSelector, this.deviceNamespace, c.Resolve <IKubernetes>(), c.Resolve <IModuleIdentityLifecycleManager>(), c.Resolve <IKubernetesServiceMapper>(), c.Resolve <IKubernetesDeploymentMapper>(), c.Resolve <IKubernetesPvcMapper>(), c.Resolve <IKubernetesServiceAccountMapper>()); return(watchOperator); }) .As <IEdgeDeploymentController>() .SingleInstance(); // IEdgeDeploymentOperator builder.Register( c => { IEdgeDeploymentOperator watchOperator = new EdgeDeploymentOperator( this.resourceName, this.deviceNamespace, c.Resolve <IKubernetes>(), c.Resolve <IEdgeDeploymentController>()); return(watchOperator); }) .As <IEdgeDeploymentOperator>() .SingleInstance(); // IKubernetesEnvironmentOperator builder.Register( c => { IKubernetesEnvironmentOperator watchOperator = new KubernetesEnvironmentOperator( this.deviceNamespace, c.Resolve <IRuntimeInfoSource>(), c.Resolve <IKubernetes>()); return(watchOperator); }) .As <IKubernetesEnvironmentOperator>() .SingleInstance(); // Task<IEnvironmentProvider> builder.Register( async c => { var moduleStateStore = c.Resolve <IEntityStore <string, ModuleState> >(); var restartPolicyManager = c.Resolve <IRestartPolicyManager>(); IRuntimeInfoProvider runtimeInfoProvider = c.Resolve <IRuntimeInfoProvider>(); IEnvironmentProvider dockerEnvironmentProvider = await DockerEnvironmentProvider.CreateAsync(runtimeInfoProvider, moduleStateStore, restartPolicyManager); return(dockerEnvironmentProvider); }) .As <Task <IEnvironmentProvider> >() .SingleInstance(); }