示例#1
0
        public void Cert()
        {
            var serverCertificateData = File.ReadAllText("assets/apiserver-pfx-data.txt");

            var clientCertificateKeyData = File.ReadAllText("assets/client-key-data.txt");
            var clientCertificateData    = File.ReadAllText("assets/client-certificate-data.txt");

            X509Certificate2 serverCertificate = null;

            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                using (var serverCertificateStream =
                           new MemoryStream(Convert.FromBase64String(serverCertificateData)))
                {
                    serverCertificate = OpenCertificateStore(serverCertificateStream);
                }
            }
            else
            {
                serverCertificate = new X509Certificate2(Convert.FromBase64String(serverCertificateData), "");
            }

            var clientCertificate = new X509Certificate2(Convert.FromBase64String(clientCertificateData), "");

            var clientCertificateValidationCalled = false;

            using (var server = new MockKubeApiServer(testOutput, listenConfigure: options =>
            {
                options.UseHttps(new HttpsConnectionAdapterOptions
                {
                    ServerCertificate = serverCertificate,
                    ClientCertificateMode = ClientCertificateMode.RequireCertificate,
                    ClientCertificateValidation = (certificate, chain, valid) =>
                    {
                        clientCertificateValidationCalled = true;
                        return(clientCertificate.Equals(certificate));
                    },
                });
            }))
            {
                {
                    clientCertificateValidationCalled = false;
                    var client = new Kubernetes(new KubernetesClientConfiguration
                    {
                        Host = server.Uri.ToString(),
                        ClientCertificateData    = clientCertificateData,
                        ClientCertificateKeyData = clientCertificateKeyData,
                        SslCaCerts    = new X509Certificate2Collection(serverCertificate),
                        SkipTlsVerify = false,
                    });

                    var listTask = ExecuteListPods(client);

                    Assert.True(clientCertificateValidationCalled);
                    Assert.True(listTask.Response.IsSuccessStatusCode);
                    Assert.Equal(1, listTask.Body.Items.Count);
                }

                {
                    clientCertificateValidationCalled = false;
                    var client = new Kubernetes(new KubernetesClientConfiguration
                    {
                        Host = server.Uri.ToString(),
                        ClientCertificateData    = clientCertificateData,
                        ClientCertificateKeyData = clientCertificateKeyData,
                        SkipTlsVerify            = true,
                    });

                    var listTask = ExecuteListPods(client);

                    Assert.True(clientCertificateValidationCalled);
                    Assert.True(listTask.Response.IsSuccessStatusCode);
                    Assert.Equal(1, listTask.Body.Items.Count);
                }

                {
                    clientCertificateValidationCalled = false;
                    var client = new Kubernetes(new KubernetesClientConfiguration
                    {
                        Host = server.Uri.ToString(),
                        ClientCertificateFilePath =
                            "assets/client.crt", // TODO amazoning why client.crt != client-data.txt
                        ClientKeyFilePath = "assets/client.key",
                        SkipTlsVerify     = true,
                    });

                    Assert.ThrowsAny <Exception>(() => ExecuteListPods(client));
                    Assert.True(clientCertificateValidationCalled);
                }

                {
                    clientCertificateValidationCalled = false;
                    var client = new Kubernetes(new KubernetesClientConfiguration
                    {
                        Host          = server.Uri.ToString(),
                        SkipTlsVerify = true,
                    });

                    Assert.ThrowsAny <Exception>(() => ExecuteListPods(client));
                    Assert.False(clientCertificateValidationCalled);
                }
            }
        }
示例#2
0
        public void Token()
        {
            const string token = "testingtoken";

            using (var server = new MockKubeApiServer(testOutput, cxt =>
            {
                var header = cxt.Request.Headers["Authorization"].FirstOrDefault();

                var expect = new AuthenticationHeaderValue("Bearer", token).ToString();

                if (header != expect)
                {
                    cxt.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    return(Task.FromResult(false));
                }

                return(Task.FromResult(true));
            }))
            {
                {
                    var client = new Kubernetes(new KubernetesClientConfiguration
                    {
                        Host        = server.Uri.ToString(),
                        AccessToken = token,
                    });

                    var listTask = ExecuteListPods(client);
                    Assert.True(listTask.Response.IsSuccessStatusCode);
                    Assert.Equal(1, listTask.Body.Items.Count);
                }

                {
                    var client = new Kubernetes(new KubernetesClientConfiguration
                    {
                        Host        = server.Uri.ToString(),
                        AccessToken = "wrong token",
                    });

                    var listTask = ExecuteListPods(client);

                    Assert.Equal(HttpStatusCode.Unauthorized, listTask.Response.StatusCode);
                }


                {
                    var client = new Kubernetes(new KubernetesClientConfiguration
                    {
                        Host     = server.Uri.ToString(),
                        Username = "******",
                        Password = "******",
                    });

                    var listTask = ExecuteListPods(client);

                    Assert.Equal(HttpStatusCode.Unauthorized, listTask.Response.StatusCode);
                }

                {
                    var client = new Kubernetes(new KubernetesClientConfiguration {
                        Host = server.Uri.ToString()
                    });

                    var listTask = ExecuteListPods(client);

                    Assert.Equal(HttpStatusCode.Unauthorized, listTask.Response.StatusCode);
                }
            }
        }
示例#3
0
        public void BasicAuth()
        {
            const string testName     = "test_name";
            const string testPassword = "******";

            using (var server = new MockKubeApiServer(testOutput, cxt =>
            {
                var header = cxt.Request.Headers["Authorization"].FirstOrDefault();

                var expect = new AuthenticationHeaderValue("Basic",
                                                           Convert.ToBase64String(Encoding.UTF8.GetBytes($"{testName}:{testPassword}")))
                             .ToString();

                if (header != expect)
                {
                    cxt.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                    return(Task.FromResult(false));
                }

                return(Task.FromResult(true));
            }))
            {
                {
                    var client = new Kubernetes(new KubernetesClientConfiguration
                    {
                        Host     = server.Uri.ToString(),
                        Username = testName,
                        Password = testPassword,
                    });

                    var listTask = ExecuteListPods(client);
                    Assert.True(listTask.Response.IsSuccessStatusCode);
                    Assert.Equal(1, listTask.Body.Items.Count);
                }

                {
                    var client = new Kubernetes(new KubernetesClientConfiguration
                    {
                        Host     = server.Uri.ToString(),
                        Username = "******",
                        Password = testPassword,
                    });

                    var listTask = ExecuteListPods(client);

                    Assert.Equal(HttpStatusCode.Unauthorized, listTask.Response.StatusCode);
                }

                {
                    var client = new Kubernetes(new KubernetesClientConfiguration
                    {
                        Host     = server.Uri.ToString(),
                        Username = testName,
                        Password = "******",
                    });

                    var listTask = ExecuteListPods(client);

                    Assert.Equal(HttpStatusCode.Unauthorized, listTask.Response.StatusCode);
                }

                {
                    var client = new Kubernetes(new KubernetesClientConfiguration
                    {
                        Host     = server.Uri.ToString(),
                        Username = "******",
                        Password = "******",
                    });

                    var listTask = ExecuteListPods(client);

                    Assert.Equal(HttpStatusCode.Unauthorized, listTask.Response.StatusCode);
                }

                {
                    var client = new Kubernetes(new KubernetesClientConfiguration {
                        Host = server.Uri.ToString()
                    });

                    var listTask = ExecuteListPods(client);

                    Assert.Equal(HttpStatusCode.Unauthorized, listTask.Response.StatusCode);
                }

                {
                    var client = new Kubernetes(new KubernetesClientConfiguration
                    {
                        Host     = server.Uri.ToString(),
                        Username = "******",
                    });

                    var listTask = ExecuteListPods(client);

                    Assert.Equal(HttpStatusCode.Unauthorized, listTask.Response.StatusCode);
                }
            }
        }
示例#4
0
        public void ExternalCertificate()
        {
            const string name = "testing_irrelevant";

            var serverCertificateData = Convert.FromBase64String(File.ReadAllText("assets/apiserver-pfx-data.txt"));

            var clientCertificateKeyData = Convert.FromBase64String(File.ReadAllText("assets/client-key-data.txt"));
            var clientCertificateData    = Convert.FromBase64String(File.ReadAllText("assets/client-certificate-data.txt"));

            X509Certificate2 serverCertificate = null;

            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                using (MemoryStream serverCertificateStream = new MemoryStream(serverCertificateData))
                {
                    serverCertificate = OpenCertificateStore(serverCertificateStream);
                }
            }
            else
            {
                serverCertificate = new X509Certificate2(serverCertificateData, "");
            }

            var clientCertificate = new X509Certificate2(clientCertificateData, "");

            var clientCertificateValidationCalled = false;

            using (var server = new MockKubeApiServer(testOutput, listenConfigure: options =>
            {
                options.UseHttps(new HttpsConnectionAdapterOptions
                {
                    ServerCertificate = serverCertificate,
                    ClientCertificateMode = ClientCertificateMode.RequireCertificate,
                    ClientCertificateValidation = (certificate, chain, valid) =>
                    {
                        clientCertificateValidationCalled = true;
                        return(clientCertificate.Equals(certificate));
                    },
                });
            }))
            {
                {
                    var clientCertificateText    = Encoding.ASCII.GetString(clientCertificateData).Replace("\n", "\\n");
                    var clientCertificateKeyText = Encoding.ASCII.GetString(clientCertificateKeyData).Replace("\n", "\\n");
                    var responseJson             = $"{{\"apiVersion\":\"testingversion\",\"status\":{{\"clientCertificateData\":\"{clientCertificateText}\",\"clientKeyData\":\"{clientCertificateKeyText}\"}}}}";
                    var kubernetesConfig         = GetK8SConfiguration(server.Uri.ToString(), responseJson, name);
                    var clientConfig             = KubernetesClientConfiguration.BuildConfigFromConfigObject(kubernetesConfig, name);
                    var client   = new Kubernetes(clientConfig);
                    var listTask = ExecuteListPods(client);
                    Assert.True(listTask.Response.IsSuccessStatusCode);
                    Assert.Equal(1, listTask.Body.Items.Count);
                }
                {
                    var clientCertificateText    = File.ReadAllText("assets/client.crt").Replace("\n", "\\n");
                    var clientCertificateKeyText = File.ReadAllText("assets/client.key").Replace("\n", "\\n");
                    var responseJson             = $"{{\"apiVersion\":\"testingversion\",\"status\":{{\"clientCertificateData\":\"{clientCertificateText}\",\"clientKeyData\":\"{clientCertificateKeyText}\"}}}}";
                    var kubernetesConfig         = GetK8SConfiguration(server.Uri.ToString(), responseJson, name);
                    var clientConfig             = KubernetesClientConfiguration.BuildConfigFromConfigObject(kubernetesConfig, name);
                    var client = new Kubernetes(clientConfig);
                    Assert.ThrowsAny <Exception>(() => ExecuteListPods(client));
                    Assert.True(clientCertificateValidationCalled);
                }
            }
        }
示例#5
0
        public async Task SuriveBadLine()
        {
            AsyncCountdownEvent   eventsReceived   = new AsyncCountdownEvent(5);
            AsyncManualResetEvent serverShutdown   = new AsyncManualResetEvent();
            AsyncManualResetEvent connectionClosed = new AsyncManualResetEvent();

            using (var server =
                       new MockKubeApiServer(
                           testOutput,
                           async httpContext =>
            {
                httpContext.Response.StatusCode = (int)HttpStatusCode.OK;
                httpContext.Response.ContentLength = null;

                await WriteStreamLine(httpContext, MockKubeApiServer.MockPodResponse);
                await WriteStreamLine(httpContext, MockBadStreamLine);
                await WriteStreamLine(httpContext, MockAddedEventStreamLine);
                await WriteStreamLine(httpContext, MockBadStreamLine);
                await WriteStreamLine(httpContext, MockModifiedStreamLine);

                // make server alive, cannot set to int.max as of it would block response
                await serverShutdown.WaitAsync();
                return(false);
            }))
            {
                var client = new Kubernetes(new KubernetesClientConfiguration
                {
                    Host = server.Uri.ToString()
                });

                var listTask = await client.ListNamespacedPodWithHttpMessagesAsync("default", watch : true);

                var events = new HashSet <WatchEventType>();
                var errors = 0;

                var watcher = listTask.Watch <V1Pod>(
                    (type, item) =>
                {
                    testOutput.WriteLine($"Watcher received '{type}' event.");

                    events.Add(type);
                    eventsReceived.Signal();
                },
                    error =>
                {
                    testOutput.WriteLine($"Watcher received '{error.GetType().FullName}' error.");

                    errors += 1;
                    eventsReceived.Signal();
                },
                    onClosed: connectionClosed.Set
                    );

                // wait server yields all events
                await Task.WhenAny(eventsReceived.WaitAsync(), Task.Delay(TestTimeout));

                Assert.True(
                    eventsReceived.CurrentCount == 0,
                    "Timed out waiting for all events / errors to be received."
                    );

                Assert.Contains(WatchEventType.Added, events);
                Assert.Contains(WatchEventType.Modified, events);

                Assert.Equal(3, errors);

                Assert.True(watcher.Watching);

                // Let the server know it can initiate a shut down.
                serverShutdown.Set();

                await Task.WhenAny(connectionClosed.WaitAsync(), Task.Delay(TestTimeout));

                Assert.True(connectionClosed.IsSet);
            }
        }
示例#6
0
        public async Task DirectWatchEventsWithTimeout()
        {
            AsyncCountdownEvent   eventsReceived = new AsyncCountdownEvent(4);
            AsyncManualResetEvent serverShutdown = new AsyncManualResetEvent();

            using (var server = new MockKubeApiServer(testOutput, async httpContext =>
            {
                await Task.Delay(TimeSpan.FromSeconds(120)); // The default timeout is 100 seconds
                await WriteStreamLine(httpContext, MockAddedEventStreamLine);
                await WriteStreamLine(httpContext, MockDeletedStreamLine);
                await WriteStreamLine(httpContext, MockModifiedStreamLine);
                await WriteStreamLine(httpContext, MockErrorStreamLine);

                // make server alive, cannot set to int.max as of it would block response
                await serverShutdown.WaitAsync();
                return(false);
            }))
            {
                var client = new Kubernetes(new KubernetesClientConfiguration
                {
                    Host = server.Uri.ToString()
                });

                var events = new HashSet <WatchEventType>();
                var errors = 0;

                var watcher = await client.WatchNamespacedPodAsync(
                    name : "myPod",
                    @namespace : "default",
                    onEvent :
                    (type, item) =>
                {
                    testOutput.WriteLine($"Watcher received '{type}' event.");

                    events.Add(type);
                    eventsReceived.Signal();
                },
                    onError :
                    error =>
                {
                    testOutput.WriteLine($"Watcher received '{error.GetType().FullName}' error.");

                    errors += 1;
                    eventsReceived.Signal();
                }
                    );

                // wait server yields all events
                await Task.WhenAny(eventsReceived.WaitAsync(), Task.Delay(TestTimeout));

                Assert.True(
                    eventsReceived.CurrentCount == 0,
                    "Timed out waiting for all events / errors to be received."
                    );

                Assert.Contains(WatchEventType.Added, events);
                Assert.Contains(WatchEventType.Deleted, events);
                Assert.Contains(WatchEventType.Modified, events);
                Assert.Contains(WatchEventType.Error, events);

                Assert.Equal(0, errors);

                Assert.True(watcher.Watching);

                serverShutdown.Set();
            }
        }
示例#7
0
        public async Task WatchAllEvents()
        {
            AsyncCountdownEvent   eventsReceived = new AsyncCountdownEvent(4 /* first line of response is eaten by WatcherDelegatingHandler */);
            AsyncManualResetEvent serverShutdown = new AsyncManualResetEvent();
            var waitForClosed = new AsyncManualResetEvent(false);

            using (var server = new MockKubeApiServer(testOutput, async httpContext =>
            {
                await WriteStreamLine(httpContext, MockAddedEventStreamLine);
                await WriteStreamLine(httpContext, MockDeletedStreamLine);
                await WriteStreamLine(httpContext, MockModifiedStreamLine);
                await WriteStreamLine(httpContext, MockErrorStreamLine);

                // make server alive, cannot set to int.max as of it would block response
                await serverShutdown.WaitAsync();
                return(false);
            }))
            {
                var client = new Kubernetes(new KubernetesClientConfiguration
                {
                    Host = server.Uri.ToString()
                });

                var listTask = await client.ListNamespacedPodWithHttpMessagesAsync("default", watch : true);

                var events = new HashSet <WatchEventType>();
                var errors = 0;

                var watcher = listTask.Watch <V1Pod>(
                    (type, item) =>
                {
                    testOutput.WriteLine($"Watcher received '{type}' event.");

                    events.Add(type);
                    eventsReceived.Signal();
                },
                    error =>
                {
                    testOutput.WriteLine($"Watcher received '{error.GetType().FullName}' error.");

                    errors += 1;
                    eventsReceived.Signal();
                },
                    onClosed: waitForClosed.Set
                    );

                // wait server yields all events
                await Task.WhenAny(eventsReceived.WaitAsync(), Task.Delay(TestTimeout));

                Assert.True(
                    eventsReceived.CurrentCount == 0,
                    "Timed out waiting for all events / errors to be received."
                    );

                Assert.Contains(WatchEventType.Added, events);
                Assert.Contains(WatchEventType.Deleted, events);
                Assert.Contains(WatchEventType.Modified, events);
                Assert.Contains(WatchEventType.Error, events);

                Assert.Equal(0, errors);

                Assert.True(watcher.Watching);

                serverShutdown.Set();

                await Task.WhenAny(waitForClosed.WaitAsync(), Task.Delay(TestTimeout));

                Assert.True(waitForClosed.IsSet);
                Assert.False(watcher.Watching);
            }
        }
示例#8
0
        public async Task DisposeWatch()
        {
            var  connectionClosed = new AsyncManualResetEvent();
            var  eventsReceived   = new AsyncCountdownEvent(1);
            bool serverRunning    = true;

            using (var server = new MockKubeApiServer(testOutput, async httpContext =>
            {
                await WriteStreamLine(httpContext, MockKubeApiServer.MockPodResponse);

                while (serverRunning)
                {
                    await WriteStreamLine(httpContext, MockAddedEventStreamLine);
                }

                return(true);
            }))
            {
                var client = new Kubernetes(new KubernetesClientConfiguration
                {
                    Host = server.Uri.ToString()
                });

                var listTask = await client.ListNamespacedPodWithHttpMessagesAsync("default", watch : true);

                var events = new HashSet <WatchEventType>();

                var watcher = listTask.Watch <V1Pod>(
                    (type, item) =>
                {
                    events.Add(type);
                    eventsReceived.Signal();
                },
                    onClosed: connectionClosed.Set
                    );

                // wait at least an event
                await Task.WhenAny(eventsReceived.WaitAsync(), Task.Delay(TestTimeout));

                Assert.True(
                    eventsReceived.CurrentCount == 0,
                    "Timed out waiting for events."
                    );

                Assert.NotEmpty(events);
                Assert.True(watcher.Watching);

                watcher.Dispose();

                events.Clear();

                // Let the server disconnect
                serverRunning = false;

                var timeout = Task.Delay(TestTimeout);

                while (!timeout.IsCompleted && watcher.Watching)
                {
                    await Task.Yield();
                }

                Assert.Empty(events);
                Assert.False(watcher.Watching);
                Assert.True(connectionClosed.IsSet);
            }
        }