Beispiel #1
0
        public static IServiceCollection AddHealthChecksUI(this IServiceCollection services, string databaseName = "healthchecksdb")
        {
            var configuration = services.BuildServiceProvider()
                                .GetService <IConfiguration>();

            services.AddOptions();
            services.Configure <Settings>((settings) =>
            {
                configuration.Bind(Keys.HEALTHCHECKSUI_SECTION_SETTING_KEY, settings);
            });

            services.AddSingleton <IHostedService, HealthCheckCollectorHostedService>();
            services.AddScoped <IHealthCheckFailureNotifier, WebHookFailureNotifier>();
            services.AddScoped <IHealthCheckReportCollector, HealthCheckReportCollector>();
            services.AddDbContext <HealthChecksDb>(db =>
            {
                db.UseSqlite($"Data Source={databaseName}");
            });

            var kubernetesDiscoveryOptions = new KubernetesDiscoveryOptions();

            configuration.Bind(Keys.HEALTHCHECKSUI_KUBERNETES_DISCOVERY_SETTING_KEY, kubernetesDiscoveryOptions);

            if (kubernetesDiscoveryOptions.Enabled)
            {
                services.AddSingleton(kubernetesDiscoveryOptions);
                services.AddHostedService <KubernetesDiscoveryHostedService>();
            }

            var serviceProvider = services.BuildServiceProvider();

            CreateDatabase(serviceProvider).Wait();

            return(services);
        }
Beispiel #2
0
        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 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);
        }
Beispiel #3
0
        public void GetInstances_ThrowsOnNull()
        {
            var k8SDiscoveryOptions = new KubernetesDiscoveryOptions();

            using var client = new Kubernetes(new KubernetesClientConfiguration { Host = "http://localhost" });
            var testK8SDiscoveryClient = new KubernetesDiscoveryClient(
                new DefaultIsServicePortSecureResolver(k8SDiscoveryOptions),
                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 void PortNumbers_ShouldBeSecuredIfDefaultOrAdded()
        {
            var properties = new KubernetesDiscoveryOptions();

            properties.KnownSecurePorts.Add(12345);
            var sut = new DefaultIsServicePortSecureResolver(properties);

            Assert.False(sut.Resolve(new Input("dummy")));
            Assert.False(sut.Resolve(new Input("dummy", 8080)));
            Assert.False(sut.Resolve(new Input("dummy", 1234)));

            Assert.True(sut.Resolve(new Input("dummy", 443)));
            Assert.True(sut.Resolve(new Input("dummy", 8443)));
            Assert.True(sut.Resolve(new Input("dummy", 12345)));
        }
Beispiel #6
0
        public static IDiscoveryClient CreateClient(KubernetesDiscoveryOptions options, IKubernetes kubernetes)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (kubernetes == null)
            {
                throw new ArgumentNullException(nameof(kubernetes));
            }

            var isServicePortSecureResolver = new DefaultIsServicePortSecureResolver(options);

            return(new KubernetesDiscoveryClient(isServicePortSecureResolver, kubernetes, options));
        }
Beispiel #7
0
        public void Constructor_Initializes_Correctly()
        {
            // arrange
            var mockHttpMessageHandler = new MockHttpMessageHandler();

            using var client = new Kubernetes(new KubernetesClientConfiguration { Host = "http://localhost" }, mockHttpMessageHandler.ToHttpClient());
            const string expectedDesc        = "Steeltoe provided Kubernetes native service discovery client";
            var          k8SDiscoveryOptions = new KubernetesDiscoveryOptions();

            // act
            var testK8SDiscoveryClient = new KubernetesDiscoveryClient(
                new DefaultIsServicePortSecureResolver(k8SDiscoveryOptions),
                client,
                k8SDiscoveryOptions);

            // assert
            Assert.Equal(expectedDesc, testK8SDiscoveryClient.Description);
        }
Beispiel #8
0
        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 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"));
        }
Beispiel #9
0
        public static IServiceCollection AddBeatPulseUI(this IServiceCollection services)
        {
            var configuration = services.BuildServiceProvider()
                                .GetService <IConfiguration>();

            services.AddOptions();
            services.Configure <BeatPulseSettings>((settings) =>
            {
                configuration.Bind(BeatPulseUIKeys.BEATPULSEUI_SECTION_SETTING_KEY, settings);
            });

            services.AddSingleton <IHostedService, LivenessHostedService>();

            services.AddScoped <ILivenessFailureNotifier, WebHookFailureNotifier>();
            services.AddScoped <ILivenessRunner, LivenessRunner>();
            services.AddDbContext <LivenessDb>(db =>
            {
                db.UseSqlite("Data Source=livenessdb");
            });

            var kubernetesDiscoveryOptions = new KubernetesDiscoveryOptions();

            configuration.Bind(BeatPulseUIKeys.BEATPULSEUI_KUBERNETES_DISCOVERY_SETTING_KEY, kubernetesDiscoveryOptions);

            if (kubernetesDiscoveryOptions.Enabled)
            {
                services.AddSingleton(kubernetesDiscoveryOptions);
                services.AddHostedService <KubernetesDiscoveryHostedService>();
            }

            var serviceProvider = services.BuildServiceProvider();

            CreateDatabase(serviceProvider).Wait();

            return(services);
        }