Ejemplo n.º 1
0
        private static void AKSAdministration()
        {
            var configuration = new k8s.KubernetesClientConfiguration
            {
                Host        = "https://ari-aks-22-demo-f681ed-b4579bd4.hcp.southeastasia.azmk8s.io:443",
                AccessToken = ReadAccessToken()
            };

            configuration.SkipTlsVerify = true;
            var client = new k8s.Kubernetes(configuration);

            var namespaces = client.ListNamespace();

            foreach (var ns in namespaces.Items)
            {
                Console.WriteLine(ns.Metadata.Name);
            }
            // ## Uncomment below lines to test creation of namespace
            //client.CreateNamespace(new k8s.Models.V1Namespace {
            // Metadata= new k8s.Models.V1ObjectMeta
            // {
            //     Name= "automation"
            // }
            //});
        }
Ejemplo n.º 2
0
 /// <summary>Creates <see cref="ServiceClientCredentials"/> based on the given config, or returns null if no such credentials are
 /// needed.
 /// </summary>
 public static ServiceClientCredentials CreateCredentials(KubernetesClientConfiguration config)
 {
     if (config == null)
     {
         throw new ArgumentNullException(nameof(config));
     }
     if (!string.IsNullOrEmpty(config.AccessToken))
     {
         return(new TokenCredentials(config.AccessToken));
     }
     else if (!string.IsNullOrEmpty(config.Username))
     {
         return(new BasicAuthenticationCredentials()
         {
             UserName = config.Username, Password = config.Password
         });
     }
     return(null);
 }
Ejemplo n.º 3
0
        private void ValidateConfig(KubernetesClientConfiguration config)
        {
            if (config == null)
            {
                throw new KubeConfigException("KubeConfig must be provided");
            }

            if (string.IsNullOrWhiteSpace(config.Host))
            {
                throw new KubeConfigException("Host url must be set");
            }

            try
            {
                BaseUri = new Uri(config.Host);
            }
            catch (UriFormatException e)
            {
                throw new KubeConfigException("Bad host url", e);
            }
        }
        /// <summary>
        ///     Initializes a new instance of the <see cref="KubernetesClientConfiguration" /> from config file
        /// </summary>
        public static KubernetesClientConfiguration BuildDefaultConfig()
        {
            var kubeconfig = Environment.GetEnvironmentVariable("KUBECONFIG");

            if (kubeconfig != null)
            {
                return(BuildConfigFromConfigFile(kubeconfigPath: kubeconfig));
            }
            if (File.Exists(KubeConfigDefaultLocation))
            {
                return(BuildConfigFromConfigFile(kubeconfigPath: KubeConfigDefaultLocation));
            }
            if (IsInCluster())
            {
                return(InClusterConfig());
            }
            var config = new KubernetesClientConfiguration();

            config.Host = "http://localhost:8080";
            return(config);
        }
Ejemplo n.º 5
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="Kubernetes" /> class.
        /// </summary>
        /// <param name='config'>
        ///     Optional. The delegating handlers to add to the http client pipeline.
        /// </param>
        /// <param name="handlers">
        ///     Optional. The delegating handlers to add to the http client pipeline.
        /// </param>
        public Kubernetes(KubernetesClientConfiguration config, params DelegatingHandler[] handlers) : this(handlers)
        {
            if (string.IsNullOrWhiteSpace(config.Host))
            {
                throw new KubeConfigException("Host url must be set");
            }

            try
            {
                BaseUri = new Uri(config.Host);
            }
            catch (UriFormatException e)
            {
                throw new KubeConfigException("Bad host url", e);
            }

            CaCert = config.SslCaCert;

            if (BaseUri.Scheme == "https")
            {
                if (config.SkipTlsVerify)
                {
                    HttpClientHandler.ServerCertificateCustomValidationCallback =
                        (sender, certificate, chain, sslPolicyErrors) => true;
                }
                else
                {
                    if (CaCert == null)
                    {
                        throw new KubeConfigException("a CA must be set when SkipTlsVerify === false");
                    }

                    HttpClientHandler.ServerCertificateCustomValidationCallback = CertificateValidationCallBack;
                }
            }

            // set credentails for the kubernernet client
            SetCredentials(config, HttpClientHandler);
        }
Ejemplo n.º 6
0
        private static KubernetesClientConfiguration GetKubernetesClientConfiguration(string currentContext, string masterUrl, K8SConfiguration k8SConfig)
        {
            var k8SConfiguration = new KubernetesClientConfiguration();

            currentContext = currentContext ?? k8SConfig.CurrentContext;
            // only init context if context if set
            if (currentContext != null)
            {
                k8SConfiguration.InitializeContext(k8SConfig, currentContext);
            }
            if (!string.IsNullOrWhiteSpace(masterUrl))
            {
                k8SConfiguration.Host = masterUrl;
            }

            if (string.IsNullOrWhiteSpace(k8SConfiguration.Host))
            {
                throw new KubeConfigException("Cannot infer server host url either from context or masterUrl");
            }

            return(k8SConfiguration);
        }
        public static KubernetesClientConfiguration InClusterConfig()
        {
            if (!IsInCluster())
            {
                throw new KubeConfigException(
                          "unable to load in-cluster configuration, KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined");
            }

            var rootCAFile = Path.Combine(ServiceAccountPath, ServiceAccountRootCAKeyFileName);
            var host       = Environment.GetEnvironmentVariable("KUBERNETES_SERVICE_HOST");
            var port       = Environment.GetEnvironmentVariable("KUBERNETES_SERVICE_PORT");

            if (string.IsNullOrEmpty(host))
            {
                host = "kubernetes.default.svc";
            }

            if (string.IsNullOrEmpty(port))
            {
                port = "443";
            }

            var result = new KubernetesClientConfiguration
            {
                Host          = new UriBuilder("https", host, Convert.ToInt32(port)).ToString(),
                TokenProvider = new TokenFileAuth(Path.Combine(ServiceAccountPath, ServiceAccountTokenKeyFileName)),
                SslCaCerts    = CertUtils.LoadPemFileCert(rootCAFile),
            };

            var namespaceFile = Path.Combine(ServiceAccountPath, ServiceAccountNamespaceFileName);

            if (FileUtils.FileSystem().File.Exists(namespaceFile))
            {
                result.Namespace = FileUtils.FileSystem().File.ReadAllText(namespaceFile);
            }

            return(result);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Generates pfx from client configuration
        /// </summary>
        /// <param name="config">Kubernetes Client Configuration</param>
        /// <returns>Generated Pfx Path</returns>
        public static X509Certificate2 GeneratePfx(KubernetesClientConfiguration config)
        {
            byte[] keyData  = null;
            byte[] certData = null;

            if (!string.IsNullOrWhiteSpace(config.ClientCertificateKeyData))
            {
                keyData = Convert.FromBase64String(config.ClientCertificateKeyData);
            }
            if (!string.IsNullOrWhiteSpace(config.ClientKeyFilePath))
            {
                keyData = File.ReadAllBytes(config.ClientKeyFilePath);
            }

            if (keyData == null)
            {
                throw new KubeConfigException("keyData is empty");
            }

            if (!string.IsNullOrWhiteSpace(config.ClientCertificateData))
            {
                certData = Convert.FromBase64String(config.ClientCertificateData);
            }
            if (!string.IsNullOrWhiteSpace(config.ClientCertificateFilePath))
            {
                certData = File.ReadAllBytes(config.ClientCertificateFilePath);
            }

            if (certData == null)
            {
                throw new KubeConfigException("certData is empty");
            }

            var cert = new X509CertificateParser().ReadCertificate(new MemoryStream(certData));

            // key usage is a bit string, zero-th bit is 'digitalSignature'
            // See https://www.alvestrand.no/objectid/2.5.29.15.html for more details.
            if (cert != null && cert.GetKeyUsage() != null && !cert.GetKeyUsage()[0])
            {
                throw new Exception(
                          "Client certificates must be marked for digital signing. " +
                          "See https://github.com/kubernetes-client/csharp/issues/319");
            }
            object obj;

            using (var reader = new StreamReader(new MemoryStream(keyData)))
            {
                obj = new PemReader(reader).ReadObject();
                var key = obj as AsymmetricCipherKeyPair;
                if (key != null)
                {
                    var cipherKey = key;
                    obj = cipherKey.Private;
                }
            }

            var keyParams = (AsymmetricKeyParameter)obj;

            var store = new Pkcs12StoreBuilder().Build();

            store.SetKeyEntry("K8SKEY", new AsymmetricKeyEntry(keyParams), new[] { new X509CertificateEntry(cert) });

            using (var pkcs = new MemoryStream())
            {
                store.Save(pkcs, new char[0], new SecureRandom());

                if (config.ClientCertificateKeyStoreFlags.HasValue)
                {
                    return(new X509Certificate2(pkcs.ToArray(), "", config.ClientCertificateKeyStoreFlags.Value));
                }
                else
                {
                    return(new X509Certificate2(pkcs.ToArray()));
                }
            }
        }
Ejemplo n.º 9
0
        private void InitializeFromConfig(KubernetesClientConfiguration config)
        {
            if (BaseUri.Scheme == "https")
            {
                if (config.SkipTlsVerify)
                {
#if NET452
                    ((WebRequestHandler)HttpClientHandler).ServerCertificateValidationCallback =
                        (sender, certificate, chain, sslPolicyErrors) => true;
#elif XAMARINIOS1_0 || MONOANDROID8_1
                    System.Net.ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) =>
                    {
                        return(true);
                    };
#else
                    HttpClientHandler.ServerCertificateCustomValidationCallback =
                        (sender, certificate, chain, sslPolicyErrors) => true;
#endif
                }
                else
                {
                    if (CaCerts == null)
                    {
                        throw new KubeConfigException("A CA must be set when SkipTlsVerify === false");
                    }
#if NET452
                    ((WebRequestHandler)HttpClientHandler).ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
                    {
                        return(Kubernetes.CertificateValidationCallBack(sender, CaCerts, certificate, chain, sslPolicyErrors));
                    };
#elif XAMARINIOS1_0
                    System.Net.ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) =>
                    {
                        var cert = new X509Certificate2(certificate);
                        return(Kubernetes.CertificateValidationCallBack(sender, CaCerts, cert, chain, sslPolicyErrors));
                    };
#elif MONOANDROID8_1
                    var certList = new System.Collections.Generic.List <Java.Security.Cert.Certificate>();

                    foreach (X509Certificate2 caCert in CaCerts)
                    {
                        using (var certStream = new System.IO.MemoryStream(caCert.RawData))
                        {
                            Java.Security.Cert.Certificate cert = Java.Security.Cert.CertificateFactory.GetInstance("X509").GenerateCertificate(certStream);

                            certList.Add(cert);
                        }
                    }

                    var handler = (Xamarin.Android.Net.AndroidClientHandler) this.HttpClientHandler;

                    handler.TrustedCerts = certList;
#else
                    HttpClientHandler.ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
                    {
                        return(Kubernetes.CertificateValidationCallBack(sender, CaCerts, certificate, chain, sslPolicyErrors));
                    };
#endif
                }
            }

            // set credentails for the kubernetes client
            SetCredentials(config);
            config.AddCertificates(HttpClientHandler);
        }
Ejemplo n.º 10
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="Kubernetes" /> class.
 /// </summary>
 /// <param name='config'>
 ///     The kube config to use.
 /// </param>
 /// <param name="httpClient">
 ///     The <see cref="HttpClient" /> to use for all requests.
 /// </param>
 public Kubernetes(KubernetesClientConfiguration config, HttpClient httpClient) : this(config, httpClient, false)
 {
 }
Ejemplo n.º 11
0
 /// <summary>
 ///     Set credentials for the Client
 /// </summary>
 /// <param name="config">k8s client configuration</param>
 private void SetCredentials(KubernetesClientConfiguration config) => Credentials = CreateCredentials(config);
Ejemplo n.º 12
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="Kubernetes" /> class.
        /// </summary>
        /// <param name='config'>
        ///     The kube config to use.
        /// </param>
        /// <param name="handlers">
        ///     Optional. The delegating handlers to add to the http client pipeline.
        /// </param>
        public Kubernetes(KubernetesClientConfiguration config, params DelegatingHandler[] handlers)
#if MONOANDROID8_1
            : this(new Xamarin.Android.Net.AndroidClientHandler(), handlers)
#else
            : this(handlers)
Ejemplo n.º 13
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="Kubernetes" /> class.
        /// </summary>
        /// <param name='config'>
        ///     Optional. The delegating handlers to add to the http client pipeline.
        /// </param>
        /// <param name="handlers">
        ///     Optional. The delegating handlers to add to the http client pipeline.
        /// </param>
        public Kubernetes(KubernetesClientConfiguration config, params DelegatingHandler[] handlers) : this(handlers)
        {
            if (string.IsNullOrWhiteSpace(config.Host))
            {
                throw new KubeConfigException("Host url must be set");
            }

            try
            {
                BaseUri = new Uri(config.Host);
            }
            catch (UriFormatException e)
            {
                throw new KubeConfigException("Bad host url", e);
            }

            CaCert        = config.SslCaCert;
            SkipTlsVerify = config.SkipTlsVerify;

            if (BaseUri.Scheme == "https")
            {
                if (config.SkipTlsVerify)
                {
#if NET452
                    ((WebRequestHandler)HttpClientHandler).ServerCertificateValidationCallback =
                        (sender, certificate, chain, sslPolicyErrors) => true;
#elif XAMARINIOS1_0
                    System.Net.ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) =>
                    {
                        return(true);
                    };
#else
                    HttpClientHandler.ServerCertificateCustomValidationCallback =
                        (sender, certificate, chain, sslPolicyErrors) => true;
#endif
                }
                else
                {
                    if (CaCert == null)
                    {
                        throw new KubeConfigException("a CA must be set when SkipTlsVerify === false");
                    }

#if NET452
                    ((WebRequestHandler)HttpClientHandler).ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
                    {
                        return(Kubernetes.CertificateValidationCallBack(sender, CaCert, certificate, chain, sslPolicyErrors));
                    };
#elif XAMARINIOS1_0
                    System.Net.ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) =>
                    {
                        var cert = new X509Certificate2(certificate);
                        return(Kubernetes.CertificateValidationCallBack(sender, CaCert, cert, chain, sslPolicyErrors));
                    };
#else
                    HttpClientHandler.ServerCertificateCustomValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
                    {
                        return(Kubernetes.CertificateValidationCallBack(sender, CaCert, certificate, chain, sslPolicyErrors));
                    };
#endif
                }
            }

            // set credentails for the kubernernet client
            SetCredentials(config, HttpClientHandler);
        }
Ejemplo n.º 14
0
        // NOTE: this method replicates the logic that the base ServiceClient uses except that it doesn't insert the RetryDelegatingHandler
        // and it does insert the WatcherDelegatingHandler. we don't want the RetryDelegatingHandler because it has a very broad definition
        // of what requests have failed. it considers everything outside 2xx to be failed, including 1xx (e.g. 101 Switching Protocols) and
        // 3xx. in particular, this prevents upgraded connections and certain generic/custom requests from working.
        private void CreateHttpClient(DelegatingHandler[] handlers, KubernetesClientConfiguration config)
        {
            FirstMessageHandler = HttpClientHandler = CreateRootHandler();


#if NET5_0
            // https://github.com/kubernetes-client/csharp/issues/587
            // let user control if tcp keep alive until better fix
            if (config.TcpKeepAlive)
            {
                // https://github.com/kubernetes-client/csharp/issues/533
                // net5 only
                // this is a temp fix to attach SocketsHttpHandler to HttpClient in order to set SO_KEEPALIVE
                // https://tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/
                //
                // _underlyingHandler is not a public accessible field
                // src of net5 HttpClientHandler and _underlyingHandler field defined here
                // https://github.com/dotnet/runtime/blob/79ae74f5ca5c8a6fe3a48935e85bd7374959c570/src/libraries/System.Net.Http/src/System/Net/Http/HttpClientHandler.cs#L22
                //
                // Should remove after better solution

                var sh = new SocketsHttpHandler();
                sh.ConnectCallback = async(context, token) =>
                {
                    var socket = new Socket(SocketType.Stream, ProtocolType.Tcp)
                    {
                        NoDelay = true,
                    };

                    socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);

                    var host = context.DnsEndPoint.Host;

                    if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                    {
                        // https://github.com/dotnet/runtime/issues/24917
                        // GetHostAddresses will return {host} if host is an ip
                        var ips = Dns.GetHostAddresses(host);
                        if (ips.Length == 0)
                        {
                            throw new Exception($"{host} DNS lookup failed");
                        }

                        host = ips[new Random().Next(ips.Length)].ToString();
                    }

                    await socket.ConnectAsync(host, context.DnsEndPoint.Port, token).ConfigureAwait(false);

                    return(new NetworkStream(socket, ownsSocket: true));
                };


                // set HttpClientHandler's cert callback before replace _underlyingHandler
                // force HttpClientHandler use our callback
                InitializeFromConfig(config);

                var p = HttpClientHandler.GetType().GetField("_underlyingHandler", BindingFlags.NonPublic | BindingFlags.Instance);
                p.SetValue(HttpClientHandler, (sh));
            }
#endif

            if (handlers == null || handlers.Length == 0)
            {
                // ensure we have at least one DelegatingHandler so AppendDelegatingHandler will work
                FirstMessageHandler = new ForwardingHandler(HttpClientHandler);
            }
            else
            {
                for (int i = handlers.Length - 1; i >= 0; i--)
                {
                    DelegatingHandler handler = handlers[i];
                    while (handler.InnerHandler is DelegatingHandler d)
                    {
                        handler = d;
                    }

                    handler.InnerHandler = FirstMessageHandler;
                    FirstMessageHandler  = handlers[i];
                }
            }

            AppendDelegatingHandler <WatcherDelegatingHandler>();
            HttpClient = new HttpClient(FirstMessageHandler, false);
        }
Ejemplo n.º 15
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="Kubernetes" /> class.
        /// </summary>
        /// <param name='k8SConfiguration'>
        ///     The configuration file for connection to Kubernetes
        /// </param>
        public Kubernetes(IK8SConfiguration k8SConfiguration)
        {
            var config = KubernetesClientConfiguration.BuildConfigFromConfigObject(k8SConfiguration);

            InitKubernetes(config);
        }
Ejemplo n.º 16
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="Kubernetes" /> class.
 /// </summary>
 /// <param name='config'>
 ///    The configuration file for connecting to Kubernetes
 /// </param>
 /// <param name="handlers">
 ///     Optional. The delegating handlers to add to the http client pipeline.
 /// </param>
 public Kubernetes(KubernetesClientConfiguration config, params DelegatingHandler[] handlers) : this(handlers)
 {
     InitKubernetes(config);
 }
Ejemplo n.º 17
0
        /// <summary>
        /// Generates pfx from client configuration
        /// </summary>
        /// <param name="config">Kubernetes Client Configuration</param>
        /// <returns>Generated Pfx Path</returns>
        public static X509Certificate2 GeneratePfx(KubernetesClientConfiguration config)
        {
            byte[] keyData  = null;
            byte[] certData = null;

            if (!string.IsNullOrWhiteSpace(config.ClientCertificateKeyData))
            {
                keyData = Convert.FromBase64String(config.ClientCertificateKeyData);
            }
            if (!string.IsNullOrWhiteSpace(config.ClientKeyFilePath))
            {
                keyData = File.ReadAllBytes(config.ClientKeyFilePath);
            }

            if (keyData == null)
            {
                throw new KubeConfigException("keyData is empty");
            }

            if (!string.IsNullOrWhiteSpace(config.ClientCertificateData))
            {
                certData = Convert.FromBase64String(config.ClientCertificateData);
            }
            if (!string.IsNullOrWhiteSpace(config.ClientCertificateFilePath))
            {
                certData = File.ReadAllBytes(config.ClientCertificateFilePath);
            }

            if (certData == null)
            {
                throw new KubeConfigException("certData is empty");
            }

            var cert = new X509CertificateParser().ReadCertificate(new MemoryStream(certData));

            object obj;

            using (var reader = new StreamReader(new MemoryStream(keyData)))
            {
                obj = new PemReader(reader).ReadObject();
                var key = obj as AsymmetricCipherKeyPair;
                if (key != null)
                {
                    var cipherKey = key;
                    obj = cipherKey.Private;
                }
            }

            var rsaKeyParams = (RsaPrivateCrtKeyParameters)obj;

            var store = new Pkcs12StoreBuilder().Build();

            store.SetKeyEntry("K8SKEY", new AsymmetricKeyEntry(rsaKeyParams), new[] { new X509CertificateEntry(cert) });

            using (var pkcs = new MemoryStream())
            {
                store.Save(pkcs, new char[0], new SecureRandom());

                if (config.ClientCertificateKeyStoreFlags.HasValue)
                {
                    return(new X509Certificate2(pkcs.ToArray(), "", config.ClientCertificateKeyStoreFlags.Value));
                }
                else
                {
                    return(new X509Certificate2(pkcs.ToArray()));
                }
            }
        }
Ejemplo n.º 18
0
 public GenericClient(KubernetesClientConfiguration config, string group, string version, string plural)
     : this(new Kubernetes(config), group, version, plural)
 {
 }