Exemplo n.º 1
0
        public async Task Usbmuxd_CanListDevices_Async()
        {
            var config = KubernetesClientConfiguration.BuildDefaultConfig();

            if (config.Namespace == null)
            {
                config.Namespace = "default";
            }

            using (var kubernetes = new KubernetesProtocol(
                       config,
                       this.loggerFactory.CreateLogger <KubernetesProtocol>(),
                       this.loggerFactory))
                using (var client = new KubernetesClient(
                           kubernetes,
                           KubernetesOptions.Default,
                           this.output.BuildLoggerFor <KubernetesClient>(),
                           this.loggerFactory))
                {
                    // There's at least one usbmuxd pod
                    var pods = await kubernetes.ListNamespacedPodAsync(config.Namespace, labelSelector : "app.kubernetes.io/component=usbmuxd");

                    Assert.NotEmpty(pods.Items);
                    var pod = pods.Items[0];

                    // The pod is in the running state
                    pod = await client.WaitForPodRunningAsync(pod, TimeSpan.FromMinutes(2), default).ConfigureAwait(false);

                    Assert.Equal("Running", pod.Status.Phase);

                    // We can connect to port 27015 and retrieve an empty device list
                    var locator     = new KubernetesMuxerSocketLocator(kubernetes, pod, this.loggerFactory.CreateLogger <KubernetesMuxerSocketLocator>(), this.loggerFactory);
                    var muxerClient = new MuxerClient(locator, this.loggerFactory.CreateLogger <MuxerClient>(), this.loggerFactory);

                    var devices = await muxerClient.ListDevicesAsync(default).ConfigureAwait(false);
Exemplo n.º 2
0
        public void KubernetesClient_IsConfigured()
        {
            using (var protocol = new KubernetesProtocol(
                       KubernetesClientConfiguration.BuildConfigFromConfigFile("Polyfill/kubeconfig.yml"),
                       NullLogger <KubernetesProtocol> .Instance,
                       NullLoggerFactory.Instance))
            {
                Assert.Collection(
                    protocol.HttpMessageHandlers,
                    (h) =>
                {
                    var apiHandler = Assert.IsType <CoreApiHandler>(h);
                    Assert.NotNull(apiHandler.InnerHandler);
                },
                    (h) =>
                {
                    var watchHandler = Assert.IsType <WatchHandler>(h);
                    Assert.NotNull(watchHandler.InnerHandler);
                },
                    (h) =>
                {
                    var handler = Assert.IsType <HttpClientHandler>(h);
                    Assert.Collection(
                        handler.ClientCertificates.OfType <X509Certificate2>(),
                        c =>
                    {
                        Assert.Equal("C2E33CEADA8CA7416367A0CA639EA155CC920319", c.Thumbprint);
                    });
                });

                Assert.Equal(new Uri("https://127.0.0.1:443"), protocol.BaseUri);
            }
        }
Exemplo n.º 3
0
        public async Task WatchNamespacedObjectAsync_CancelsIfNeeded_Async()
        {
            var readTaskCompletion = new TaskCompletionSource <int>();

            var stream = new Mock <Stream>(MockBehavior.Strict);

            stream.Setup(s => s.CanSeek).Returns(false);
            stream.Setup(s => s.CanRead).Returns(true);
            stream
            .Setup(s => s.ReadAsync(It.IsAny <Memory <byte> >(), It.IsAny <CancellationToken>()))
            .Returns <Memory <byte>, CancellationToken>(async(memory, cancellationToken) => await readTaskCompletion.Task);
            stream
            .Setup(s => s.Close())
            .Callback(() => readTaskCompletion.TrySetException(new ObjectDisposedException("Stream", "Stream is being disposed, and all pending I/O cancelled")))
            .Verifiable();

            var handler = new DummyHandler();

            handler.Responses.Enqueue(
                new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.OK,
                Content    = new WatchHttpContent(
                    new StreamContent(stream.Object)),
            });

            Collection <(WatchEventType, V1Pod)> events = new Collection <(WatchEventType, V1Pod)>();

            var protocol = new KubernetesProtocol(handler, this.loggerFactory.CreateLogger <KubernetesProtocol>(), this.loggerFactory);
            var cts      = new CancellationTokenSource();

            var watchTask = protocol.WatchNamespacedObjectAsync(
                new V1Pod()
            {
                Metadata = new V1ObjectMeta(name: "pod", namespaceProperty: "default", resourceVersion: "1"),
            },
                protocol.ListNamespacedPodWithHttpMessagesAsync,
                (eventType, result) =>
            {
                events.Add((eventType, result));
                return(Task.FromResult(WatchResult.Continue));
            },
                cts.Token);

            Assert.False(watchTask.IsCompleted);
            cts.Cancel();

            await Task.WhenAny(
                watchTask,
                Task.Delay(TimeSpan.FromSeconds(5))).ConfigureAwait(false);

            Assert.True(watchTask.IsCompletedSuccessfully);

            stream.Verify();
        }
Exemplo n.º 4
0
        public async Task ApiServer_Is_Running_Async()
        {
            var config = KubernetesClientConfiguration.BuildDefaultConfig();

            if (config.Namespace == null)
            {
                config.Namespace = "default";
            }

            using (var kubernetes = new KubernetesProtocol(
                       config,
                       this.loggerFactory.CreateLogger <KubernetesProtocol>(),
                       this.loggerFactory))
                using (var client = new KubernetesClient(
                           kubernetes,
                           KubernetesOptions.Default,
                           this.output.BuildLoggerFor <KubernetesClient>(),
                           this.loggerFactory))
                {
                    // There's at least one operator pod
                    var pods = await kubernetes.ListNamespacedPodAsync(config.Namespace, labelSelector : "app.kubernetes.io/component=operator");

                    Assert.NotEmpty(pods.Items);
                    var pod = pods.Items[0];

                    // The pod is in the running state
                    pod = await client.WaitForPodRunningAsync(pod, TimeSpan.FromMinutes(5), default).ConfigureAwait(false);

                    Assert.Equal("Running", pod.Status.Phase);

                    // We can connect to port 80 and fetch the status
                    using (var httpClient = new HttpClient(
                               new SocketsHttpHandler()
                    {
                        ConnectCallback = (context, cancellationToken) => client.ConnectToPodPortAsync(pod, 80, cancellationToken),
                    }))
                    {
                        httpClient.BaseAddress = new Uri("http://localhost:80/");

                        var urls = new string[] { "/", "/health/ready", "/health/alive" };

                        foreach (var url in urls)
                        {
                            var response = await httpClient.GetAsync(url).ConfigureAwait(false);

                            Assert.True(response.IsSuccessStatusCode);
                            Assert.True(response.Headers.TryGetValues("X-Kaponata-Version", out var values));
                            Assert.Equal(ThisAssembly.AssemblyInformationalVersion, Assert.Single(values));
                        }
                    }
                }
        }
Exemplo n.º 5
0
        public async Task WatchNamespacedObjectAsync_ValidatesArguments_Async()
        {
            var pod = new V1Pod()
            {
                Metadata = new V1ObjectMeta()
                {
                    Name = "name", NamespaceProperty = "namespace"
                }
            };

            var protocol = new KubernetesProtocol(new DummyHandler(), this.loggerFactory.CreateLogger <KubernetesProtocol>(), this.loggerFactory);
            await Assert.ThrowsAsync <ArgumentNullException>("value", () => protocol.WatchNamespacedObjectAsync <V1Pod, V1PodList>(null, protocol.ListNamespacedPodWithHttpMessagesAsync, (eventType, result) => Task.FromResult(WatchResult.Continue), default)).ConfigureAwait(false);

            await Assert.ThrowsAsync <ValidationException>(() => protocol.WatchNamespacedObjectAsync <V1Pod, V1PodList>(new V1Pod()
            {
            }, null, (eventType, result) => Task.FromResult(WatchResult.Continue), default)).ConfigureAwait(false);

            await Assert.ThrowsAsync <ValidationException>(() => protocol.WatchNamespacedObjectAsync <V1Pod, V1PodList>(new V1Pod()
            {
                Metadata = new V1ObjectMeta()
            }, null, (eventType, result) => Task.FromResult(WatchResult.Continue), default)).ConfigureAwait(false);

            await Assert.ThrowsAsync <ValidationException>(() => protocol.WatchNamespacedObjectAsync <V1Pod, V1PodList>(new V1Pod()
            {
                Metadata = new V1ObjectMeta()
                {
                    Name = "test"
                }
            }, null, (eventType, result) => Task.FromResult(WatchResult.Continue), default)).ConfigureAwait(false);

            await Assert.ThrowsAsync <ValidationException>(() => protocol.WatchNamespacedObjectAsync <V1Pod, V1PodList>(new V1Pod()
            {
                Metadata = new V1ObjectMeta()
                {
                    NamespaceProperty = "test"
                }
            }, null, (eventType, result) => Task.FromResult(WatchResult.Continue), default)).ConfigureAwait(false);

            await Assert.ThrowsAsync <ArgumentNullException>("listOperation", () => protocol.WatchNamespacedObjectAsync <V1Pod, V1PodList>(pod, null, (eventType, result) => Task.FromResult(WatchResult.Continue), default)).ConfigureAwait(false);

            await Assert.ThrowsAsync <ArgumentNullException>("eventHandler", () => protocol.WatchNamespacedObjectAsync <V1Pod, V1PodList>(pod, protocol.ListNamespacedPodWithHttpMessagesAsync, null, default)).ConfigureAwait(false);

            await Assert.ThrowsAsync <ArgumentNullException>("namespace", () => protocol.WatchNamespacedObjectAsync <V1Pod, V1PodList>(null, string.Empty, string.Empty, string.Empty, null, protocol.ListNamespacedPodWithHttpMessagesAsync, (eventType, result) => Task.FromResult(WatchResult.Continue), default)).ConfigureAwait(false);

            await Assert.ThrowsAsync <ArgumentNullException>("listOperation", () => protocol.WatchNamespacedObjectAsync <V1Pod, V1PodList>("default", null, null, null, null, null, (eventType, result) => Task.FromResult(WatchResult.Continue), default)).ConfigureAwait(false);

            await Assert.ThrowsAsync <ArgumentNullException>("eventHandler", () => protocol.WatchNamespacedObjectAsync <V1Pod, V1PodList>("default", null, null, null, null, protocol.ListNamespacedPodWithHttpMessagesAsync, null, default)).ConfigureAwait(false);
        }
Exemplo n.º 6
0
        public async Task WatchNamespacedObjectAsync_ThrowsExceptionIfNeeded_Async()
        {
            var handler = new DummyHandler();

            handler.Responses.Enqueue(
                new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.OK,
                Content    = new WatchHttpContent(
                    new StringContent(
                        JsonConvert.SerializeObject(
                            new V1WatchEvent()
                {
                    Type           = nameof(WatchEventType.Error),
                    ObjectProperty =
                        new V1Status()
                    {
                        Kind    = "Status",
                        Message = "ErrorMessage",
                    },
                }))),
            });

            Collection <(WatchEventType, V1Pod)> events = new Collection <(WatchEventType, V1Pod)>();

            var protocol = new KubernetesProtocol(handler, this.loggerFactory.CreateLogger <KubernetesProtocol>(), this.loggerFactory);
            var cts      = new CancellationTokenSource();

            var ex = await Assert.ThrowsAsync <KubernetesException>(
                () => protocol.WatchNamespacedObjectAsync(
                    new V1Pod()
            {
                Metadata = new V1ObjectMeta(name: "pod", namespaceProperty: "default", resourceVersion: "1"),
            },
                    protocol.ListNamespacedPodWithHttpMessagesAsync,
                    (eventType, result) =>
            {
                events.Add((eventType, result));
                return(Task.FromResult(WatchResult.Continue));
            },
                    cts.Token)).ConfigureAwait(false);

            Assert.Equal("ErrorMessage", ex.Message);
        }
Exemplo n.º 7
0
        public async Task WatchCustomResourceDefinitionAsync_ValidatesArguments_Async()
        {
            var protocol = new KubernetesProtocol(new DummyHandler(), this.loggerFactory.CreateLogger <KubernetesProtocol>(), this.loggerFactory);
            await Assert.ThrowsAsync <ArgumentNullException>("value", () => protocol.WatchCustomResourceDefinitionAsync(null, (eventType, result) => Task.FromResult(WatchResult.Continue), default)).ConfigureAwait(false);

            await Assert.ThrowsAsync <ValidationException>(() => protocol.WatchCustomResourceDefinitionAsync(new V1CustomResourceDefinition(), (eventType, result) => Task.FromResult(WatchResult.Continue), default)).ConfigureAwait(false);

            await Assert.ThrowsAsync <ValidationException>(() => protocol.WatchCustomResourceDefinitionAsync(new V1CustomResourceDefinition()
            {
                Metadata = new V1ObjectMeta()
            }, (eventType, result) => Task.FromResult(WatchResult.Continue), default)).ConfigureAwait(false);

            await Assert.ThrowsAsync <ArgumentNullException>("eventHandler", () => protocol.WatchCustomResourceDefinitionAsync(new V1CustomResourceDefinition()
            {
                Metadata = new V1ObjectMeta()
                {
                    Name = "test"
                }
            }, null, default)).ConfigureAwait(false);
        }
Exemplo n.º 8
0
        public async Task Registry_Running_Async()
        {
            var config = KubernetesClientConfiguration.BuildDefaultConfig();

            if (config.Namespace == null)
            {
                config.Namespace = "default";
            }

            using (var kubernetes = new KubernetesProtocol(
                       config,
                       this.loggerFactory.CreateLogger <KubernetesProtocol>(),
                       this.loggerFactory))
                using (var client = new KubernetesClient(
                           kubernetes,
                           KubernetesOptions.Default,
                           this.output.BuildLoggerFor <KubernetesClient>(),
                           this.loggerFactory))
                {
                    // There's at least one usbmuxd pod
                    var pods = await kubernetes.ListNamespacedPodAsync(config.Namespace, labelSelector : "app.kubernetes.io/component=registry");

                    Assert.NotEmpty(pods.Items);
                    var pod = pods.Items[0];

                    // The pod is in the running state
                    pod = await client.WaitForPodRunningAsync(pod, TimeSpan.FromMinutes(2), default).ConfigureAwait(false);

                    Assert.Equal("Running", pod.Status.Phase);

                    // Try to perform a handshake
                    var httpClient = client.CreatePodHttpClient(pod, 5000);
                    httpClient.BaseAddress = new Uri($"http://{pod.Metadata.Name}:5000/v2/");

                    var response = await httpClient.GetAsync(string.Empty).ConfigureAwait(false);

                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                    var apiVersion = Assert.Single(response.Headers.GetValues("Docker-Distribution-Api-Version"));
                    Assert.Equal("registry/2.0", apiVersion);
                }
        }
Exemplo n.º 9
0
        public async Task Guacd_PerformsHandshake_Async()
        {
            var config = KubernetesClientConfiguration.BuildDefaultConfig();

            if (config.Namespace == null)
            {
                config.Namespace = "default";
            }

            using (var kubernetes = new KubernetesProtocol(
                       config,
                       this.loggerFactory.CreateLogger <KubernetesProtocol>(),
                       this.loggerFactory))
                using (var client = new KubernetesClient(
                           kubernetes,
                           KubernetesOptions.Default,
                           this.output.BuildLoggerFor <KubernetesClient>(),
                           this.loggerFactory))
                {
                    // There's at least one guacd pod
                    var pods = await kubernetes.ListNamespacedPodAsync(config.Namespace, labelSelector : "app.kubernetes.io/name=guacamole,app.kubernetes.io/component=guacd");

                    Assert.NotEmpty(pods.Items);
                    var pod = pods.Items[0];

                    // The pod is in the running state
                    pod = await client.WaitForPodRunningAsync(pod, Timeout, default).ConfigureAwait(false);

                    Assert.Equal("Running", pod.Status.Phase);

                    // Try to perform a handshake
                    using (var connection = await client.ConnectToPodPortAsync(pod, 4822, default).ConfigureAwait(false))
                    {
                        GuacdProtocol protocol = new GuacdProtocol(connection);

                        // Handshake phase
                        await protocol.SendInstructionAsync("select", new string[] { "vnc" }, default).ConfigureAwait(false);

                        var response = await protocol.ReadInstructionAsync(default);
Exemplo n.º 10
0
        public async Task WatchNamespacedObjectAsync_EmptyContent_Completes_Async()
        {
            var handler = new DummyHandler();

            handler.Responses.Enqueue(
                new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.OK,
                Content    = new WatchHttpContent(
                    new StringContent(string.Empty)),
            });

            Collection <(WatchEventType, V1Pod)> events = new Collection <(WatchEventType, V1Pod)>();

            var protocol = new KubernetesProtocol(handler, this.loggerFactory.CreateLogger <KubernetesProtocol>(), this.loggerFactory);
            var result   = await protocol.WatchNamespacedObjectAsync <V1Pod, V1PodList>(
                new V1Pod()
            {
                Metadata = new V1ObjectMeta(name: "pod", namespaceProperty: "default", resourceVersion: "1"),
            },
                protocol.ListNamespacedPodWithHttpMessagesAsync,
                (eventType, result) =>
            {
                events.Add((eventType, result));
                return(Task.FromResult(WatchResult.Continue));
            },
                default).ConfigureAwait(false);

            Assert.Equal(WatchExitReason.ServerDisconnected, result);
            Assert.Empty(events);
            Assert.Collection(
                handler.Requests,
                r =>
            {
                Assert.Equal(new Uri("http://localhost/api/v1/namespaces/default/pods?allowWatchBookmarks=true&fieldSelector=metadata.name%3Dpod&resourceVersion=1&watch=true"), r.RequestUri);
            });
        }
Exemplo n.º 11
0
        public async Task WatchCustomResourceDefinitionAsync_EmptyContent_Completes_Async()
        {
            var handler = new DummyHandler();

            handler.Responses.Enqueue(
                new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.OK,
                Content    = new WatchHttpContent(
                    new StringContent(string.Empty)),
            });

            Collection <(WatchEventType, V1CustomResourceDefinition)> events = new Collection <(WatchEventType, V1CustomResourceDefinition)>();

            var protocol = new KubernetesProtocol(handler, this.loggerFactory.CreateLogger <KubernetesProtocol>(), this.loggerFactory);
            var result   = await protocol.WatchCustomResourceDefinitionAsync(
                new V1CustomResourceDefinition()
            {
                Metadata = new V1ObjectMeta(name: "crd", namespaceProperty: "default", resourceVersion: "1"),
            },
                (eventType, result) =>
            {
                events.Add((eventType, result));
                return(Task.FromResult(WatchResult.Continue));
            },
                default).ConfigureAwait(false);

            Assert.Equal(WatchExitReason.ServerDisconnected, result);
            Assert.Empty(events);
            Assert.Collection(
                handler.Requests,
                r =>
            {
                Assert.Equal(new Uri("http://localhost/apis/apiextensions.k8s.io/v1/customresourcedefinitions?fieldSelector=metadata.name%3Dcrd&resourceVersion=1&watch=true"), r.RequestUri);
            });
        }
Exemplo n.º 12
0
        public async Task WatchNamespacedObjectAsync_ClientCanStopLoop_Async()
        {
            using (var stream = new SimplexStream())
                using (var writer = new StreamWriter(stream))
                {
                    var handler = new DummyHandler();
                    handler.Responses.Enqueue(
                        new HttpResponseMessage()
                    {
                        StatusCode = HttpStatusCode.OK,
                        Content    = new WatchHttpContent(
                            new StreamContent(stream)),
                    });

                    Collection <(WatchEventType, V1Pod)> events = new Collection <(WatchEventType, V1Pod)>();

                    var protocol = new KubernetesProtocol(handler, this.loggerFactory.CreateLogger <KubernetesProtocol>(), this.loggerFactory);
                    var cts      = new CancellationTokenSource();

                    var watchTask = protocol.WatchNamespacedObjectAsync(
                        new V1Pod()
                    {
                        Metadata = new V1ObjectMeta(name: "pod", namespaceProperty: "default", resourceVersion: "1"),
                    },
                        protocol.ListNamespacedPodWithHttpMessagesAsync,
                        (eventType, result) =>
                    {
                        events.Add((eventType, result));
                        return(Task.FromResult(events.Count == 1 ? WatchResult.Continue : WatchResult.Stop));
                    },
                        cts.Token);

                    Assert.True(!watchTask.IsCompleted);

                    await writer.WriteAsync(
                        JsonConvert.SerializeObject(
                            new V1WatchEvent()
                    {
                        Type           = nameof(WatchEventType.Deleted),
                        ObjectProperty = new V1Pod()
                        {
                            Metadata = new V1ObjectMeta()
                            {
                                NamespaceProperty = "some-namespace",
                                Name = "some-name",
                            },
                        },
                    }));

                    await writer.WriteAsync('\n').ConfigureAwait(false);

                    await writer.FlushAsync().ConfigureAwait(false);

                    Assert.True(!watchTask.IsCompleted);

                    await writer.WriteAsync(
                        JsonConvert.SerializeObject(
                            new V1WatchEvent()
                    {
                        Type           = nameof(WatchEventType.Deleted),
                        ObjectProperty = new V1Pod()
                        {
                            Metadata = new V1ObjectMeta()
                            {
                                NamespaceProperty = "some-namespace2",
                                Name = "some-name2",
                            },
                        },
                    }));

                    await writer.WriteAsync('\n').ConfigureAwait(false);

                    await writer.FlushAsync().ConfigureAwait(false);

                    var result = await watchTask;
                    Assert.Equal(WatchExitReason.ClientDisconnected, result);

                    Assert.Collection(
                        events,
                        e =>
                    {
                        Assert.Equal(WatchEventType.Deleted, e.Item1);
                        Assert.Equal("some-namespace", e.Item2.Metadata.NamespaceProperty);
                        Assert.Equal("some-name", e.Item2.Metadata.Name);
                    },
                        e =>
                    {
                        Assert.Equal(WatchEventType.Deleted, e.Item1);
                        Assert.Equal("some-namespace2", e.Item2.Metadata.NamespaceProperty);
                        Assert.Equal("some-name2", e.Item2.Metadata.Name);
                    });
                }
        }