Exemple #1
0
        public async Task NamespacedPodExecAsyncHttpExceptionWithStatus()
        {
            var kubernetesMock = new Moq.Mock <Kubernetes>(
                new object[] { Moq.Mock.Of <ServiceClientCredentials>(), new DelegatingHandler[] { } });
            var command = new string[] { "/bin/bash", "-c", "echo Hello, World!" };
            var handler = new ExecAsyncCallback((stdIn, stdOut, stdError) => Task.CompletedTask);

            var status = new V1Status();

            kubernetesMock.Setup(m => m.MuxedStreamNamespacedPodExecAsync("pod-name", "pod-namespace", command,
                                                                          "my-container", true, true, true, false, WebSocketProtocol.V4BinaryWebsocketProtocol, null,
                                                                          CancellationToken.None))
            .Throws(new HttpOperationException()
            {
                Body = status
            });

            using (Kubernetes client = kubernetesMock.Object)
            {
                var ex = await Assert.ThrowsAsync <KubernetesException>(() => client.NamespacedPodExecAsync(
                                                                            "pod-name",
                                                                            "pod-namespace", "my-container", command, false, handler, CancellationToken.None))
                         .ConfigureAwait(false);

                Assert.Same(status, ex.Status);
            }
        }
        public async Task NamespacedPodExecAsyncGenericException()
        {
            var kubernetesMock = new Moq.Mock <Kubernetes>(
                new object[] { new KubernetesClientConfiguration()
                               {
                                   Host = "http://localhost"
                               }, new DelegatingHandler[] { } })
            {
                CallBase = true
            };
            var command = new string[] { "/bin/bash", "-c", "echo Hello, World!" };
            var handler = new ExecAsyncCallback((stdIn, stdOut, stdError) => Task.CompletedTask);

            var exception = new Exception();

            kubernetesMock.Setup(m => m.MuxedStreamNamespacedPodExecAsync("pod-name", "pod-namespace", command,
                                                                          "my-container", true, true, true, false, WebSocketProtocol.V4BinaryWebsocketProtocol, null,
                                                                          CancellationToken.None))
            .Throws(exception);

            using (Kubernetes client = kubernetesMock.Object)
            {
                var ex = await Assert.ThrowsAsync <Exception>(() => client.NamespacedPodExecAsync(
                                                                  "pod-name",
                                                                  "pod-namespace", "my-container", command, false, handler, CancellationToken.None))
                         .ConfigureAwait(false);

                Assert.Same(exception, ex);
            }
        }
        public async Task NamespacedPodExecAsyncExitCodeNonZero()
        {
            var processStatus = new V1Status()
            {
                Metadata = null,
                Status   = "Failure",
                Message  = "command terminated with non-zero exit code: Error executing in Docker Container: 1",
                Reason   = "NonZeroExitCode",
                Details  = new V1StatusDetails()
                {
                    Causes = new List <V1StatusCause>()
                    {
                        new V1StatusCause()
                        {
                            Reason = "ExitCode", Message = "1"
                        },
                    },
                },
            };

            var processStatusJson = JsonSerializer.SerializeToUtf8Bytes(processStatus);
            var handler           = new ExecAsyncCallback((stdIn, stdOut, stdError) => Task.CompletedTask);

            using (MemoryStream stdIn = new MemoryStream())
                using (MemoryStream stdOut = new MemoryStream())
                    using (MemoryStream stdErr = new MemoryStream())
                        using (MemoryStream errorStream = new MemoryStream(processStatusJson))
                        {
                            var muxedStream = new Moq.Mock <IStreamDemuxer>();
                            muxedStream.Setup(m => m.GetStream(null, ChannelIndex.StdIn)).Returns(stdIn);
                            muxedStream.Setup(m => m.GetStream(ChannelIndex.StdOut, null)).Returns(stdOut);
                            muxedStream.Setup(m => m.GetStream(ChannelIndex.StdErr, null)).Returns(stdErr);
                            muxedStream.Setup(m => m.GetStream(ChannelIndex.Error, null)).Returns(errorStream);

                            var kubernetesMock = new Moq.Mock <Kubernetes>(
                                new object[] { new KubernetesClientConfiguration()
                                               {
                                                   Host = "http://localhost"
                                               }, new DelegatingHandler[] { } })
                            {
                                CallBase = true
                            };
                            var command = new string[] { "/bin/bash", "-c", "echo Hello, World!" };

                            var exception = new Exception();
                            kubernetesMock.Setup(m => m.MuxedStreamNamespacedPodExecAsync("pod-name", "pod-namespace", command,
                                                                                          "my-container", true, true, true, false, WebSocketProtocol.V4BinaryWebsocketProtocol, null,
                                                                                          CancellationToken.None))
                            .Returns(Task.FromResult(muxedStream.Object));

                            using (Kubernetes client = kubernetesMock.Object)
                            {
                                var exitCode = await client.NamespacedPodExecAsync("pod-name", "pod-namespace", "my-container",
                                                                                   command, false, handler, CancellationToken.None).ConfigureAwait(false);

                                Assert.Equal(1, exitCode);
                            }
                        }
        }
Exemple #4
0
        /// <summary>
        /// Helper method for running node commands via a busybox container.
        /// </summary>
        /// <param name="podName"></param>
        /// <param name="namespace"></param>
        /// <param name="command"></param>
        /// <param name="containerName"></param>
        /// <param name="retry"></param>
        /// <returns>The command output as lines of text.</returns>
        public async Task <string> ExecInPodAsync(
            string podName,
            string @namespace,
            string command,
            string containerName = null,
            bool retry           = false)
        {
            var podCommand = new string[]
            {
                "chroot",
                "/host",
                "/bin/bash",
                "-c",
                command
            };

            var pod = await k8s.ReadNamespacedPodAsync(podName, @namespace);

            if (string.IsNullOrEmpty(containerName))
            {
                containerName = pod.Spec.Containers.FirstOrDefault().Name;
            }

            string stdOut = "";
            string stdErr = "";

            var handler = new ExecAsyncCallback(async(_stdIn, _stdOut, _stdError) =>
            {
                stdOut = Encoding.UTF8.GetString(await _stdOut.ReadToEndAsync());
                stdErr = Encoding.UTF8.GetString(await _stdError.ReadToEndAsync());
            });

            var exitcode = await k8s.NamespacedPodExecAsync(podName, @namespace, containerName, podCommand, true, handler, CancellationToken.None);

            if (exitcode != 0)
            {
                throw new KubernetesException($@"{stdOut}

{stdErr}");
            }

            var result = new StringBuilder();

            foreach (var line in stdOut.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None))
            {
                result.AppendLine(line);
            }

            return(result.ToString());
        }
Exemple #5
0
        public async Task <int> NamespacedPodExecAsync(string name, string @namespace, string container,
                                                       IEnumerable <string> command, bool tty, ExecAsyncCallback action, CancellationToken cancellationToken)
        {
            // All other parameters are being validated by MuxedStreamNamespacedPodExecAsync
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            try
            {
                using (var muxedStream = await this.MuxedStreamNamespacedPodExecAsync(
                           name: name,
                           @namespace: @namespace, command: command, container: container, tty: tty,
                           cancellationToken: cancellationToken).ConfigureAwait(false))
                    using (Stream stdIn = muxedStream.GetStream(null, ChannelIndex.StdIn))
                        using (Stream stdOut = muxedStream.GetStream(ChannelIndex.StdOut, null))
                            using (Stream stdErr = muxedStream.GetStream(ChannelIndex.StdErr, null))
                                using (Stream error = muxedStream.GetStream(ChannelIndex.Error, null))
                                    using (StreamReader errorReader = new StreamReader(error))
                                    {
                                        muxedStream.Start();

                                        await action(stdIn, stdOut, stdErr).ConfigureAwait(false);

                                        var errors = await errorReader.ReadToEndAsync().ConfigureAwait(false);

                                        // StatusError is defined here:
                                        // https://github.com/kubernetes/kubernetes/blob/068e1642f63a1a8c48c16c18510e8854a4f4e7c5/staging/src/k8s.io/apimachinery/pkg/api/errors/errors.go#L37
                                        var returnMessage = SafeJsonConvert.DeserializeObject <V1Status>(errors);
                                        return(GetExitCodeOrThrow(returnMessage));
                                    }
            }
            catch (HttpOperationException httpEx) when(httpEx.Body is V1Status)
            {
                throw new KubernetesException((V1Status)httpEx.Body);
            }
        }