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(Constants.EdgeAgentModuleName); var unixUris = new Dictionary <string, string> { { Constants.EdgeletWorkloadUriVariableName, "unix:///path/to/workload.sock" }, { Constants.EdgeletManagementUriVariableName, "unix:///path/to/mgmt.sock" } }; var windowsUris = new Dictionary <string, string> { { Constants.EdgeletWorkloadUriVariableName, "unix:///C:/path/to/workload/sock" }, { Constants.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 CombinedEdgeletConfigProvider(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]); } }
public override CombinedDockerConfig GetCombinedConfig(IModule module, IRuntimeInfo runtimeInfo) { CombinedDockerConfig combinedConfig = base.GetCombinedConfig(module, runtimeInfo); CreateContainerParameters createOptions = CloneOrCreateParams(combinedConfig.CreateOptions); // before making any other modifications to createOptions, save edge agent's createOptions + env as // container labels so they're available as soon as it loads InjectEdgeAgentLabels(module, createOptions); // if the workload URI is a Unix domain socket then volume mount it into the container this.MountSockets(module, createOptions); this.InjectNetworkAliases(module, createOptions); return(new CombinedDockerConfig(combinedConfig.Image, createOptions, combinedConfig.Digest, combinedConfig.AuthConfig)); }
public void ValidatePodPropertyTranslation() { var identity = new ModuleIdentity("hostname", "gatewayhost", "deviceid", "ModuleId", Mock.Of <ICredentials>()); var config = new CombinedDockerConfig("image", new global::Microsoft.Azure.Devices.Edge.Agent.Docker.Models.CreateContainerParameters(), Option.None <AuthConfig>()); config.CreateOptions.Labels = new Dictionary <string, string> { // Add a label { "demo", "test" } }; config.CreateOptions.HostConfig = new global::Microsoft.Azure.Devices.Edge.Agent.Docker.Models.HostConfig { // Make container privileged Privileged = true, // Add a readonly mount Binds = new List <string> { "/home/blah:/home/blah2:ro" } }; var docker = new DockerModule("module1", "v1", ModuleStatus.Running, Core.RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVarsDict); var module = new KubernetesModule(docker, config); var mapper = new KubernetesDeploymentMapper("namespace", "edgehub", "proxy", "configPath", "configVolumeName", "configMapName", "trustBundlePAth", "trustBundleVolumeName", "trustBindleConfigMapName", "apiVersion", new Uri("http://workload"), new Uri("http://management")); var labels = new Dictionary <string, string>(); var deployment = mapper.CreateDeployment(identity, module, labels); var pod = deployment.Spec.Template; Assert.NotNull(pod); // Validate annotation Assert.True(pod.Metadata.Annotations.ContainsKey("demo")); // Two containers should exist - proxy and the module Assert.Equal(2, pod.Spec.Containers.Count); // There should only be one container var moduleContainer = pod.Spec.Containers.Single(p => p.Name != "proxy"); // We made this container privileged Assert.True(moduleContainer.SecurityContext.Privileged); // Validate that there are 4 mounts Assert.Equal(3, moduleContainer.VolumeMounts.Count); // Validate the custom mount that we added Assert.Contains(moduleContainer.VolumeMounts, vm => vm.Name.Equals("homeblah")); var mount = moduleContainer.VolumeMounts.Single(vm => vm.Name.Equals("homeblah")); // Lets make sure that it is read only Assert.True(mount.ReadOnlyProperty); }
public void EmptyIsNotAllowedAsPodAnnotation() { var identity = new ModuleIdentity("hostname", "gatewayhost", "deviceid", "ModuleId", Mock.Of <ICredentials>()); var config = new CombinedDockerConfig("image", new global::Microsoft.Azure.Devices.Edge.Agent.Docker.Models.CreateContainerParameters(), Option.None <AuthConfig>()); config.CreateOptions.Labels = new Dictionary <string, string> { // string.Empty is an invalid label name { string.Empty, "test" } }; var docker = new DockerModule("module1", "v1", ModuleStatus.Running, Core.RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVarsDict); var module = new KubernetesModule(docker, config); var mapper = new KubernetesDeploymentMapper("namespace", "edgehub", "proxy", "configPath", "configVolumeName", "configMapName", "trustBundlePAth", "trustBundleVolumeName", "trustBindleConfigMapName", "apiVersion", new Uri("http://workload"), new Uri("http://management")); var labels = new Dictionary <string, string>(); Assert.Throws <InvalidKubernetesNameException>(() => mapper.CreateDeployment(identity, module, labels)); }
public void EmptyIsNotAllowedAsServiceAnnotation() { var config = new CombinedDockerConfig("image", new Docker.Models.CreateContainerParameters(), Option.None <AuthConfig>()); config.CreateOptions.Labels = new Dictionary <string, string> { // string.Empty is an invalid label name { string.Empty, "test" } }; var moduleId = new ModuleIdentity("hub", "gateway", "deviceId", "moduleid", Mock.Of <ICredentials>()); var docker = new DockerModule(moduleId.ModuleId, "v1", ModuleStatus.Running, Core.RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); var module = new KubernetesModule(docker, config); var moduleLabels = new Dictionary <string, string>(); var mapper = new KubernetesServiceMapper(PortMapServiceType.ClusterIP); Assert.Throws <InvalidKubernetesNameException>(() => mapper.CreateService(moduleId, module, moduleLabels)); }
public void TestAddNewRootKeyRegistryCredential() { var runtimeConfig = new DockerRuntimeConfig( "1.0", new Dictionary <string, RegistryCredentials> { ["r1"] = new RegistryCredentials("mcr.microsoft.com", "foo", "foo", "credential") }); var runtimeInfo = new DockerRuntimeInfo("docker", runtimeConfig); var module = new Mock <IModule <DockerConfig> >(); module.SetupGet(m => m.Config).Returns(new DockerConfig("mcr.microsoft.com/windows/nanoserver:1809")); module.SetupGet(m => m.Name).Returns(Constants.EdgeAgentModuleName); var unixUris = new Dictionary <string, string> { { Constants.EdgeletWorkloadUriVariableName, "unix:///path/to/workload.sock" }, { Constants.EdgeletManagementUriVariableName, "unix:///path/to/mgmt.sock" } }; var windowsUris = new Dictionary <string, string> { { Constants.EdgeletWorkloadUriVariableName, "unix:///C:/path/to/workload/sock" }, { Constants.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); var authConfig = new AuthConfig { ServerAddress = "mcr.microsoft.com" }; ICombinedConfigProvider <CombinedDockerConfig> provider = new CombinedEdgeletConfigProvider(new[] { authConfig }, configSource); var systemInfoSample = new SystemInfo("linux", "x86", "1"); var moduleManager = Mock.Of <IModuleManager>(m => m.GetSystemInfoAsync(CancellationToken.None) == Task.FromResult(systemInfoSample)); ICommandFactory factory = new EdgeletCommandFactory <CombinedDockerConfig>(moduleManager, configSource, provider); // Act CombinedDockerConfig config = provider.GetCombinedConfig(module.Object, runtimeInfo); // Assert Assert.Equal("credential", config.AuthConfig.OrDefault().RegistryToken); }
public void UnknownProtocolDoesNotCreateService() { var config = new CombinedDockerConfig("image", new Docker.Models.CreateContainerParameters(), Option.None <AuthConfig>()); var moduleId = new ModuleIdentity("hostname", "gatewayhost", "deviceid", "moduleid", Mock.Of <ICredentials>()); config.CreateOptions.ExposedPorts = new Dictionary <string, EmptyStruct> { // Add unknown protocol { "123/XXX", default(EmptyStruct) } }; var docker = new DockerModule("module1", "v1", ModuleStatus.Running, Core.RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); var module = new KubernetesModule(docker, config); var moduleLabels = new Dictionary <string, string>(); var mapper = new KubernetesServiceMapper(PortMapServiceType.ClusterIP); var service = mapper.CreateService(moduleId, module, moduleLabels); Assert.False(service.HasValue); }
public async Task ImageNotFoundTest() { const string Image = "non-existing-image:latest"; const string Name = "non-existing-image-name"; try { using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(15))) { await DockerHelper.Client.CleanupContainerAsync(Name, Image); var config = new CombinedDockerConfig(Image, new CreateContainerParameters(), NoAuth); ICommand pullCommand = new PullCommand(DockerHelper.Client, config); await Assert.ThrowsAsync <ImageNotFoundException>(() => pullCommand.ExecuteAsync(cts.Token)); } } finally { await DockerHelper.Client.CleanupContainerAsync(Name, Image); } }
public async Task PullValidImages(string testFullImage, string image, string tag) { // Arrange string testImage = string.Empty; string testTag = string.Empty; var auth = new AuthConfig(); var client = new Mock <IDockerClient>(); var images = new Mock <IImageOperations>(); images.Setup( i => i.CreateImageAsync( It.IsAny <ImagesCreateParameters>(), It.IsAny <AuthConfig>(), It.IsAny <IProgress <JSONMessage> >(), It.IsAny <CancellationToken>())) .Callback <ImagesCreateParameters, AuthConfig, IProgress <JSONMessage>, CancellationToken>( (icp, a, p, t) => { testImage = icp.FromImage; testTag = icp.Tag; }) .Returns(TaskEx.Done); client.SetupGet(c => c.Images).Returns(images.Object); var config = new CombinedDockerConfig(testFullImage, new CreateContainerParameters(), Option.Some(auth)); // Act var command = new PullCommand(client.Object, config); await command.ExecuteAsync(CancellationToken.None); // Assert client.VerifyAll(); images.VerifyAll(); Assert.Equal(image, testImage); Assert.Equal(tag, testTag); }
public void ExposingPortsCreatesAServiceWithPorts() { var createOptions = new Docker.Models.CreateContainerParameters { // Add a port to be exposed ExposedPorts = new Dictionary <string, EmptyStruct> { ["10/TCP"] = default(EmptyStruct) } }; var config = new CombinedDockerConfig("image", createOptions, Option.None <AuthConfig>()); var docker = new DockerModule("module1", "v1", ModuleStatus.Running, Core.RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); var module = new KubernetesModule(docker, config); var moduleLabels = new Dictionary <string, string>(); var mapper = new KubernetesServiceMapper(PortMapServiceType.ClusterIP); var moduleId = new ModuleIdentity("hostname", "gatewayhost", "deviceid", "moduleid", Mock.Of <ICredentials>()); var service = mapper.CreateService(moduleId, module, moduleLabels).OrDefault(); Assert.Equal(1, service.Spec.Ports.Count); AssertPort(new V1ServicePort(10, "exposedport-10-tcp", null, "TCP"), service.Spec.Ports.First()); Assert.Equal("ClusterIP", service.Spec.Type); }
public void InjectNetworkAliasHostNetworkTest() { // Arrange var runtimeInfo = new Mock <IRuntimeInfo <DockerRuntimeConfig> >(); runtimeInfo.SetupGet(ri => ri.Config).Returns(new DockerRuntimeConfig("1.24", string.Empty)); string hostNetworkCreateOptions = "{\"NetworkingConfig\":{\"EndpointsConfig\":{\"host\":{}}},\"HostConfig\":{\"NetworkMode\":\"host\"}}"; var module = new Mock <IModule <DockerConfig> >(); module.SetupGet(m => m.Config).Returns(new DockerConfig("nginx:latest", hostNetworkCreateOptions)); module.SetupGet(m => m.Name).Returns("mod1"); 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.False(config.CreateOptions.NetworkingConfig.EndpointsConfig.ContainsKey("testnetwork1")); Assert.NotNull(config.CreateOptions.NetworkingConfig.EndpointsConfig["host"]); Assert.Null(config.CreateOptions.NetworkingConfig.EndpointsConfig["host"].Aliases); Assert.Equal("host", config.CreateOptions.HostConfig.NetworkMode); }
public PullCommand(IDockerClient client, CombinedDockerConfig combinedDockerConfig) { this.client = Preconditions.CheckNotNull(client, nameof(client)); this.combinedDockerConfig = Preconditions.CheckNotNull(combinedDockerConfig, nameof(combinedDockerConfig)); }
public void CompareModule() { var auth1 = new AuthConfig { Username = "******", Password = "******", ServerAddress = "test1-server.com" }; var auth2 = new AuthConfig { Username = "******", Password = "******", ServerAddress = "test1-server.com" }; var auth3 = new AuthConfig { Username = "******", Password = "******", ServerAddress = "test1-server.com" }; var auth4 = new AuthConfig { Username = "******", Password = "******", ServerAddress = "test2-server.com" }; Dictionary <string, EnvVal> goodEnv = new Dictionary <string, EnvVal>(); Dictionary <string, EnvVal> newEnv = new Dictionary <string, EnvVal> { ["a"] = new EnvVal("B") }; IList <string> dockerEnv = new List <string> { "c=d" }; CombinedDockerConfig goodCombinedDockerConfig = new CombinedDockerConfig("image:tag", new CreateContainerParameters(), Option.None <AuthConfig>()); CombinedDockerConfig imageDifferent = new CombinedDockerConfig("image:newtag", new CreateContainerParameters(), Option.None <AuthConfig>()); CombinedDockerConfig auth1Config = new CombinedDockerConfig("image:tag", new CreateContainerParameters(), Option.Some(auth1)); CombinedDockerConfig auth2Config = new CombinedDockerConfig("image:tag", new CreateContainerParameters(), Option.Some(auth2)); CombinedDockerConfig auth3Config = new CombinedDockerConfig("image:tag", new CreateContainerParameters(), Option.Some(auth3)); CombinedDockerConfig auth4Config = new CombinedDockerConfig("image:tag", new CreateContainerParameters(), Option.Some(auth4)); CombinedDockerConfig createContainerConfigDifferent = new CombinedDockerConfig("image:tag", new CreateContainerParameters { Env = dockerEnv }, Option.None <AuthConfig>()); ConfigurationInfo goodInfo = new ConfigurationInfo(string.Empty); var m1 = new CombinedDockerModule("name1", "v1", ModuleStatus.Running, RestartPolicy.Always, goodCombinedDockerConfig, goodInfo, goodEnv); var m2 = new CombinedDockerModule("name2", "v1", ModuleStatus.Running, RestartPolicy.Always, goodCombinedDockerConfig, goodInfo, goodEnv); var m3 = new CombinedDockerModule("name1", "v1", ModuleStatus.Running, RestartPolicy.Always, goodCombinedDockerConfig, goodInfo, goodEnv); var m4 = new CombinedDockerModule("name1", "v2", ModuleStatus.Running, RestartPolicy.Always, goodCombinedDockerConfig, goodInfo, goodEnv); var m5 = new CombinedDockerModule("name1", "v1", ModuleStatus.Running, RestartPolicy.Always, goodCombinedDockerConfig, goodInfo, goodEnv); var m6 = new CombinedDockerModule("name1", "v1", ModuleStatus.Stopped, RestartPolicy.Always, goodCombinedDockerConfig, goodInfo, goodEnv); var m7 = new CombinedDockerModule("name1", "v1", ModuleStatus.Running, RestartPolicy.Always, goodCombinedDockerConfig, goodInfo, goodEnv); var m8 = new CombinedDockerModule("name1", "v1", ModuleStatus.Running, RestartPolicy.Never, goodCombinedDockerConfig, goodInfo, goodEnv); var m9 = new CombinedDockerModule("name1", "v1", ModuleStatus.Running, RestartPolicy.Always, imageDifferent, goodInfo, goodEnv); var m10 = new CombinedDockerModule("name1", "v1", ModuleStatus.Running, RestartPolicy.Always, auth1Config, goodInfo, goodEnv); var m11 = new CombinedDockerModule("name1", "v1", ModuleStatus.Running, RestartPolicy.Always, auth2Config, goodInfo, goodEnv); var m12 = new CombinedDockerModule("name1", "v1", ModuleStatus.Running, RestartPolicy.Always, auth3Config, goodInfo, goodEnv); var m13 = new CombinedDockerModule("name1", "v1", ModuleStatus.Running, RestartPolicy.Always, auth4Config, goodInfo, goodEnv); var m14 = new CombinedDockerModule("name1", "v1", ModuleStatus.Running, RestartPolicy.Always, createContainerConfigDifferent, goodInfo, goodEnv); var m15 = new CombinedDockerModule("name1", "v1", ModuleStatus.Running, RestartPolicy.Always, goodCombinedDockerConfig, goodInfo, newEnv); Assert.NotEqual(m1, m2); Assert.NotEqual(m3, m4); Assert.NotEqual(m5, m6); Assert.NotEqual(m7, m8); Assert.NotEqual(m1, m9); Assert.NotEqual(m9, m1); Assert.NotEqual(m10, m9); Assert.NotEqual(m9, m10); Assert.NotEqual(m10, m11); Assert.NotEqual(m11, m10); Assert.NotEqual(m10, m12); Assert.NotEqual(m10, m13); Assert.NotEqual(m11, m14); Assert.NotEqual(m11, m15); Assert.True(m5.IsOnlyModuleStatusChanged(m6)); Assert.False(m1.IsOnlyModuleStatusChanged(m2)); Assert.False(m1.IsOnlyModuleStatusChanged(m9)); }
public async void CrdCommandExecuteWithAuthCreateNewObjects() { CombinedDockerConfig config = new CombinedDockerConfig("image", new Docker.Models.CreateContainerParameters(), Option.None <AuthConfig>()); IModule m1 = new DockerModule("module1", "v1", ModuleStatus.Running, Core.RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); var km1 = new KubernetesModule((IModule <DockerConfig>)m1, config); KubernetesModule[] modules = { km1 }; var token = default(CancellationToken); var auth = new AuthConfig() { Username = "******", Password = "******", ServerAddress = "docker.io" }; var configProvider = new Mock <ICombinedConfigProvider <CombinedDockerConfig> >(); configProvider.Setup(cp => cp.GetCombinedConfig(km1, Runtime)).Returns(() => new CombinedDockerConfig("test-image:1", Config1.CreateOptions, Option.Maybe(auth))); bool getSecretCalled = false; bool postSecretCalled = false; bool getCrdCalled = false; bool postCrdCalled = 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)) { httpContext.Response.StatusCode = 404; if (pathStr.Contains($"api/v1/namespaces/{Namespace}/secrets")) { getSecretCalled = true; } else if (pathStr.Contains($"namespaces/{Namespace}/{Constants.EdgeDeployment.Plural}")) { getCrdCalled = true; } } else if (string.Equals(method, "POST", StringComparison.OrdinalIgnoreCase)) { httpContext.Response.StatusCode = 201; httpContext.Response.Body = httpContext.Request.Body; if (pathStr.Contains($"api/v1/namespaces/{Namespace}/secrets")) { postSecretCalled = true; } else if (pathStr.Contains($"namespaces/{Namespace}/{Constants.EdgeDeployment.Plural}")) { postCrdCalled = true; } } return(Task.FromResult(false)); })) { var client = new Kubernetes( new KubernetesClientConfiguration { Host = server.Uri }); var cmd = new EdgeDeploymentCommand(Namespace, ResourceName, client, modules, Runtime, configProvider.Object); await cmd.ExecuteAsync(token); Assert.True(getSecretCalled, nameof(getSecretCalled)); Assert.True(postSecretCalled, nameof(postSecretCalled)); Assert.True(getCrdCalled, nameof(getCrdCalled)); Assert.True(postCrdCalled, nameof(postCrdCalled)); } }
public async void CrdCommandExecuteWithAuthReplaceObjects() { CombinedDockerConfig config = new CombinedDockerConfig("image", new Docker.Models.CreateContainerParameters(), Option.None <AuthConfig>()); string secretName = "username-docker.io"; var secretData = new Dictionary <string, byte[]> { [Constants.K8sPullSecretData] = Encoding.UTF8.GetBytes("Invalid Secret Data") }; var secretMeta = new V1ObjectMeta(name: secretName, namespaceProperty: Namespace); IModule m1 = new DockerModule("module1", "v1", ModuleStatus.Running, Core.RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, EnvVars); var km1 = new KubernetesModule((IModule <DockerConfig>)m1, config); KubernetesModule[] modules = { km1 }; var token = default(CancellationToken); var auth = new AuthConfig() { Username = "******", Password = "******", ServerAddress = "docker.io" }; var configProvider = new Mock <ICombinedConfigProvider <CombinedDockerConfig> >(); configProvider.Setup(cp => cp.GetCombinedConfig(km1, Runtime)).Returns(() => new CombinedDockerConfig("test-image:1", Config1.CreateOptions, Option.Maybe(auth))); var existingSecret = new V1Secret("v1", secretData, type: Constants.K8sPullSecretType, kind: "Secret", metadata: secretMeta); var existingDeployment = new EdgeDeploymentDefinition(Constants.EdgeDeployment.ApiVersion, Constants.EdgeDeployment.Kind, new V1ObjectMeta(name: ResourceName), new List <KubernetesModule>()); bool getSecretCalled = false; bool putSecretCalled = false; bool getCrdCalled = false; bool putCrdCalled = 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($"api/v1/namespaces/{Namespace}/secrets/{secretName}")) { getSecretCalled = true; await httpContext.Response.Body.WriteAsync(JsonConvert.SerializeObject(existingSecret).ToBody(), token); } else if (pathStr.Contains($"namespaces/{Namespace}/{Constants.EdgeDeployment.Plural}/{ResourceName}")) { getCrdCalled = true; await httpContext.Response.Body.WriteAsync(JsonConvert.SerializeObject(existingDeployment).ToBody(), token); } } else if (string.Equals(method, "PUT", StringComparison.OrdinalIgnoreCase)) { httpContext.Response.Body = httpContext.Request.Body; if (pathStr.Contains($"api/v1/namespaces/{Namespace}/secrets/{secretName}")) { putSecretCalled = true; } else if (pathStr.Contains($"namespaces/{Namespace}/{Constants.EdgeDeployment.Plural}/{ResourceName}")) { putCrdCalled = true; } } return(false); })) { var client = new Kubernetes( new KubernetesClientConfiguration { Host = server.Uri }); var cmd = new EdgeDeploymentCommand(Namespace, ResourceName, client, modules, Runtime, configProvider.Object); await cmd.ExecuteAsync(token); Assert.True(getSecretCalled, nameof(getSecretCalled)); Assert.True(putSecretCalled, nameof(putSecretCalled)); Assert.True(getCrdCalled, nameof(getCrdCalled)); Assert.True(putCrdCalled, nameof(putCrdCalled)); } }
public async void CrdCommandExecuteDeploysModulesWithEnvVars() { CombinedDockerConfig config = new CombinedDockerConfig("image", new Docker.Models.CreateContainerParameters(), Option.None <AuthConfig>()); IDictionary <string, EnvVal> moduleEnvVars = new Dictionary <string, EnvVal>() { { "ACamelCaseEnvVar", new EnvVal("ACamelCaseEnvVarValue") } }; IModule m1 = new DockerModule("module1", "v1", ModuleStatus.Running, Core.RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, DefaultConfigurationInfo, moduleEnvVars); var km1 = new KubernetesModule((IModule <DockerConfig>)m1, config); KubernetesModule[] modules = { km1 }; var token = default(CancellationToken); var auth = new AuthConfig() { Username = "******", Password = "******", ServerAddress = "docker.io" }; var configProvider = new Mock <ICombinedConfigProvider <CombinedDockerConfig> >(); configProvider.Setup(cp => cp.GetCombinedConfig(km1, Runtime)).Returns(() => new CombinedDockerConfig("test-image:1", Config1.CreateOptions, Option.Maybe(auth))); EdgeDeploymentDefinition postedEdgeDeploymentDefinition = null; bool postCrdCalled = 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)) { httpContext.Response.StatusCode = 404; } else if (string.Equals(method, "POST", StringComparison.OrdinalIgnoreCase)) { httpContext.Response.StatusCode = 201; httpContext.Response.Body = httpContext.Request.Body; if (pathStr.Contains($"namespaces/{Namespace}/{Constants.EdgeDeployment.Plural}")) { postCrdCalled = true; using (var reader = new StreamReader(httpContext.Response.Body)) { string crdBody = await reader.ReadToEndAsync(); postedEdgeDeploymentDefinition = JsonConvert.DeserializeObject <EdgeDeploymentDefinition>(crdBody); } } } return(false); })) { var client = new Kubernetes( new KubernetesClientConfiguration { Host = server.Uri }); var cmd = new EdgeDeploymentCommand(Namespace, ResourceName, client, modules, Runtime, configProvider.Object); await cmd.ExecuteAsync(token); Assert.True(postCrdCalled); Assert.Equal("module1", postedEdgeDeploymentDefinition.Spec[0].Name); Assert.Equal("test-image:1", postedEdgeDeploymentDefinition.Spec[0].Config.Image); Assert.True(postedEdgeDeploymentDefinition.Spec[0].Env.Contains(new KeyValuePair <string, EnvVal>("ACamelCaseEnvVar", new EnvVal("ACamelCaseEnvVarValue")))); } }