Beispiel #1
0
 /// <summary>
 /// Tries to get the full path to a file referenced from the Kubernetes configuration.
 /// </summary>
 /// <param name="configuration">
 /// The Kubernetes configuration.
 /// </param>
 /// <param name="path">
 /// The path to resolve.
 /// </param>
 /// <returns>
 /// When possible a fully qualified path to the file.
 /// </returns>
 /// <remarks>
 /// For example, if the configuration file is at "C:\Users\me\kube.config" and path is "ca.crt",
 /// this will return "C:\Users\me\ca.crt". Similarly, if path is "D:\ca.cart", this will return
 /// "D:\ca.crt".
 /// </remarks>
 private static string GetFullPath(IK8SConfiguration configuration, string path)
 {
     // If we don't have a file name,
     if (string.IsNullOrWhiteSpace(configuration.FileName) || Path.IsPathRooted(path))
     {
         return(path);
     }
     else
     {
         return(Path.Combine(Path.GetDirectoryName(configuration.FileName), path));
     }
 }
Beispiel #2
0
        private void SetClusterDetails(IK8SConfiguration k8SConfig, Context activeContext)
        {
            var clusterDetails =
                k8SConfig.Clusters.FirstOrDefault(c => c.Name.Equals(activeContext.ContextDetails.Cluster,
                                                                     StringComparison.OrdinalIgnoreCase));

            if (clusterDetails?.ClusterEndpoint == null)
            {
                throw new KubeConfigException($"Cluster not found for context {activeContext} in kubeconfig");
            }

            if (string.IsNullOrWhiteSpace(clusterDetails.ClusterEndpoint.Server))
            {
                throw new KubeConfigException($"Server not found for current-context {activeContext} in kubeconfig");
            }
            Host = clusterDetails.ClusterEndpoint.Server;

            SkipTlsVerify = clusterDetails.ClusterEndpoint.SkipTlsVerify;

            try
            {
                var uri = new Uri(Host);
                if (uri.Scheme == "https")
                {
                    // check certificate for https
                    if (!clusterDetails.ClusterEndpoint.SkipTlsVerify &&
                        string.IsNullOrWhiteSpace(clusterDetails.ClusterEndpoint.CertificateAuthorityData) &&
                        string.IsNullOrWhiteSpace(clusterDetails.ClusterEndpoint.CertificateAuthority))
                    {
                        throw new KubeConfigException(
                                  $"neither certificate-authority-data nor certificate-authority not found for current-context :{activeContext} in kubeconfig");
                    }

                    if (!string.IsNullOrEmpty(clusterDetails.ClusterEndpoint.CertificateAuthorityData))
                    {
                        var data = clusterDetails.ClusterEndpoint.CertificateAuthorityData;
                        SslCaCert = new X509Certificate2(Convert.FromBase64String(data));
                    }
                    else if (!string.IsNullOrEmpty(clusterDetails.ClusterEndpoint.CertificateAuthority))
                    {
                        SslCaCert = new X509Certificate2(GetFullPath(k8SConfig, clusterDetails.ClusterEndpoint.CertificateAuthority));
                    }
                }
            }
            catch (UriFormatException e)
            {
                throw new KubeConfigException("Bad Server host url", e);
            }
        }
Beispiel #3
0
        /// <summary>
        ///     Validates and Intializes Client Configuration
        /// </summary>
        /// <param name="k8SConfig">Kubernetes Configuration</param>
        /// <param name="currentContext">Current Context</param>
        private void InitializeContext(IK8SConfiguration k8SConfig, string currentContext)
        {
            // current context
            var activeContext =
                k8SConfig.Contexts.FirstOrDefault(
                    c => c.Name.Equals(currentContext, StringComparison.OrdinalIgnoreCase));

            if (activeContext == null)
            {
                throw new KubeConfigException($"CurrentContext: {currentContext} not found in contexts in kubeconfig");
            }

            CurrentContext = activeContext.Name;

            // cluster
            SetClusterDetails(k8SConfig, activeContext);

            // user
            SetUserDetails(k8SConfig, activeContext);

            // namespace
            Namespace = activeContext.Namespace;
        }
        /// <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);
        }
Beispiel #5
0
 /// <summary>
 /// Initializes a new instance of <see cref="KubernetesClientConfiguration"/> from pre-loaded config object.
 /// </summary>
 /// <param name="k8sConfig">A <see cref="K8SConfiguration"/>, for example loaded from <see cref="LoadKubeConfigAsync(string, bool)" /></param>
 /// <param name="currentContext">Override the current context in config, set null if do not want to override</param>
 /// <param name="masterUrl">Override the Kubernetes API server endpoint, set null if do not want to override</param>
 public static KubernetesClientConfiguration BuildConfigFromConfigObject(IK8SConfiguration k8SConfig, string currentContext = null, string masterUrl = null)
 => GetKubernetesClientConfiguration(currentContext, masterUrl, k8SConfig);
Beispiel #6
0
        private void SetUserDetails(IK8SConfiguration k8SConfig, Context activeContext)
        {
            if (string.IsNullOrWhiteSpace(activeContext.ContextDetails.User))
            {
                return;
            }

            var userDetails = k8SConfig.Users.FirstOrDefault(c => c.Name.Equals(activeContext.ContextDetails.User,
                                                                                StringComparison.OrdinalIgnoreCase));

            if (userDetails == null)
            {
                throw new KubeConfigException("User not found for context {activeContext.Name} in kubeconfig");
            }

            if (userDetails.UserCredentials == null)
            {
                throw new KubeConfigException($"User credentials not found for user: {userDetails.Name} in kubeconfig");
            }

            var userCredentialsFound = false;

            // Basic and bearer tokens are mutually exclusive
            if (!string.IsNullOrWhiteSpace(userDetails.UserCredentials.Token))
            {
                AccessToken          = userDetails.UserCredentials.Token;
                userCredentialsFound = true;
            }
            else if (!string.IsNullOrWhiteSpace(userDetails.UserCredentials.UserName) &&
                     !string.IsNullOrWhiteSpace(userDetails.UserCredentials.Password))
            {
                Username             = userDetails.UserCredentials.UserName;
                Password             = userDetails.UserCredentials.Password;
                userCredentialsFound = true;
            }

            // Token and cert based auth can co-exist
            if (!string.IsNullOrWhiteSpace(userDetails.UserCredentials.ClientCertificateData) &&
                !string.IsNullOrWhiteSpace(userDetails.UserCredentials.ClientKeyData))
            {
                ClientCertificateData    = userDetails.UserCredentials.ClientCertificateData;
                ClientCertificateKeyData = userDetails.UserCredentials.ClientKeyData;
                userCredentialsFound     = true;
            }

            if (!string.IsNullOrWhiteSpace(userDetails.UserCredentials.ClientCertificate) &&
                !string.IsNullOrWhiteSpace(userDetails.UserCredentials.ClientKey))
            {
                ClientCertificateFilePath = GetFullPath(k8SConfig, userDetails.UserCredentials.ClientCertificate);
                ClientKeyFilePath         = GetFullPath(k8SConfig, userDetails.UserCredentials.ClientKey);
                userCredentialsFound      = true;
            }

            if (userDetails.UserCredentials.AuthProvider != null)
            {
                if (userDetails.UserCredentials.AuthProvider.Name == "azure" &&
                    userDetails.UserCredentials.AuthProvider.Config != null &&
                    userDetails.UserCredentials.AuthProvider.Config.ContainsKey("access-token"))
                {
                    var config = userDetails.UserCredentials.AuthProvider.Config;
                    if (config.ContainsKey("expires-on"))
                    {
                        var            expiresOn = Int32.Parse(config["expires-on"]);
                        DateTimeOffset expires;
#if NET452
                        var epoch = new DateTimeOffset(1970, 1, 1, 0, 0, 0, TimeSpan.Zero);
                        expires = epoch.AddSeconds(expiresOn);
#else
                        expires = DateTimeOffset.FromUnixTimeSeconds(expiresOn);
#endif

                        if (DateTimeOffset.Compare(expires, DateTimeOffset.Now) <= 0)
                        {
                            var tenantId    = config["tenant-id"];
                            var clientId    = config["client-id"];
                            var apiServerId = config["apiserver-id"];
                            var refresh     = config["refresh-token"];
                            var newToken    = RenewAzureToken(tenantId, clientId, apiServerId, refresh);
                            config["access-token"] = newToken;
                        }
                    }
                    AccessToken          = config["access-token"];
                    userCredentialsFound = true;
                }
            }

            if (!userCredentialsFound)
            {
                throw new KubeConfigException(
                          $"User: {userDetails.Name} does not have appropriate auth credentials in kubeconfig");
            }
        }
Beispiel #7
0
        private static KubernetesClientConfiguration GetKubernetesClientConfiguration(string currentContext, string masterUrl, IK8SConfiguration 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);
        }