pkg/kubeconfig/kubeconfig_writer.go (79 lines of code) (raw):

package kubeconfig import ( "bytes" "context" "io" "time" corev1 "k8s.io/api/core/v1" "github.com/aws/eks-anywhere/pkg/clients/kubernetes" "github.com/aws/eks-anywhere/pkg/clusterapi" "github.com/aws/eks-anywhere/pkg/constants" "github.com/aws/eks-anywhere/pkg/retrier" ) // ClientFactory builds Kubernetes clients. type ClientFactory interface { // BuildClientFromKubeconfig builds a Kubernetes client from a kubeconfig file. BuildClientFromKubeconfig(kubeconfigPath string) (kubernetes.Client, error) } // ClusterAPIKubeconfigSecretWriter reads the kubeconfig secret on a cluster and copies the contents to a writer. type ClusterAPIKubeconfigSecretWriter struct { client ClientFactory timeout time.Duration backoff time.Duration } // WriterOpt allows to configure [KubeconfigWriter]. type WriterOpt func(*ClusterAPIKubeconfigSecretWriter) // WithTimeout sets the optional timeout for a KubeconfigWriter. func WithTimeout(timeout time.Duration) WriterOpt { return func(writer *ClusterAPIKubeconfigSecretWriter) { writer.timeout = timeout } } // WithBackoff sets the optional backoff duration for a KubeconfigWriter. func WithBackoff(backoff time.Duration) WriterOpt { return func(writer *ClusterAPIKubeconfigSecretWriter) { writer.backoff = backoff } } // NewClusterAPIKubeconfigSecretWriter creates a ClusterAPIKubeconfigSecretWriter. func NewClusterAPIKubeconfigSecretWriter(unauthClient ClientFactory, opts ...WriterOpt) ClusterAPIKubeconfigSecretWriter { kr := &ClusterAPIKubeconfigSecretWriter{ client: unauthClient, timeout: time.Minute, backoff: time.Second, } for _, o := range opts { o(kr) } return *kr } // WriteKubeconfig retrieves the contents of the specified cluster's kubeconfig from a secret and copies it to an io.Writer. func (kr ClusterAPIKubeconfigSecretWriter) WriteKubeconfig(ctx context.Context, clusterName, kubeconfigPath string, w io.Writer) error { rawKubeconfig, err := kr.GetClusterKubeconfig(ctx, clusterName, kubeconfigPath) if err != nil { return err } if err := kr.WriteKubeconfigContent(ctx, clusterName, rawKubeconfig, w); err != nil { return err } return nil } // WriteKubeconfigContent copies a raw kubeconfig to an io.Writer. func (kr ClusterAPIKubeconfigSecretWriter) WriteKubeconfigContent(ctx context.Context, clusterName string, content []byte, w io.Writer) error { if _, err := io.Copy(w, bytes.NewReader(content)); err != nil { return err } return nil } // GetClusterKubeconfig gets the cluster's kubeconfig from the secret. func (kr ClusterAPIKubeconfigSecretWriter) GetClusterKubeconfig(ctx context.Context, clusterName, kubeconfigPath string) ([]byte, error) { kubeconfigSecret := &corev1.Secret{} var kubeClient kubernetes.Client kubeClient, err := kr.client.BuildClientFromKubeconfig(kubeconfigPath) if err != nil { return nil, err } err = retrier.New( kr.timeout, retrier.WithRetryPolicy(retrier.BackOffPolicy(kr.backoff)), ).Retry(func() error { if err = kubeClient.Get(ctx, clusterapi.ClusterKubeconfigSecretName(clusterName), constants.EksaSystemNamespace, kubeconfigSecret); err != nil { return err } return nil }) if err != nil { return nil, err } return kubeconfigSecret.Data["value"], nil }