-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Get kubeconfig secret instead of listing all secrets
- Loading branch information
Showing
7 changed files
with
285 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,80 @@ | ||
package providers | ||
|
||
import ( | ||
"fmt" | ||
|
||
corev1 "k8s.io/api/core/v1" | ||
"k8s.io/apimachinery/pkg/types" | ||
clusterv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" | ||
logf "sigs.k8s.io/controller-runtime/pkg/log" | ||
) | ||
|
||
var logger = logf.Log.WithName("capargo-providers") | ||
|
||
// controlPlaneRefKind | ||
type controlPlaneRefKind string | ||
|
||
const ( | ||
// kubeadmKind | ||
kubeadmKind controlPlaneRefKind = "KubeadmControlPlane" | ||
|
||
// awsManagedKind | ||
awsManagedKind controlPlaneRefKind = "AWSManagedControlPlane" | ||
|
||
// vclusterKind | ||
vclusterKind controlPlaneRefKind = "VCluster" | ||
) | ||
|
||
type provider interface { | ||
GetNamespacedName() types.NamespacedName | ||
IsKubeconfig(*corev1.Secret) bool | ||
} | ||
|
||
// isCapiKubeconfig determines whether the secret provided is a CAPI kubeconfig | ||
// from a given control plane controller. | ||
func IsCapiKubeconfig(secret *corev1.Secret, cluster *clusterv1beta1.Cluster) bool { | ||
switch cluster.Spec.ControlPlaneRef.Kind { | ||
case "KubeadmControlPlane": | ||
// getProvider returns the provider interface for a given CAPI cluster, | ||
func getProvider(cluster *clusterv1beta1.Cluster) (provider, error) { | ||
switch controlPlaneRefKind(cluster.Spec.ControlPlaneRef.Kind) { | ||
case kubeadmKind: | ||
var p provider = kubeadmControlPlane{ | ||
APIVersion: cluster.Spec.ControlPlaneRef.APIVersion, | ||
Name: cluster.Spec.ControlPlaneRef.Name, | ||
Namespace: cluster.Spec.ControlPlaneRef.Namespace, | ||
} | ||
return p.IsKubeconfig(secret) | ||
case "AWSManagedControlPlane": | ||
return p, nil | ||
case awsManagedKind: | ||
var p provider = awsManagedControlPlane{ | ||
APIVersion: cluster.Spec.ControlPlaneRef.APIVersion, | ||
Name: cluster.Spec.ControlPlaneRef.Name, | ||
Namespace: cluster.Spec.ControlPlaneRef.Namespace, | ||
} | ||
return p.IsKubeconfig(secret) | ||
case "VCluster": | ||
return p, nil | ||
case vclusterKind: | ||
var p provider = vCluster{ | ||
APIVersion: cluster.Spec.ControlPlaneRef.APIVersion, | ||
Name: cluster.Spec.ControlPlaneRef.Name, | ||
Namespace: cluster.Spec.ControlPlaneRef.Namespace, | ||
} | ||
return p.IsKubeconfig(secret) | ||
return p, nil | ||
default: | ||
logger.V(2).Info("ControlPlaneRef kind unsupported", "kind", cluster.Spec.ControlPlaneRef.Kind) | ||
return false | ||
return nil, fmt.Errorf("controlPlaneRef kind %s unsupported", cluster.Spec.ControlPlaneRef.Kind) | ||
} | ||
} | ||
|
||
// IsCapiKubeconfig determines whether the secret provided is a CAPI kubeconfig | ||
// from a given control plane controller. | ||
func IsCapiKubeconfig(secret *corev1.Secret, cluster *clusterv1beta1.Cluster) (bool, error) { | ||
p, err := getProvider(cluster) | ||
if err != nil { | ||
return false, err | ||
} | ||
return p.IsKubeconfig(secret), nil | ||
} | ||
|
||
// GetCapiKubeconfigNamespacedName retrieves the expected namespace and name | ||
// for a CAPI cluster's kubeconfig. | ||
func GetCapiKubeconfigNamespacedName(cluster *clusterv1beta1.Cluster) (types.NamespacedName, error) { | ||
p, err := getProvider(cluster) | ||
if err != nil { | ||
return types.NamespacedName{}, err | ||
} | ||
return p.GetNamespacedName(), nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
package providers | ||
|
||
import ( | ||
. "github.com/onsi/ginkgo/v2" | ||
. "github.com/onsi/gomega" | ||
|
||
"github.com/google/uuid" | ||
"k8s.io/apimachinery/pkg/types" | ||
|
||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
capiv1beta1 "sigs.k8s.io/cluster-api/api/v1beta1" | ||
) | ||
|
||
var _ = Describe("Provider functions", func() { | ||
Context("When a cluster has a kubeadm controlPlaneRef", func() { | ||
clusterName := "kubeadm-cluster" | ||
clusterNamespace := "kubeadm-cluster-namespace" | ||
cluster := capiv1beta1.Cluster{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: clusterName, | ||
Namespace: clusterNamespace, | ||
UID: types.UID(uuid.New().String()), | ||
}, | ||
Spec: capiv1beta1.ClusterSpec{ | ||
ControlPlaneRef: &corev1.ObjectReference{ | ||
APIVersion: "controlplane.cluster.x-k8s.io/v1beta1", | ||
Kind: "KubeadmControlPlane", | ||
Name: clusterName, | ||
Namespace: clusterNamespace, | ||
}, | ||
}, | ||
} | ||
|
||
var kubeconfig = corev1.Secret{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: clusterName + "-kubeconfig", | ||
Namespace: clusterNamespace, | ||
OwnerReferences: []metav1.OwnerReference{ | ||
{ | ||
APIVersion: "controlplane.cluster.x-k8s.io/v1beta1", | ||
BlockOwnerDeletion: func(v bool) *bool { return &v }(true), | ||
Controller: func(v bool) *bool { return &v }(true), | ||
Kind: "KubeadmControlPlane", | ||
UID: cluster.GetUID(), | ||
}, | ||
}, | ||
}, | ||
Type: "cluster.x-k8s.io/secret", | ||
Data: map[string][]byte{}, | ||
} | ||
It("should return the proper name for the kubeconfig", func() { | ||
By("providing a namespaced cluster object") | ||
namespacedName, err := GetCapiKubeconfigNamespacedName(&cluster) | ||
|
||
By("asserting that the name is correct") | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(namespacedName).To(Equal(types.NamespacedName{Name: kubeconfig.Name, Namespace: kubeconfig.Namespace})) | ||
}) | ||
|
||
It("should validate the kubeconfig", func() { | ||
By("providing a kubeconfig secret object") | ||
validated, err := IsCapiKubeconfig(&kubeconfig, &cluster) | ||
|
||
By("asserting that the secret is a kubeadm kubeconfig") | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(validated).To(BeTrue()) | ||
}) | ||
}) | ||
|
||
Context("When a cluster has a vcluster controlPlaneRef", func() { | ||
clusterName := "vcluster-cluster" | ||
clusterNamespace := "vcluster-cluster-namespace" | ||
cluster := capiv1beta1.Cluster{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: clusterName, | ||
Namespace: clusterNamespace, | ||
UID: types.UID(uuid.New().String()), | ||
}, | ||
Spec: capiv1beta1.ClusterSpec{ | ||
ControlPlaneRef: &corev1.ObjectReference{ | ||
APIVersion: "infrastructure.cluster.x-k8s.io/v1alpha1", | ||
Kind: "VCluster", | ||
Name: clusterName, | ||
Namespace: clusterNamespace, | ||
}, | ||
}, | ||
} | ||
|
||
var kubeconfig = corev1.Secret{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: clusterName + "-kubeconfig", | ||
Namespace: clusterNamespace, | ||
}, | ||
Data: map[string][]byte{}, | ||
} | ||
It("should return the proper name for the kubeconfig", func() { | ||
By("providing a namespaced cluster object") | ||
namespacedName, err := GetCapiKubeconfigNamespacedName(&cluster) | ||
|
||
By("asserting that the name is correct") | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(namespacedName).To(Equal(types.NamespacedName{Name: kubeconfig.Name, Namespace: kubeconfig.Namespace})) | ||
}) | ||
|
||
It("should validate the kubeconfig", func() { | ||
By("providing a kubeconfig secret object") | ||
validated, err := IsCapiKubeconfig(&kubeconfig, &cluster) | ||
|
||
By("asserting that the secret is a vcluster kubeconfig") | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(validated).To(BeTrue()) | ||
}) | ||
}) | ||
|
||
Context("When a cluster has an AWS managed controlPlaneRef", func() { | ||
clusterName := "eks-cluster" | ||
clusterNamespace := "eks-cluster-namespace" | ||
cluster := capiv1beta1.Cluster{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: clusterName, | ||
Namespace: clusterNamespace, | ||
UID: types.UID(uuid.New().String()), | ||
}, | ||
Spec: capiv1beta1.ClusterSpec{ | ||
ControlPlaneRef: &corev1.ObjectReference{ | ||
APIVersion: "controlplane.cluster.x-k8s.io/v1beta2", | ||
Kind: "AWSManagedControlPlane", | ||
Name: clusterName, | ||
Namespace: clusterNamespace, | ||
}, | ||
}, | ||
} | ||
|
||
var kubeconfig = corev1.Secret{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: clusterName + "-user-kubeconfig", | ||
Namespace: clusterNamespace, | ||
OwnerReferences: []metav1.OwnerReference{ | ||
{ | ||
APIVersion: "controlplane.cluster.x-k8s.io/v1beta2", | ||
BlockOwnerDeletion: func(v bool) *bool { return &v }(true), | ||
Controller: func(v bool) *bool { return &v }(true), | ||
Kind: "AWSManagedControlPlane", | ||
UID: cluster.GetUID(), | ||
}, | ||
}, | ||
}, | ||
Type: "cluster.x-k8s.io/secret", | ||
Data: map[string][]byte{}, | ||
} | ||
It("should return the proper name for the kubeconfig", func() { | ||
By("providing a namespaced cluster object") | ||
namespacedName, err := GetCapiKubeconfigNamespacedName(&cluster) | ||
|
||
By("asserting that the name is correct") | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(namespacedName).To(Equal(types.NamespacedName{Name: kubeconfig.Name, Namespace: kubeconfig.Namespace})) | ||
}) | ||
|
||
It("should validate the kubeconfig", func() { | ||
By("providing a kubeconfig secret object") | ||
validated, err := IsCapiKubeconfig(&kubeconfig, &cluster) | ||
|
||
By("asserting that the secret is an AWS managed kubeconfig") | ||
Expect(err).NotTo(HaveOccurred()) | ||
Expect(validated).To(BeTrue()) | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.