Пример #1
0
        public void MakesKubernetesAwareAuthConfig()
        {
            // Arrange
            var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >();

            runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty));

            var module = new Mock <IModule <DockerConfig> >();

            module.SetupGet(m => m.Config).Returns(new DockerConfig("docker.io/nginx:latest", (string)null, Option.None <NotaryContentTrust>()));
            module.SetupGet(m => m.Name).Returns("mod1");

            var authConfig = new AuthConfig {
                Username = "******", Password = "******", ServerAddress = "docker.io"
            };

            CombinedKubernetesConfigProvider provider = new CombinedKubernetesConfigProvider(new[] { authConfig }, new Uri("unix:///var/run/iotedgedworkload.sock"), new Uri("unix:///var/run/iotedgedmgmt.sock"), false);

            // Act
            CombinedKubernetesConfig config = provider.GetCombinedConfig(module.Object, runtimeInfo.Object);

            // Assert
            Assert.True(config.ImagePullSecret.HasValue);
            config.ImagePullSecret.ForEach(secret => Assert.Equal("user-docker.io", secret.Name));
        }
Пример #2
0
        public void TestNoVolMountForNonUds()
        {
            // Arrange
            var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >();

            runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty));

            var module = new Mock <IModule <DockerConfig> >();

            module.SetupGet(m => m.Config).Returns(new DockerConfig("nginx:latest"));
            module.SetupGet(m => m.Name).Returns(CoreConstants.EdgeAgentModuleName);

            IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection(
                new Dictionary <string, string>
            {
                { CoreConstants.EdgeletWorkloadUriVariableName, "http://localhost:2375/" },
                { CoreConstants.EdgeletManagementUriVariableName, "http://localhost:2376/" }
            }).Build();
            var configSource = Mock.Of <IConfigSource>(s => s.Configuration == configRoot);
            ICombinedConfigProvider <CombinedDockerConfig> provider = new CombinedKubernetesConfigProvider(new[] { new AuthConfig() }, configSource);

            // Act
            CombinedDockerConfig config = provider.GetCombinedConfig(module.Object, runtimeInfo.Object);

            // Assert
            Assert.NotNull(config.CreateOptions);
            Assert.Null(config.CreateOptions.HostConfig);
        }
Пример #3
0
        public void InjectNetworkAliasEdgeHubTest()
        {
            // Arrange
            var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >();

            runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty));

            var module = new Mock <IModule <DockerConfig> >();

            module.SetupGet(m => m.Config).Returns(new DockerConfig("nginx:latest"));
            module.SetupGet(m => m.Name).Returns(CoreConstants.EdgeHubModuleName);

            IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection(
                new Dictionary <string, string>
            {
                { CoreConstants.EdgeletWorkloadUriVariableName, "unix:///var/run/iotedgedworkload.sock" },
                { CoreConstants.EdgeletManagementUriVariableName, "unix:///var/run/iotedgedmgmt.sock" },
                { CoreConstants.NetworkIdKey, "testnetwork1" },
                { CoreConstants.EdgeDeviceHostNameKey, "edhk1" }
            }).Build();
            var configSource = Mock.Of <IConfigSource>(s => s.Configuration == configRoot);

            ICombinedConfigProvider <CombinedDockerConfig> provider = new CombinedKubernetesConfigProvider(new[] { new AuthConfig() }, configSource);

            // Act
            CombinedDockerConfig config = provider.GetCombinedConfig(module.Object, runtimeInfo.Object);

            // Assert
            Assert.NotNull(config.CreateOptions);
            Assert.NotNull(config.CreateOptions.NetworkingConfig);
            Assert.NotNull(config.CreateOptions.NetworkingConfig.EndpointsConfig);
            Assert.NotNull(config.CreateOptions.NetworkingConfig.EndpointsConfig["testnetwork1"]);
            Assert.Equal("edhk1", config.CreateOptions.NetworkingConfig.EndpointsConfig["testnetwork1"].Aliases[0]);
        }
Пример #4
0
        public void ParsesKubernetesCreateOptionsWhenExperimentalEnabled()
        {
            // Arrange
            var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >();

            runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty));

            var module = new Mock <IModule <DockerConfig> >();

            module.SetupGet(m => m.Config).Returns(new DockerConfig("nginx:latest", ExperimentalCreateOptions, Option.None <NotaryContentTrust>()));
            module.SetupGet(m => m.Name).Returns("mod1");

            CombinedKubernetesConfigProvider provider = new CombinedKubernetesConfigProvider(new[] { new AuthConfig() }, new Uri("unix:///var/run/iotedgedworkload.sock"), new Uri("unix:///var/run/iotedgedmgmt.sock"), true);

            // Act
            CombinedKubernetesConfig config = provider.GetCombinedConfig(module.Object, runtimeInfo.Object);

            // Assert
            Assert.True(config.CreateOptions.Volumes.HasValue);
            config.CreateOptions.Volumes.ForEach(volumes => Assert.Equal(1, volumes.Count));
            config.CreateOptions.Volumes.ForEach(volumes => Assert.NotNull(volumes.First()));

            Assert.True(config.CreateOptions.NodeSelector.HasValue);
            config.CreateOptions.NodeSelector.ForEach(selector => Assert.Equal(2, selector.Count));

            Assert.True(config.CreateOptions.Resources.HasValue);
            config.CreateOptions.Resources.ForEach(resources => Assert.Equal(3, resources.Limits.Count));
            config.CreateOptions.Resources.ForEach(resources => Assert.Equal(3, resources.Requests.Count));
        }
Пример #5
0
        public void TestVolMount()
        {
            // Arrange
            var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >();

            runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty));

            var module = new Mock <IModule <DockerConfig> >();

            module.SetupGet(m => m.Config).Returns(new DockerConfig("nginx:latest"));
            module.SetupGet(m => m.Name).Returns(CoreConstants.EdgeAgentModuleName);

            var unixUris = new Dictionary <string, string>
            {
                { CoreConstants.EdgeletWorkloadUriVariableName, "unix:///path/to/workload.sock" },
                { CoreConstants.EdgeletManagementUriVariableName, "unix:///path/to/mgmt.sock" }
            };

            var windowsUris = new Dictionary <string, string>
            {
                { CoreConstants.EdgeletWorkloadUriVariableName, "unix:///C:/path/to/workload/sock" },
                { CoreConstants.EdgeletManagementUriVariableName, "unix:///C:/path/to/mgmt/sock" }
            };

            IConfigurationRoot configRoot = new ConfigurationBuilder().AddInMemoryCollection(
                RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? windowsUris : unixUris).Build();
            var configSource = Mock.Of <IConfigSource>(s => s.Configuration == configRoot);
            ICombinedConfigProvider <CombinedDockerConfig> provider = new CombinedKubernetesConfigProvider(new[] { new AuthConfig() }, configSource);

            // Act
            CombinedDockerConfig config = provider.GetCombinedConfig(module.Object, runtimeInfo.Object);

            // Assert
            Assert.NotNull(config.CreateOptions);
            Assert.NotNull(config.CreateOptions.HostConfig);
            Assert.NotNull(config.CreateOptions.HostConfig.Binds);
            Assert.Equal(2, config.CreateOptions.HostConfig.Binds.Count);
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Equal("C:\\path\\to\\workload:C:\\path\\to\\workload", config.CreateOptions.HostConfig.Binds[0]);
                Assert.Equal("C:\\path\\to\\mgmt:C:\\path\\to\\mgmt", config.CreateOptions.HostConfig.Binds[1]);
            }
            else
            {
                Assert.Equal("/path/to/workload.sock:/path/to/workload.sock", config.CreateOptions.HostConfig.Binds[0]);
                Assert.Equal("/path/to/mgmt.sock:/path/to/mgmt.sock", config.CreateOptions.HostConfig.Binds[1]);
            }
        }
Пример #6
0
        public void InvalidWorkingDirOptionsThrows()
        {
            var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >();

            runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty));

            var module = new Mock <IModule <DockerConfig> >();

            module.SetupGet(m => m.Config).Returns(new DockerConfig("nginx:latest", InvalidWorkingDirCreateOptions, Option.None <NotaryContentTrust>()));
            module.SetupGet(m => m.Name).Returns("mod1");

            CombinedKubernetesConfigProvider provider = new CombinedKubernetesConfigProvider(new[] { new AuthConfig() }, new Uri("unix:///var/run/iotedgedworkload.sock"), new Uri("unix:///var/run/iotedgedmgmt.sock"), true);

            // Act
            // Assert
            Assert.Throws <ArgumentException>(() => provider.GetCombinedConfig(module.Object, runtimeInfo.Object));
        }
Пример #7
0
        public void WorkingDirOptionsWillExist()
        {
            var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >();

            runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty));

            var module = new Mock <IModule <DockerConfig> >();

            module.SetupGet(m => m.Config).Returns(new DockerConfig("nginx:latest", WorkingDirCreateOptions, Option.None <NotaryContentTrust>()));
            module.SetupGet(m => m.Name).Returns("mod1");

            CombinedKubernetesConfigProvider provider = new CombinedKubernetesConfigProvider(new[] { new AuthConfig() }, new Uri("unix:///var/run/iotedgedworkload.sock"), new Uri("unix:///var/run/iotedgedmgmt.sock"), true);

            // Act
            CombinedKubernetesConfig config = provider.GetCombinedConfig(module.Object, runtimeInfo.Object);

            // Assert
            Assert.True(config.CreateOptions.WorkingDir.HasValue);
            config.CreateOptions.WorkingDir.ForEach(wd => Assert.Equal("a-directory", wd));
        }
        public void EntrypointOptionsWillExist()
        {
            var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >();

            runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty));

            var module = new Mock <IModule <DockerConfig> >();

            module.SetupGet(m => m.Config).Returns(new DockerConfig("nginx:latest", EntryPointCreateOptions, Option.None <string>()));
            module.SetupGet(m => m.Name).Returns("mod1");

            CombinedKubernetesConfigProvider provider = new CombinedKubernetesConfigProvider(new[] { new AuthConfig() }, new Uri("unix:///var/run/iotedgedworkload.sock"), new Uri("unix:///var/run/iotedgedmgmt.sock"), true);

            // Act
            CombinedKubernetesConfig config = provider.GetCombinedConfig(module.Object, runtimeInfo.Object);

            // Assert
            Assert.True(config.CreateOptions.Entrypoint.HasValue);
            config.CreateOptions.Entrypoint.ForEach(ep => Assert.Equal("a-command", ep[0]));
        }
Пример #9
0
        public void TestNoVolMountForNonUds()
        {
            // Arrange
            var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >();

            runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty));

            var module = new Mock <IModule <DockerConfig> >();

            module.SetupGet(m => m.Config).Returns(new DockerConfig("nginx:latest"));
            module.SetupGet(m => m.Name).Returns(CoreConstants.EdgeAgentModuleName);

            CombinedKubernetesConfigProvider provider = new CombinedKubernetesConfigProvider(new[] { new AuthConfig() }, new Uri("http://localhost:2375/"), new Uri("http://localhost:2376/"), false);

            // Act
            CombinedKubernetesConfig config = provider.GetCombinedConfig(module.Object, runtimeInfo.Object);

            // Assert
            Assert.NotNull(config.CreateOptions);
            Assert.False(config.CreateOptions.HostConfig.HasValue);
        }
Пример #10
0
        public void NoExecArgumentMeansNoExecArguments()
        {
            var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >();

            runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty));

            var module = new Mock <IModule <DockerConfig> >();

            module.SetupGet(m => m.Config).Returns(new DockerConfig("nginx:latest", string.Empty, Option.None <NotaryContentTrust>()));
            module.SetupGet(m => m.Name).Returns("mod1");

            CombinedKubernetesConfigProvider provider = new CombinedKubernetesConfigProvider(new[] { new AuthConfig() }, new Uri("unix:///var/run/iotedgedworkload.sock"), new Uri("unix:///var/run/iotedgedmgmt.sock"), true);

            // Act
            CombinedKubernetesConfig config = provider.GetCombinedConfig(module.Object, runtimeInfo.Object);

            // Assert
            Assert.False(config.CreateOptions.Cmd.HasValue);
            Assert.False(config.CreateOptions.Entrypoint.HasValue);
            Assert.False(config.CreateOptions.WorkingDir.HasValue);
        }
Пример #11
0
        public void IgnoresKubernetesCreateOptionsWhenExperimentalDisabled()
        {
            // Arrange
            var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >();

            runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty));

            var    module        = new Mock <IModule <DockerConfig> >();
            string createOptions = "{ \"k8s-experimental\": { nodeSelector: { disktype: \"ssd\" } } }";

            module.SetupGet(m => m.Config).Returns(new DockerConfig("nginx:latest", createOptions));
            module.SetupGet(m => m.Name).Returns("mod1");

            CombinedKubernetesConfigProvider provider = new CombinedKubernetesConfigProvider(new[] { new AuthConfig() }, new Uri("unix:///var/run/iotedgedworkload.sock"), new Uri("unix:///var/run/iotedgedmgmt.sock"), false);

            // Act
            CombinedKubernetesConfig config = provider.GetCombinedConfig(module.Object, runtimeInfo.Object);

            // Assert
            Assert.False(config.CreateOptions.NodeSelector.HasValue);
        }
Пример #12
0
        public void IgnoresKubernetesCreateOptionsWhenExperimentalDisabled()
        {
            // Arrange
            var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >();

            runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty));

            var module = new Mock <IModule <DockerConfig> >();

            module.SetupGet(m => m.Config).Returns(new DockerConfig("nginx:latest", ExperimentalCreateOptions, Option.None <NotaryContentTrust>()));
            module.SetupGet(m => m.Name).Returns("mod1");

            CombinedKubernetesConfigProvider provider = new CombinedKubernetesConfigProvider(new[] { new AuthConfig() }, new Uri("unix:///var/run/iotedgedworkload.sock"), new Uri("unix:///var/run/iotedgedmgmt.sock"), false);

            // Act
            CombinedKubernetesConfig config = provider.GetCombinedConfig(module.Object, runtimeInfo.Object);

            // Assert
            Assert.False(config.CreateOptions.Volumes.HasValue);
            Assert.False(config.CreateOptions.NodeSelector.HasValue);
            Assert.False(config.CreateOptions.Resources.HasValue);
        }
Пример #13
0
        public void TestVolMount()
        {
            // Arrange
            var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >();

            runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty));

            var module = new Mock <IModule <DockerConfig> >();

            module.SetupGet(m => m.Config).Returns(new DockerConfig("nginx:latest"));
            module.SetupGet(m => m.Name).Returns(CoreConstants.EdgeAgentModuleName);

            (Uri workloadUri, Uri managementUri) = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
                ? (new Uri("unix:///C:/path/to/workload/sock"), new Uri("unix:///C:/path/to/mgmt/sock"))
                : (new Uri("unix:///path/to/workload.sock"), new Uri("unix:///path/to/mgmt.sock"));

            CombinedKubernetesConfigProvider provider = new CombinedKubernetesConfigProvider(new[] { new AuthConfig() }, workloadUri, managementUri, false);

            // Act
            CombinedKubernetesConfig config = provider.GetCombinedConfig(module.Object, runtimeInfo.Object);

            // Assert
            Assert.NotNull(config.CreateOptions);
            Assert.True(config.CreateOptions.HostConfig.HasValue);
            config.CreateOptions.HostConfig.ForEach(hostConfig => Assert.NotNull(hostConfig.Binds));
            config.CreateOptions.HostConfig.ForEach(hostConfig => Assert.Equal(2, hostConfig.Binds.Count));

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                config.CreateOptions.HostConfig.ForEach(hostConfig => Assert.Equal(@"C:\path\to\workload:C:\path\to\workload", hostConfig.Binds[0]));
                config.CreateOptions.HostConfig.ForEach(hostConfig => Assert.Equal(@"C:\path\to\mgmt:C:\path\to\mgmt", hostConfig.Binds[1]));
            }
            else
            {
                config.CreateOptions.HostConfig.ForEach(hostConfig => Assert.Equal("/path/to/workload.sock:/path/to/workload.sock", hostConfig.Binds[0]));
                config.CreateOptions.HostConfig.ForEach(hostConfig => Assert.Equal("/path/to/mgmt.sock:/path/to/mgmt.sock", hostConfig.Binds[1]));
            }
        }
Пример #14
0
        public void CmdEntryOptionsWillExist()
        {
            var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >();

            runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty));

            var module = new Mock <IModule <DockerConfig> >();

            module.SetupGet(m => m.Config).Returns(new DockerConfig("nginx:latest", CmdCreateOptions));
            module.SetupGet(m => m.Name).Returns("mod1");

            CombinedKubernetesConfigProvider provider = new CombinedKubernetesConfigProvider(new[] { new AuthConfig() }, new Uri("unix:///var/run/iotedgedworkload.sock"), new Uri("unix:///var/run/iotedgedmgmt.sock"), true);

            // Act
            CombinedKubernetesConfig config = provider.GetCombinedConfig(module.Object, runtimeInfo.Object);

            // Assert
            Assert.True(config.CreateOptions.Cmd.HasValue);
            config.CreateOptions.Cmd.ForEach(cmd =>
            {
                Assert.Equal("argument1", cmd[0]);
                Assert.Equal("argument2", cmd[1]);
            });
        }
Пример #15
0
        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();

            // ICombinedConfigProvider<CombinedDockerConfig>
            builder.Register(
                async c =>
            {
                IConfigSource configSource = await c.Resolve <Task <IConfigSource> >();
                ICombinedConfigProvider <CombinedDockerConfig> provider = new CombinedKubernetesConfigProvider(this.dockerAuthConfig, configSource);
                return(provider);
            })
            .As <Task <ICombinedConfigProvider <CombinedDockerConfig> > >()
            .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 combinedConfigProvider     = await c.Resolve <Task <ICombinedConfigProvider <CombinedDockerConfig> > >();
                ICommandFactory commandFactory = await c.Resolve <Task <ICommandFactory> >();
                IPlanner planner = new KubernetesPlanner(this.deviceNamespace, this.resourceName, c.Resolve <IKubernetes>(), commandFactory, combinedConfigProvider);
                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.apiVersion,
                    this.workloadUri,
                    this.managementUri))
            .As <IKubernetesDeploymentMapper>();

            // KubernetesServiceProvider
            builder.Register(c => new KubernetesServiceMapper(this.defaultMapServiceType))
            .As <IKubernetesServiceMapper>();

            // 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 <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();
        }