public async Task Two_Namespace_Will_Create_A_Error() { // Arrange var namespaceName = "namespace-from-test-" + Guid.NewGuid().ToString().Substring(0, 5); var awsRoleName = "awsRoleName"; var config = KubernetesClientConfiguration.BuildConfigFromConfigFile(); var client = new k8s.Kubernetes(config); var sut = new NamespaceRepository(new KubernetesWrapper(client)); try { await sut.CreateNamespaceAsync(namespaceName, awsRoleName); // Act / Assert await Assert.ThrowsAsync <NamespaceAlreadyExistException>(async() => await sut.CreateNamespaceAsync(namespaceName, awsRoleName)); } finally { client.DeleteNamespace( body: new V1DeleteOptions(), name: namespaceName ); } }
public async Task ReturnsPodOnSuccessGettingPod() { var hostname = "kubernetes1-7d7c8ff84f-76mkq"; Environment.SetEnvironmentVariable("HOSTNAME", hostname); var podListRsp = "{\"kind\":\"PodList\",\"apiVersion\":\"v1\",\"metadata\":{\"selfLink\":\"/api/v1/namespaces/default/pods\",\"resourceVersion\":\"8541208\"},\"items\":[{\"metadata\":{\"name\":\"kubernetes1-7d7c8ff84f-76mkq\",\"generateName\":\"kubernetes1-7d7c8ff84f-\",\"namespace\":\"default\",\"selfLink\":\"/api/v1/namespaces/default/pods/kubernetes1-7d7c8ff84f-76mkq\",\"uid\":\"989ef5d3-c2bd-4179-a1ab-9925e15d202a\",\"resourceVersion\":\"8523457\",\"creationTimestamp\":\"2020-05-28T18:32:37Z\",\"labels\":{ \"app\":\"kubernetes1\"},\"annotations\":{\"buildID\":\"\"},\"ownerReferences\":[],\"containers\":[{\"name\":\"kubernetes1\",\"image\":\"kubernetes1:x01725c8eb04d86fc\",\"command\":[],\"ports\":[],\"resources\":{},\"volumeMounts\":[],\"terminationMessagePath\":\"/dev/termination-log\",\"terminationMessagePolicy\":\"File\",\"imagePullPolicy\":\"Never\"}],\"restartPolicy\":\"Always\",\"terminationGracePeriodSeconds\":0,\"dnsPolicy\":\"ClusterFirst\",\"serviceAccountName\":\"default\",\"serviceAccount\":\"default\",\"nodeName\":\"agentpool\",\"securityContext\":{},\"schedulerName\":\"default-scheduler\",\"tolerations\":[{\"key\":\"node.kubernetes.io/not-ready\",\"operator\":\"Exists\",\"effect\":\"NoExecute\",\"tolerationSeconds\":300},{\"key\":\"node.kubernetes.io/unreachable\",\"operator\":\"Exists\",\"effect\":\"NoExecute\",\"tolerationSeconds\":300}],\"priority\":0,\"enableServiceLinks\":true},\"spec\":{\"serviceAccountName\": \"default\", \"serviceAccount\": \"default\", \"nodeName\": \"agentpool\"},\"status\":{\"phase\":\"Running\",\"conditions\":[{\"type\":\"Initialized\",\"status\":\"True\",\"lastProbeTime\":null,\"lastTransitionTime\":\"2020-05-28T18:33:19Z\"},{\"type\":\"Ready\",\"status\":\"True\",\"lastProbeTime\":null,\"lastTransitionTime\":\"2020-05-28T18:33:20Z\"},{\"type\":\"ContainersReady\",\"status\":\"True\",\"lastProbeTime\":null,\"lastTransitionTime\":\"2020-05-28T18:33:20Z\"},{\"type\":\"PodScheduled\",\"status\":\"True\",\"lastProbeTime\":null,\"lastTransitionTime\":\"2020-05-28T18:32:37Z\"}],\"hostIP\":\"10.240.0.4\",\"podIP\":\"10.244.1.128\",\"podIPs\":[{\"ip\":\"10.244.1.128\"}],\"startTime\":\"2020-05-28T18:32:37Z\",\"initContainerStatuses\":[],\"containerStatuses\":[],\"qosClass\":\"BestEffort\"}}]}\n"; var mockHttpMessageHandler = new MockHttpMessageHandler(); mockHttpMessageHandler.Expect(HttpMethod.Get, "*").Respond(HttpStatusCode.OK, new StringContent(podListRsp)); var appOptions = new KubernetesApplicationOptions(new ConfigurationBuilder().Build()); using var client = new k8s.Kubernetes(new KubernetesClientConfiguration { Host = "http://localhost" }, httpClient: mockHttpMessageHandler.ToHttpClient()); var utils = new StandardPodUtilities(appOptions, null, client); var getPodResult = await utils.GetCurrentPodAsync(); Assert.NotNull(getPodResult); Assert.Equal("default", getPodResult.Metadata.NamespaceProperty); Assert.Equal(hostname, getPodResult.Metadata.Name); Assert.Equal("10.244.1.128", getPodResult.Status.PodIP); Assert.Equal("default", getPodResult.Spec.ServiceAccountName); Assert.Equal("agentpool", getPodResult.Spec.NodeName); Assert.Equal("10.240.0.4", getPodResult.Status.HostIP); Environment.SetEnvironmentVariable("HOSTNAME", null); }
public void KubernetesConfigMapProvider_AddsEnvSpecificJsonFileToDictionaryOnSuccess() { // arrange var mockHttpMessageHandler = new MockHttpMessageHandler(); mockHttpMessageHandler .Expect(HttpMethod.Get, "*") .Respond(new StringContent("{\"kind\":\"ConfigMap\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"testconfigmap\",\"namespace\":\"default\",\"selfLink\":\"/api/v1/namespaces/default/configmaps/testconfigmap\",\"uid\":\"8582b94c-f4fa-47fa-bacc-47019223775c\",\"resourceVersion\":\"1320622\",\"creationTimestamp\":\"2020-04-15T18:33:49Z\",\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"v1\\\",\\\"data\\\":{\\\"ConfigMapName\\\":\\\"testconfigmap\\\"},\\\"kind\\\":\\\"ConfigMap\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"kubernetes1\\\",\\\"namespace\\\":\\\"default\\\"}}\\n\"}},\"data\":{" + "\"appsettings.demo.json\": \"{\n \\\"Test0\\\": \\\"Value0\\\",\n \\\"Test1\\\": [\n {\n \\\"Test2\\\": \\\"Value1\\\"\n }\n ]\n}\"" + "}\n}\n")); using var client = new k8s.Kubernetes(new KubernetesClientConfiguration { Host = "http://localhost" }, httpClient: mockHttpMessageHandler.ToHttpClient()); var settings = new KubernetesConfigSourceSettings("default", "testconfigmap", new ReloadSettings()); var provider = new KubernetesConfigMapProvider(client, settings); // act provider.Load(); // assert Assert.True(provider.TryGet("Test0", out var testValue)); Assert.Equal("Value0", testValue); Assert.True(provider.TryGet("Test1:0:Test2", out var testValue2)); Assert.Equal("Value1", testValue2); }
public SecretConfigurationProvider(string?namespaceSelector, string?labelSelector, string?separator, bool reloadOnChange, bool decodeData = true) { _namespaceSelector = namespaceSelector ?? string.Empty; _labelSelector = labelSelector ?? string.Empty; _separator = separator ?? "__"; _decodeData = decodeData; KubernetesClientConfiguration config; try { config = KubernetesClientConfiguration.InClusterConfig(); } catch { config = KubernetesClientConfiguration.BuildConfigFromConfigFile(); } _client = new k8s.Kubernetes(config); if (!reloadOnChange) { return; } var secretResponse = _client.ListNamespacedSecretWithHttpMessagesAsync(_namespaceSelector, labelSelector: _labelSelector, watch: true).Result; secretResponse.Watch <V1Secret, V1SecretList>((type, item) => { if (type.Equals(WatchEventType.Modified)) { Load(true); } }); }
public async Task A_Created_Namespace_Will_Have_the_KIAM_Annotation() { // Arrange var namespaceName = "namespace-from-test"; var awsRoleName = "awsRoleName"; var config = KubernetesClientConfiguration.BuildConfigFromConfigFile(); var client = new k8s.Kubernetes(config); var sut = new NamespaceRespoitory(client); try { // act await sut.CreateNamespace(namespaceName, awsRoleName); // Assert var namespaces = await client.ListNamespaceAsync(); var @namespace = namespaces.Items.Single(n => n.Metadata.Name == namespaceName); var annotationValue = @namespace.Metadata.Annotations["iam.amazonaws.com/permitted"]; Assert.Equal(awsRoleName, annotationValue); } finally { client.DeleteNamespace( body: new V1DeleteOptions(), name: namespaceName ); } }
public async Task Two_Namespace_Will_Create_A_Error() { // Arrange var namespaceName = "namespace-from-test"; var awsRoleName = "awsRoleName"; var config = KubernetesClientConfiguration.BuildConfigFromConfigFile(); var client = new k8s.Kubernetes(config); var sut = new NamespaceRespoitory(client); try { await sut.CreateNamespace(namespaceName, awsRoleName); // Act var ex = await Assert.ThrowsAsync <Exception>(async() => await sut.CreateNamespace(namespaceName, awsRoleName)); // Assert var expectedStart = "Error occured while communicating with k8s:"; Assert.StartsWith(expectedStart, ex.Message); } finally { client.DeleteNamespace( body: new V1DeleteOptions(), name: namespaceName ); } }
private static void AKSAdministration() { var configuration = new k8s.KubernetesClientConfiguration { Host = "https://ari-aks-22-demo-f681ed-b4579bd4.hcp.southeastasia.azmk8s.io:443", AccessToken = ReadAccessToken() }; configuration.SkipTlsVerify = true; var client = new k8s.Kubernetes(configuration); var namespaces = client.ListNamespace(); foreach (var ns in namespaces.Items) { Console.WriteLine(ns.Metadata.Name); } // ## Uncomment below lines to test creation of namespace //client.CreateNamespace(new k8s.Models.V1Namespace { // Metadata= new k8s.Models.V1ObjectMeta // { // Name= "automation" // } //}); }
public async Task Create_already_existing_role_should_result_in_typed_exception() { // Arrange var config = KubernetesClientConfiguration.BuildConfigFromConfigFile(); var client = new k8s.Kubernetes(config); var wrapper = new KubernetesWrapper(client); var namespaceRepository = new NamespaceRepository(wrapper); var subjectNameSpace = "namespace-with-role-test-" + Guid.NewGuid().ToString().Substring(0, 5); var awsRoleName = "notUSed"; var sut = new WebApi.Repositories.Kubernetes.RoleRepository(wrapper); try { // Act await namespaceRepository.CreateNamespaceAsync(subjectNameSpace, awsRoleName); await sut.CreateNamespaceFullAccessRole(subjectNameSpace); // Assert await Assert.ThrowsAsync <RoleAlreadyExistException>(() => sut.CreateNamespaceFullAccessRole(subjectNameSpace)); } finally { client.DeleteNamespace( body: new V1DeleteOptions(), name: subjectNameSpace ); } }
public async Task Create_A_Role_For_A_Existing_Namespace() { // Arrange var config = KubernetesClientConfiguration.BuildConfigFromConfigFile(); var client = new k8s.Kubernetes(config); var wrapper = new KubernetesWrapper(client); var namespaceRepository = new NamespaceRepository(wrapper); var subjectNameSpace = "namespace-with-role-test-" + Guid.NewGuid().ToString().Substring(0, 5); var awsRoleName = "notUSed"; var sut = new WebApi.Repositories.Kubernetes.RoleRepository(wrapper); try { // Act await namespaceRepository.CreateNamespaceAsync(subjectNameSpace, awsRoleName); await sut.CreateNamespaceFullAccessRole(subjectNameSpace); // Assert client.ListNamespacedRole(subjectNameSpace).Items.Single(); } finally { client.DeleteNamespace( body: new V1DeleteOptions(), name: subjectNameSpace ); } }
public void GetInstances_ShouldBeAbleToHandleEndpointsFromMultipleNamespaces() { // arrange var mockHttpMessageHandler = new MockHttpMessageHandler(); mockHttpMessageHandler.Expect(HttpMethod.Get, "/api/v1/endpoints?fieldSelector=metadata.name%3Dendpoint") .Respond( HttpStatusCode.OK, new StringContent("{\"apiVersion\":\"v1\",\"items\":[{\"apiVersion\":\"v1\",\"kind\":\"Endpoints\",\"metadata\":{\"name\":\"endpoint\",\"namespace\":\"test\"},\"subsets\":[{\"addresses\":[{\"ip\":\"ip1\", \"targetRef\": {\"uid\":\"uid1\"}}],\"ports\":[{\"name\":\"http\",\"port\":80,\"protocol\":\"TCP\"}]}]},{\"apiVersion\":\"v1\",\"kind\":\"Endpoints\",\"metadata\":{\"name\":\"endpoint\",\"namespace\":\"test2\"},\"subsets\":[{\"addresses\":[{\"ip\":\"ip2\",\"targetRef\": {\"uid\":\"uid2\"}}],\"ports\":[{\"name\":\"http\",\"port\":80,\"protocol\":\"TCP\"}]}]}],\"kind\":\"List\",\"metadata\":{\"resourceVersion\":\"\",\"selfLink\":\"\"}}")); mockHttpMessageHandler.When(HttpMethod.Get, "/api/v1/namespaces/test/services") .WithQueryString("fieldSelector=metadata.name%3Dendpoint") .Respond( HttpStatusCode.OK, new StringContent( "{\"apiVersion\":\"v1\",\"items\":[{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"labels\":{\"l\":\"v\"},\"name\":\"endpoint\",\"namespace\":\"test\",\"uid\":\"uids1\"}}],\"kind\":\"List\",\"metadata\":{\"resourceVersion\":\"\",\"selfLink\":\"\"}}")); mockHttpMessageHandler.When(HttpMethod.Get, "/api/v1/namespaces/test2/services") .WithQueryString("fieldSelector=metadata.name%3Dendpoint") .Respond( HttpStatusCode.OK, new StringContent( "{\"apiVersion\":\"v1\",\"items\":[{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"labels\":{\"l\":\"v\"},\"name\":\"endpoint\",\"namespace\":\"test2\",\"uid\":\"uids2\"}}],\"kind\":\"List\",\"metadata\":{\"resourceVersion\":\"\",\"selfLink\":\"\"}}")); using var client = new k8s.Kubernetes( config: new KubernetesClientConfiguration { Host = "http://localhost" }, httpClient: mockHttpMessageHandler.ToHttpClient()); var options = new KubernetesDiscoveryOptions() { AllNamespaces = true }; IDiscoveryClient discoveryClient = new KubernetesDiscoveryClient( new DefaultIsServicePortSecureResolver(options), client, options); // act var genericInstances = discoveryClient.GetInstances("endpoint"); var instances = genericInstances.Select(s => (KubernetesServiceInstance)s).ToList(); // assert Assert.NotNull(instances); Assert.Equal(actual: instances.Count, expected: 2); Assert.Equal( actual: instances.Count(s => s.Host.Equals("ip1") && !s.IsSecure), expected: 1); Assert.Equal( actual: instances.Count(s => s.Host.Equals("ip2") && !s.IsSecure), expected: 1); Assert.Equal( actual: instances.Count(s => s.InstanceId.Equals("uid1")), expected: 1); Assert.Equal( actual: instances.Count(s => s.InstanceId.Equals("uid2")), expected: 1); }
public async Task Start(CancellationToken cancellationToken) { var kubernetesClient = new k8s.Kubernetes(_kubernetesConfiguration); var kubernetesNamespace = _configuration.GetValue <string>(key: "NAMESPACE"); HttpOperationResponse <V1EventList> eventsPerNamespace = await kubernetesClient.ListNamespacedEventWithHttpMessagesAsync(kubernetesNamespace, watch : true, cancellationToken : cancellationToken); _watch = eventsPerNamespace.Watch <V1Event>(async(type, kubernetesEvent) => await HandleKubernetesEvent(type, kubernetesEvent)); }
protected override IKubernetes ConfigureClientForPlatform(k8s.Kubernetes client) { RetryPolicy <KubernetesTransientErrorDetectionStrategy> policy = new RetryPolicy <KubernetesTransientErrorDetectionStrategy>(new ExponentialBackoffRetryStrategy()); client.SetRetryPolicy(policy); return(client); }
public async Task KubernetesSecretProvider_ReloadsDictionaryOnInterval() { // arrange var foundKey = false; var mockHttpMessageHandler = new MockHttpMessageHandler(); mockHttpMessageHandler .Expect(HttpMethod.Get, "*") .Respond(new StringContent("{\"kind\":\"Secret\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"testsecret\",\"namespace\":\"default\",\"selfLink\":\"/api/v1/namespaces/default/secrets/testsecret\",\"uid\":\"04a256d5-5480-4e6a-ab1a-81b1df2b1f15\",\"resourceVersion\":\"724153\",\"creationTimestamp\":\"2020-04-17T14:32:42Z\",\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"v1\\\",\\\"data\\\":{\\\"testKey\\\":\\\"dGVzdFZhbHVl\\\"},\\\"kind\\\":\\\"Secret\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"testsecret\\\",\\\"namespace\\\":\\\"default\\\"},\\\"type\\\":\\\"Opaque\\\"}\\n\"}},\"data\":{\"testKey\":\"dGVzdFZhbHVl\"},\"type\":\"Opaque\"}\n")); mockHttpMessageHandler .Expect(HttpMethod.Get, "*") .Respond(new StringContent("{\"kind\":\"Secret\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"testsecret\",\"namespace\":\"default\",\"selfLink\":\"/api/v1/namespaces/default/secrets/testsecret\",\"uid\":\"04a256d5-5480-4e6a-ab1a-81b1df2b1f15\",\"resourceVersion\":\"724153\",\"creationTimestamp\":\"2020-04-17T14:32:42Z\",\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"v1\\\",\\\"data\\\":{\\\"testKey\\\":\\\"dGVzdFZhbHVl\\\"},\\\"kind\\\":\\\"Secret\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"testsecret\\\",\\\"namespace\\\":\\\"default\\\"},\\\"type\\\":\\\"Opaque\\\"}\\n\"}},\"data\":{\"updatedKey\":\"dGVzdFZhbHVl\"},\"type\":\"Opaque\"}\n")); mockHttpMessageHandler .Expect(HttpMethod.Get, "*") .Respond(new StringContent("{\"kind\":\"Secret\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"testsecret\",\"namespace\":\"default\",\"selfLink\":\"/api/v1/namespaces/default/secrets/testsecret\",\"uid\":\"04a256d5-5480-4e6a-ab1a-81b1df2b1f15\",\"resourceVersion\":\"724153\",\"creationTimestamp\":\"2020-04-17T14:32:42Z\",\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"v1\\\",\\\"data\\\":{\\\"testKey\\\":\\\"dGVzdFZhbHVl\\\"},\\\"kind\\\":\\\"Secret\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"testsecret\\\",\\\"namespace\\\":\\\"default\\\"},\\\"type\\\":\\\"Opaque\\\"}\\n\"}},\"data\":{\"updatedAgain\":\"dGVzdFZhbHVl\"},\"type\":\"Opaque\"}\n")); var client = new k8s.Kubernetes(new KubernetesClientConfiguration() { Host = "http://localhost" }, httpClient: mockHttpMessageHandler.ToHttpClient()); var settings = new KubernetesConfigSourceSettings("default", "testsecret", new ReloadSettings() { Period = 1, Secrets = true }); var provider = new KubernetesSecretProvider(client, settings, new CancellationTokenSource(20000).Token); // act provider.Load(); // assert Assert.True(provider.TryGet("testKey", out var testValue), "TryGet testKey"); Assert.Equal("testValue", testValue); while (!foundKey) { await Task.Delay(100); foundKey = provider.TryGet("updatedKey", out testValue); if (foundKey) { Assert.Equal("testValue", testValue); } } foundKey = false; while (!foundKey) { await Task.Delay(100); foundKey = provider.TryGet("updatedAgain", out testValue); if (foundKey) { Assert.Equal("testValue", testValue); } } Assert.False(provider.TryGet("testKey", out _), "TryGet testKey after update"); Assert.False(provider.TryGet("updatedKey", out _), "TryGet updatedKey after update"); }
public async Task KubernetesConfigMapProvider_ReloadsDictionaryOnInterval() { // arrange var foundKey = false; var mockHttpMessageHandler = new MockHttpMessageHandler(); mockHttpMessageHandler .Expect(HttpMethod.Get, "*") .Respond(new StringContent("{\"kind\":\"ConfigMap\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"testconfigmap\",\"namespace\":\"default\",\"selfLink\":\"/api/v1/namespaces/default/configmaps/testconfigmap\",\"uid\":\"8582b94c-f4fa-47fa-bacc-47019223775c\",\"resourceVersion\":\"1320622\",\"creationTimestamp\":\"2020-04-15T18:33:49Z\",\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"v1\\\",\\\"data\\\":{\\\"ConfigMapName\\\":\\\"testconfigmap\\\"},\\\"kind\\\":\\\"ConfigMap\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"kubernetes1\\\",\\\"namespace\\\":\\\"default\\\"}}\\n\"}},\"data\":{\"TestKey\":\"TestValue\"}}\n")); mockHttpMessageHandler .Expect(HttpMethod.Get, "*") .Respond(new StringContent("{\"kind\":\"ConfigMap\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"testconfigmap\",\"namespace\":\"default\",\"selfLink\":\"/api/v1/namespaces/default/configmaps/testconfigmap\",\"uid\":\"8582b94c-f4fa-47fa-bacc-47019223775c\",\"resourceVersion\":\"1320622\",\"creationTimestamp\":\"2020-04-15T18:33:49Z\",\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"v1\\\",\\\"data\\\":{\\\"ConfigMapName\\\":\\\"testconfigmap\\\"},\\\"kind\\\":\\\"ConfigMap\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"kubernetes1\\\",\\\"namespace\\\":\\\"default\\\"}}\\n\"}},\"data\":{\"TestKey2\":\"UpdatedValue\"}}\n")); mockHttpMessageHandler .Expect(HttpMethod.Get, "*") .Respond(new StringContent("{\"kind\":\"ConfigMap\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"testconfigmap\",\"namespace\":\"default\",\"selfLink\":\"/api/v1/namespaces/default/configmaps/testconfigmap\",\"uid\":\"8582b94c-f4fa-47fa-bacc-47019223775c\",\"resourceVersion\":\"1320622\",\"creationTimestamp\":\"2020-04-15T18:33:49Z\",\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"v1\\\",\\\"data\\\":{\\\"ConfigMapName\\\":\\\"testconfigmap\\\"},\\\"kind\\\":\\\"ConfigMap\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"kubernetes1\\\",\\\"namespace\\\":\\\"default\\\"}}\\n\"}},\"data\":{\"TestKey3\":\"UpdatedAgain\"}}\n")); using var client = new k8s.Kubernetes(new KubernetesClientConfiguration { Host = "http://localhost" }, httpClient: mockHttpMessageHandler.ToHttpClient()); var settings = new KubernetesConfigSourceSettings("default", "testconfigmap", new ReloadSettings() { Period = 1, ConfigMaps = true }); var provider = new KubernetesConfigMapProvider(client, settings, new CancellationTokenSource(20000).Token); // act provider.Load(); // assert Assert.True(provider.TryGet("TestKey", out var testValue), "TryGet TestKey"); Assert.Equal("TestValue", testValue); while (!foundKey) { await Task.Delay(100); foundKey = provider.TryGet("TestKey2", out var testValue2); if (foundKey) { Assert.Equal("UpdatedValue", testValue2); } } foundKey = false; while (!foundKey) { await Task.Delay(100); foundKey = provider.TryGet("TestKey3", out var testValue3); if (foundKey) { Assert.Equal("UpdatedAgain", testValue3); } } Assert.False(provider.TryGet("TestKey", out _), "TryGet TestKey after update"); Assert.False(provider.TryGet("TestKey2", out _), "TryGet TestKey2 after update"); }
public WebSocketBuilder ExpectServerCertificate(X509Certificate2Collection serverCertificate) { Options.RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { return(Kubernetes.CertificateValidationCallBack(sender, serverCertificate, certificate, chain, sslPolicyErrors)); }; return(this); }
/// <summary> /// Initializes a new instance of the <see cref="Kubernetes" /> class. /// </summary> /// <param name='config'> /// Optional. The delegating handlers to add to the http client pipeline. /// </param> /// <param name="handlers"> /// Optional. The delegating handlers to add to the http client pipeline. /// </param> public Kubernetes(KubernetesClientConfiguration config, params DelegatingHandler[] handlers) : this(handlers) { if (string.IsNullOrWhiteSpace(config.Host)) { throw new KubeConfigException("Host url must be set"); } try { BaseUri = new Uri(config.Host); } catch (UriFormatException e) { throw new KubeConfigException("Bad host url", e); } CaCert = config.SslCaCert; SkipTlsVerify = config.SkipTlsVerify; if (BaseUri.Scheme == "https") { if (config.SkipTlsVerify) { #if NET452 ((WebRequestHandler)HttpClientHandler).ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; #else HttpClientHandler.ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true; #endif } else { if (CaCert == null) { throw new KubeConfigException("a CA must be set when SkipTlsVerify === false"); } #if NET452 ((WebRequestHandler)HttpClientHandler).ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { return(Kubernetes.CertificateValidationCallBack(sender, CaCert, certificate, chain, sslPolicyErrors)); }; #else HttpClientHandler.ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) => { return(Kubernetes.CertificateValidationCallBack(sender, CaCert, certificate, chain, sslPolicyErrors)); }; #endif } } // set credentails for the kubernernet client SetCredentials(config, HttpClientHandler); }
public void ExistingClientIsNotReplaced() { using var client = new k8s.Kubernetes(KubernetesClientConfiguration.BuildDefaultConfig()); var services = new ServiceCollection(); services.AddSingleton <IKubernetes>(client); services.AddKubernetesCore(); var serviceProvider = services.BuildServiceProvider(); Assert.Same(client, serviceProvider.GetService <IKubernetes>()); }
public void GetInstances_ThrowsOnNull() { var k8SDiscoveryOptions = new TestOptionsMonitor <KubernetesDiscoveryOptions>(new KubernetesDiscoveryOptions()); using var client = new k8s.Kubernetes(new KubernetesClientConfiguration { Host = "http://localhost" }); var testK8SDiscoveryClient = new KubernetesDiscoveryClient( new DefaultIsServicePortSecureResolver(k8SDiscoveryOptions.CurrentValue), client, k8SDiscoveryOptions); Assert.Throws <ArgumentNullException>(() => testK8SDiscoveryClient.GetInstances(null)); }
public void EnabledPropertyWorksBothWays() { // arrange var mockHttpMessageHandler = new MockHttpMessageHandler(); mockHttpMessageHandler .When(HttpMethod.Get, "/api/v1/namespaces/test/services") .Respond( HttpStatusCode.OK, new StringContent( "{\"apiVersion\":\"v1\",\"items\":[{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":" + "{\"labels\":{\"label1\":\"value1\"},\"name\":\"endpoint1\",\"namespace\":\"test\",\"uid\":" + "\"uids1\"}},{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"labels\":{\"label2\":" + "\"value2\"},\"name\":\"endpoint2\",\"namespace\":\"test\",\"uid\":\"uids2\"}}]," + "\"kind\":\"List\",\"metadata\"" + ":{\"resourceVersion\":\"\",\"selfLink\":\"\"}}")); using var client = new k8s.Kubernetes( config: new KubernetesClientConfiguration { Host = "http://localhost" }, httpClient: mockHttpMessageHandler.ToHttpClient()); var k8sOptions = new KubernetesDiscoveryOptions() { Enabled = false, Namespace = "test" }; var options = new TestOptionsMonitor <KubernetesDiscoveryOptions>(k8sOptions); var discoveryClient = new KubernetesDiscoveryClient( new DefaultIsServicePortSecureResolver(options.CurrentValue), client, options); // act var services = discoveryClient.Services; // assert Assert.NotNull(services); Assert.Empty(services); // turn it on k8sOptions.Enabled = true; // act services = discoveryClient.Services; // assert Assert.NotNull(services); Assert.Equal(actual: services.Count, expected: 2); Assert.True(services.Contains("endpoint1")); Assert.True(services.Contains("endpoint2")); }
public async Task ReturnsNullOnFailureToGetCurrentPod() { var mockHttpMessageHandler = new MockHttpMessageHandler(); mockHttpMessageHandler.Expect(HttpMethod.Get, "*").Respond(HttpStatusCode.NotFound); var appOptions = new KubernetesApplicationOptions(new ConfigurationBuilder().Build()); using var client = new k8s.Kubernetes(new KubernetesClientConfiguration { Host = "http://localhost" }, httpClient: mockHttpMessageHandler.ToHttpClient()); var utils = new StandardPodUtilities(appOptions, null, client); var getPodResult = await utils.GetCurrentPodAsync(); Assert.Null(getPodResult); }
public void KubernetesProviderGetsNewLoggerFactory() { // arrange using var client = new k8s.Kubernetes(new KubernetesClientConfiguration { Host = "http://localhost" }, new HttpClient()); var settings = new KubernetesConfigSourceSettings("default", "testconfigmap", new ReloadSettings()); var provider = new KubernetesConfigMapProvider(client, settings); var originalLoggerFactory = settings.LoggerFactory; var newFactory = new LoggerFactory(); provider.ProvideRuntimeReplacements(newFactory); Assert.Equal(newFactory, settings.LoggerFactory); Assert.NotEqual(originalLoggerFactory, settings.LoggerFactory); }
public void KubernetesConfigMapProvider_ThrowsOn403() { var mockHttpMessageHandler = new MockHttpMessageHandler(); mockHttpMessageHandler.Expect(HttpMethod.Get, "*").Respond(HttpStatusCode.Forbidden); using var client = new k8s.Kubernetes(new KubernetesClientConfiguration { Host = "http://localhost" }, httpClient: mockHttpMessageHandler.ToHttpClient()); var settings = new KubernetesConfigSourceSettings("default", "test", new ReloadSettings()); var provider = new KubernetesConfigMapProvider(client, settings); var ex = Assert.Throws <HttpOperationException>(() => provider.Load()); Assert.Equal(HttpStatusCode.Forbidden, ex.Response.StatusCode); }
public void Constructor_Initializes_Correctly() { var mockHttpMessageHandler = new MockHttpMessageHandler(); using var client = new k8s.Kubernetes(new KubernetesClientConfiguration { Host = "http://localhost" }, mockHttpMessageHandler.ToHttpClient()); const string expectedDesc = "Steeltoe provided Kubernetes native service discovery client"; var k8SDiscoveryOptions = new TestOptionsMonitor <KubernetesDiscoveryOptions>(new KubernetesDiscoveryOptions()); var testK8SDiscoveryClient = new KubernetesDiscoveryClient( new DefaultIsServicePortSecureResolver(k8SDiscoveryOptions.CurrentValue), client, k8SDiscoveryOptions); Assert.Equal(expectedDesc, testK8SDiscoveryClient.Description); }
public void ExistingClientIsNotReplaced() { // arrange using var client = new k8s.Kubernetes(KubernetesClientConfiguration.BuildDefaultConfig()); var services = new ServiceCollection(); // act services.AddSingleton <IKubernetes>(client); services.AddKubernetesCore(); // assert var serviceProvider = services.BuildServiceProvider(); serviceProvider.GetService <IKubernetes>().ShouldBeSameAs(client); }
public void KubernetesProviderGetsNewLogger() { // arrange using var client = new k8s.Kubernetes(new KubernetesClientConfiguration { Host = "http://localhost" }, new HttpClient()); var settings = new KubernetesConfigSourceSettings("default", "testconfigmap", new ReloadSettings()); var provider = new KubernetesConfigMapProvider(client, settings); settings.LoggerFactory ??= new LoggerFactory(); var firstLogger = settings.LoggerFactory.CreateLogger <KubernetesConfigMapProviderTest>(); provider.ProvideRuntimeReplacements(new LoggerFactory()); var secondLogger = settings.LoggerFactory.CreateLogger <KubernetesConfigMapProviderTest>(); Assert.NotEqual(firstLogger.GetHashCode(), secondLogger.GetHashCode()); }
public void ConnectOnClusterNative() { var kubeconfig = new FileInfo("./config"); var config = KubernetesClientConfiguration.BuildConfigFromConfigFile(kubeconfig); IKubernetes client = new k8s.Kubernetes(config); var list = client.ListNamespacedPod("kube-system"); Assert.AreEqual(list.Items.Count > 0, true); foreach (var item in list.Items) { Trace.WriteLine(item.Metadata.Name); } }
public void KubernetesConfigMapProvider_SeesDoubleUnderscore() { var mockHttpMessageHandler = new MockHttpMessageHandler(); mockHttpMessageHandler .Expect(HttpMethod.Get, "*") .Respond(new StringContent("{\"kind\":\"ConfigMap\",\"apiVersion\":\"v1\",\"metadata\":{\"name\":\"testconfigmap\",\"namespace\":\"default\",\"selfLink\":\"/api/v1/namespaces/default/configmaps/testconfigmap\",\"uid\":\"8582b94c-f4fa-47fa-bacc-47019223775c\",\"resourceVersion\":\"1320622\",\"creationTimestamp\":\"2020-04-15T18:33:49Z\",\"annotations\":{\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"v1\\\",\\\"data\\\":{\\\"ConfigMapName\\\":\\\"testconfigmap\\\"},\\\"kind\\\":\\\"ConfigMap\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"kubernetes1\\\",\\\"namespace\\\":\\\"default\\\"}}\\n\"}},\"data\":{\"several__layers__deep__TestKey\":\"TestValue\"}}\n")); using var client = new k8s.Kubernetes(new KubernetesClientConfiguration { Host = "http://localhost" }, httpClient: mockHttpMessageHandler.ToHttpClient()); var settings = new KubernetesConfigSourceSettings("default", "testconfigmap", new ReloadSettings()); var provider = new KubernetesConfigMapProvider(client, settings); provider.Load(); Assert.True(provider.TryGet("several:layers:deep:TestKey", out var testValue)); Assert.Equal("TestValue", testValue); }
public async Task KubernetesSecretProvider_ContinuesOn404() { var mockHttpMessageHandler = new MockHttpMessageHandler(); mockHttpMessageHandler.Expect(HttpMethod.Get, "*").Respond(HttpStatusCode.NotFound); using var client = new k8s.Kubernetes(new KubernetesClientConfiguration { Host = "http://localhost" }, httpClient: mockHttpMessageHandler.ToHttpClient()); var settings = new KubernetesConfigSourceSettings("default", "test", new ReloadSettings() { ConfigMaps = true, Period = 0 }); var provider = new KubernetesConfigMapProvider(client, settings); provider.Load(); await Task.Delay(50); Assert.True(provider.Polling, "Provider has begun polling"); }
public KubernetesClusterAgent( IClusterMembershipService clusterMembershipService, ILogger <KubernetesClusterAgent> logger, IOptionsMonitor <KubernetesHostingOptions> options, IOptions <ClusterOptions> clusterOptions, ILocalSiloDetails localSiloDetails) { _localSiloDetails = localSiloDetails; _logger = logger; _shutdownToken = new CancellationTokenSource(); _options = options; _clusterOptions = clusterOptions.Value; _clusterMembershipService = clusterMembershipService; _config = _options.CurrentValue.GetClientConfiguration?.Invoke() ?? throw new ArgumentNullException(nameof(KubernetesHostingOptions) + "." + nameof(KubernetesHostingOptions.GetClientConfiguration)); _client = new k8s.Kubernetes(_config); _podLabelSelector = $"{KubernetesHostingOptions.ServiceIdLabel}={_clusterOptions.ServiceId},{KubernetesHostingOptions.ClusterIdLabel}={_clusterOptions.ClusterId}"; _podNamespace = _options.CurrentValue.Namespace; _podName = _options.CurrentValue.PodName; }
public void GetServices_ShouldReturnOnlyMatchingServicesWhenLabelsAreAppliedToTheClient() { // arrange var mockHttpMessageHandler = new MockHttpMessageHandler(); mockHttpMessageHandler.When(HttpMethod.Get, "/api/v1/namespaces/test/services") .WithQueryString("labelSelector=label%3Dvalue") .Respond( HttpStatusCode.OK, new StringContent( "{\"apiVersion\":\"v1\",\"items\":[{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":" + "{\"labels\":{\"label1\":\"value1\"},\"name\":\"endpoint1\",\"namespace\":\"test\",\"uid\":" + "\"uids1\"}},{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"labels\":{\"label2\":" + "\"value2\"},\"name\":\"endpoint2\",\"namespace\":\"test\",\"uid\":\"uids2\"}}]," + "\"kind\":\"List\",\"metadata\"" + ":{\"resourceVersion\":\"\",\"selfLink\":\"\"}}")); using var client = new k8s.Kubernetes( config: new KubernetesClientConfiguration { Host = "http://localhost" }, httpClient: mockHttpMessageHandler.ToHttpClient()); var options = new KubernetesDiscoveryOptions() { Namespace = "test" }; var discoveryClient = new KubernetesDiscoveryClient( new DefaultIsServicePortSecureResolver(options), client, options); // act var services = discoveryClient.GetServices(new Dictionary <string, string> { { "label", "value" } }); // assert Assert.NotNull(services); Assert.Equal(actual: services.Count, expected: 2); Assert.True(services.Contains("endpoint1")); Assert.True(services.Contains("endpoint2")); }