Пример #1
0
        /// <summary>
        /// Determines the process' exit code based on a <see cref="V1Status"/> message.
        ///
        /// This will:
        /// - return 0 if the process completed successfully
        /// - return the exit code if the process completed with a non-zero exit code
        /// - throw a <see cref="KubernetesException"/> in all other cases.
        /// </summary>
        /// <param name="status">
        /// A <see cref="V1Status"/> object.
        /// </param>
        /// <returns>
        /// The process exit code.
        /// </returns>
        public static int GetExitCodeOrThrow(V1Status status)
        {
            if (status == null)
            {
                throw new ArgumentNullException(nameof(status));
            }

            if (status.Status == "Success")
            {
                return(0);
            }
            else if (status.Status == "Failure" && status.Reason == "NonZeroExitCode")
            {
                var exitCodeString = status.Details.Causes.FirstOrDefault(c => c.Reason == "ExitCode")?.Message;

                if (int.TryParse(exitCodeString, out int exitCode))
                {
                    return(exitCode);
                }
                else
                {
                    throw new KubernetesException(status);
                }
            }
            else
            {
                throw new KubernetesException(status);
            }
        }
Пример #2
0
        public void GetExitCodeOrThrow_InvalidExitCode()
        {
            var status = 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 = "abc"
                        }
                    }
                }
            };

            var ex = Assert.Throws <KubernetesException>(() => Kubernetes.GetExitCodeOrThrow(status));

            Assert.Equal(status, ex.Status);
        }
Пример #3
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);
            }
        }
Пример #4
0
        public void GetExitCodeOrThrowOtherError()
        {
            var status = new V1Status() { Metadata = null, Status = "Failure", Reason = "SomethingElse" };

            var ex = Assert.Throws<KubernetesException>(() => Kubernetes.GetExitCodeOrThrow(status));
            Assert.Equal(status, ex.Status);
        }
Пример #5
0
        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);
                            }
                        }
        }
Пример #6
0
        public void GetExitCodeOrThrowSuccess()
        {
            var status = new V1Status()
            {
                Metadata = null, Status = "Success",
            };

            Assert.Equal(0, Kubernetes.GetExitCodeOrThrow(status));
        }
        public async Task StatusAsync_successfully_returns_a_status()
        {
            LatestStatusEndpoints internalLatestStatus = new LatestStatusEndpoints(string.Empty, true);

            V1Status response = await internalLatestStatus.StatusAsync();

            Assert.Equal(12345, response.Players);
            Assert.Equal("1132976", response.ServerVersion);
            Assert.Equal(new DateTime(2017, 01, 02, 12, 34, 56), response.StartTime);
        }
Пример #8
0
        public void TestV1Status()
        {
            var s = new V1Status()
            {
                Status = "Success"
            };

            Assert.Equal("Success", s.ToString());

            s = new V1Status()
            {
                Status = "Failure"
            };
            Assert.Equal("Failure", s.ToString());

            s = new V1Status()
            {
                Status = "Failure", Reason = "BombExploded"
            };
            Assert.Equal("BombExploded", s.ToString());

            s = new V1Status()
            {
                Status = "Failure", Message = "Something bad happened."
            };
            Assert.Equal("Something bad happened.", s.ToString());

            s = new V1Status()
            {
                Status = "Failure", Code = 400
            };
            Assert.Equal("BadRequest", s.ToString());

            s = new V1Status()
            {
                Status = "Failure", Code = 911
            };
            Assert.Equal("911", s.ToString());

            s = new V1Status()
            {
                Status = "Failure", Code = 400, Message = "It's all messed up."
            };
            Assert.Equal("BadRequest - It's all messed up.", s.ToString());

            s = new V1Status()
            {
                Status  = "Failure",
                Code    = 400,
                Reason  = "IllegalValue",
                Message = "You're breaking the LAW!",
            };
            Assert.Equal("IllegalValue - You're breaking the LAW!", s.ToString());
        }
Пример #9
0
        public async Task StatusAsync_successfully_returns_a_status()
        {
            Mock <IWebClient> mockedWebClient = new Mock <IWebClient>();

            string json = "{\r\n  \"players\": 12345,\r\n  \"server_version\": \"1132976\",\r\n  \"start_time\": \"2017-01-02T12:34:56Z\"\r\n}";

            mockedWebClient.Setup(x => x.GetAsync(It.IsAny <WebHeaderCollection>(), It.IsAny <string>(), It.IsAny <int>())).ReturnsAsync(new EsiModel {
                Model = json
            });

            InternalLatestStatus internalLatestStatus = new InternalLatestStatus(mockedWebClient.Object, string.Empty);

            V1Status response = await internalLatestStatus.StatusAsync();

            Assert.Equal(12345, response.Players);
            Assert.Equal("1132976", response.ServerVersion);
            Assert.Equal(new DateTime(2017, 01, 02, 12, 34, 56), response.StartTime);
        }
Пример #10
0
        public void ReturnStatus()
        {
            var v1Status = new V1Status {
                Message = "test message", Status = "test status"
            };

            using (var server = new MockKubeApiServer(testOutput, resp: JsonConvert.SerializeObject(v1Status)))
            {
                var client = new Kubernetes(new KubernetesClientConfiguration {
                    Host = server.Uri.ToString()
                });

                var status = client.DeleteNamespace("test", new V1DeleteOptions());

                Assert.False(status.HasObject);
                Assert.Equal(v1Status.Message, status.Message);
                Assert.Equal(v1Status.Status, status.Status);
            }
        }
Пример #11
0
        public void GetExitCodeOrThrowNonZeroExitCode()
        {
            var status = 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" },
                    },
                },
            };

            Assert.Equal(1, Kubernetes.GetExitCodeOrThrow(status));
        }
Пример #12
0
        internal void DeleteServicePod(string podName)
        {
            using (Stream stream = KubeConfigStream)
            {
                var config = KubernetesClientConfiguration.BuildConfigFromConfigFile(stream);

                using (IKubernetes client = new Kubernetes(config))
                {
                    V1DeleteOptions options = new V1DeleteOptions()
                    {
                    };
                    IList <V1Pod>             podsList             = client.ListNamespacedPod(DefaultNamespace).Items;
                    IList <V1beta1ReplicaSet> replicaSetsList      = client.ListNamespacedReplicaSet2(DefaultNamespace).Items;
                    List <string>             replicaSetDeleteList = new List <string>();
                    List <string>             podsDeleteList       = new List <string>();
                    List <string>             pvcDeleteList        = new List <string>();
                    V1Pod pod = null;

                    foreach (V1Pod podItem in podsList)
                    {
                        string containerName = podItem.Spec.Containers[0].Name;
                        if (containerName == podName)
                        {
                            var volumes = podItem.Spec.Volumes;
                            foreach (var replicaSet in replicaSetsList)
                            {
                                if (replicaSet.Spec.Selector.MatchLabels["app"] == podName)
                                {
                                    replicaSetDeleteList.Add(replicaSet.Metadata.Name);
                                }
                            }
                            foreach (var volume in volumes)
                            {
                                if (volume.PersistentVolumeClaim != null)
                                {
                                    pvcDeleteList.Add(volume.PersistentVolumeClaim.ClaimName);
                                }
                            }
                            podsDeleteList.Add(podItem.Metadata.Name);
                        }
                    }

                    try
                    {
                        V1Status status = client.DeleteNamespacedDeployment1(options, podName, DefaultNamespace);
                    }
                    catch (HttpOperationException e)
                    {
                    }

                    foreach (string replicaSetName in replicaSetDeleteList)
                    {
                        try
                        {
                            client.DeleteNamespacedReplicaSet2(options, replicaSetName, DefaultNamespace);
                        } catch (HttpOperationException e)
                        {
                        }
                    }
                    foreach (string podNameToDelete in podsDeleteList)
                    {
                        try
                        {
                            client.DeleteNamespacedPod(options, podNameToDelete, DefaultNamespace);
                        }
                        catch (HttpOperationException e)
                        {
                        }
                    }

                    foreach (string pvcName in pvcDeleteList)
                    {
                        try
                        {
                            client.DeleteNamespacedPersistentVolumeClaim(options, pvcName, DefaultNamespace);
                        }
                        catch (HttpOperationException e)
                        {
                        }
                    }

                    try
                    {
                        client.DeleteNamespacedService(options, $"{podName}-lb", DefaultNamespace);
                    }
                    catch (HttpOperationException e)
                    {
                    }


                    options = null;
                }
            }
        }
Пример #13
0
 public KubernetesApiResponse(V1Status status, HttpStatusCode httpStatusCode)
 {
     Object         = default(TDataType);
     Status         = status;
     HttpStatusCode = httpStatusCode;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="KubernetesException"/> class using
 /// the data from a <see cref="V1Status"/> object and a reference to the inner exception
 /// that is the cause of this exception..
 /// </summary>
 /// <param name="status">
 /// A status message which triggered this exception to be thrown.
 /// </param>
 /// <param name="innerException">
 /// The exception that is the cause of the current exception, or <see langword="null"/>
 /// if no inner exception is specified.
 /// </param>
 public KubernetesException(V1Status status, Exception innerException)
     : this(status?.Message, innerException)
 {
     Status = status;
 }
Пример #15
0
 public void Handle(int code, V1Status errorStatus)
 {
     throw new HttpListenerException(code, errorStatus?.Message);
 }
Пример #16
0
        protected async Task <WebSocket> StreamConnectAsync(Uri uri, string invocationId = null, string webSocketSubProtocol = null, Dictionary <string, List <string> > customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
        {
            bool _shouldTrace = ServiceClientTracing.IsEnabled;

            // Create WebSocket transport objects
            WebSocketBuilder webSocketBuilder = this.CreateWebSocketBuilder();

            // Set Headers
            if (customHeaders != null)
            {
                foreach (var _header in customHeaders)
                {
                    webSocketBuilder.SetRequestHeader(_header.Key, string.Join(" ", _header.Value));
                }
            }

            // Set Credentials
#if NET452
            foreach (var cert in ((WebRequestHandler)this.HttpClientHandler).ClientCertificates.OfType <X509Certificate2>())
#else
            foreach (var cert in this.HttpClientHandler.ClientCertificates.OfType <X509Certificate2>())
#endif
            {
                webSocketBuilder.AddClientCertificate(cert);
            }

            if (this.Credentials != null)
            {
                // Copy the default (credential-related) request headers from the HttpClient to the WebSocket
                HttpRequestMessage message = new HttpRequestMessage();
                await this.Credentials.ProcessHttpRequestAsync(message, cancellationToken).ConfigureAwait(false);

                foreach (var _header in message.Headers)
                {
                    webSocketBuilder.SetRequestHeader(_header.Key, string.Join(" ", _header.Value));
                }
            }

#if (NET452 || NETSTANDARD2_0)
            if (this.CaCerts != null)
            {
                webSocketBuilder.SetServerCertificateValidationCallback(this.ServerCertificateValidationCallback);
            }
#endif

#if NETCOREAPP2_1
            if (this.CaCerts != null)
            {
                webSocketBuilder.ExpectServerCertificate(this.CaCerts);
            }

            if (this.SkipTlsVerify)
            {
                webSocketBuilder.SkipServerCertificateValidation();
            }

            if (webSocketSubProtocol != null)
            {
                webSocketBuilder.Options.AddSubProtocol(webSocketSubProtocol);
            }
#endif // NETCOREAPP2_1

            // Send Request
            cancellationToken.ThrowIfCancellationRequested();

            WebSocket webSocket = null;
            try
            {
                webSocket = await webSocketBuilder.BuildAndConnectAsync(uri, CancellationToken.None).ConfigureAwait(false);
            }
            catch (WebSocketException wse) when(wse.WebSocketErrorCode == WebSocketError.HeaderError || (wse.InnerException is WebSocketException && ((WebSocketException)wse.InnerException).WebSocketErrorCode == WebSocketError.HeaderError))
            {
                // This usually indicates the server sent an error message, like 400 Bad Request. Unfortunately, the WebSocket client
                // class doesn't give us a lot of information about what went wrong. So, retry the connection.
                var uriBuilder = new UriBuilder(uri);

                uriBuilder.Scheme = uri.Scheme == "wss" ? "https" : "http";

                var response = await this.HttpClient.GetAsync(uriBuilder.Uri, cancellationToken).ConfigureAwait(false);

                if (response.StatusCode == HttpStatusCode.SwitchingProtocols)
                {
                    // This should never happen - the server just allowed us to switch to WebSockets but the previous call didn't work.
                    // Rethrow the original exception
                    response.Dispose();
                    throw;
                }
                else
                {
                    var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                    // Try to parse the content as a V1Status object
                    var      genericObject = SafeJsonConvert.DeserializeObject <KubernetesObject>(content);
                    V1Status status        = null;

                    if (genericObject.ApiVersion == "v1" && genericObject.Kind == "Status")
                    {
                        status = SafeJsonConvert.DeserializeObject <V1Status>(content);
                    }

                    var ex = new HttpOperationException($"The operation returned an invalid status code: {response.StatusCode}", wse)
                    {
                        Response = new HttpResponseMessageWrapper(response, content),
                        Body     = status != null ? (object)status : content,
                    };

                    response.Dispose();

                    throw ex;
                }
            }
            catch (Exception ex)
            {
                if (_shouldTrace)
                {
                    ServiceClientTracing.Error(invocationId, ex);
                }

                throw;
            }
            finally
            {
                if (_shouldTrace)
                {
                    ServiceClientTracing.Exit(invocationId, null);
                }

#if (NET452 || NETSTANDARD2_0)
                if (this.CaCerts != null)
                {
                    webSocketBuilder.CleanupServerCertificateValidationCallback(this.ServerCertificateValidationCallback);
                }
#endif
            }
            return(webSocket);
        }
Пример #17
0
 /// <summary>
 /// Initializes a ne winstance of the <see cref="KubernetesException"/> class using
 /// the data from a <see cref="V1Status"/> object.
 /// </summary>
 /// <param name="status">
 /// A status message which triggered this exception to be thrown.
 /// </param>
 public KubernetesException(V1Status status)
     : this(status?.Message)
 {
     this.Status = status;
 }
Пример #18
0
 public ReconcilerException(V1Status status)
     : base((status ?? throw new ArgumentNullException(nameof(status))).Message)