Skip to content

Commit

Permalink
[e2e] Deploy clusters and creds in the default namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
eromanova committed Nov 14, 2024
1 parent 61adb50 commit cbd95cb
Show file tree
Hide file tree
Showing 11 changed files with 95 additions and 75 deletions.
50 changes: 27 additions & 23 deletions test/e2e/kubeclient/kubeclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,16 @@ func NewFromLocal(namespace string) *KubeClient {
// the kubeconfig from secret it needs an existing kubeclient.
func (kc *KubeClient) NewFromCluster(ctx context.Context, namespace, clusterName string) *KubeClient {
GinkgoHelper()
return newKubeClient(kc.getKubeconfigSecretData(ctx, clusterName), namespace)
return newKubeClient(kc.getKubeconfigSecretData(ctx, namespace, clusterName), namespace)
}

// WriteKubeconfig writes the kubeconfig for the given clusterName to the
// test/e2e directory returning the path to the file and a function to delete
// it later.
func (kc *KubeClient) WriteKubeconfig(ctx context.Context, clusterName string) (string, func() error) {
func (kc *KubeClient) WriteKubeconfig(ctx context.Context, namespace, clusterName string) (string, func() error) {
GinkgoHelper()

secretData := kc.getKubeconfigSecretData(ctx, clusterName)
secretData := kc.getKubeconfigSecretData(ctx, namespace, clusterName)

dir, err := os.Getwd()
Expect(err).NotTo(HaveOccurred())
Expand All @@ -95,11 +95,11 @@ func (kc *KubeClient) WriteKubeconfig(ctx context.Context, clusterName string) (
return path, deleteFunc
}

func (kc *KubeClient) getKubeconfigSecretData(ctx context.Context, clusterName string) []byte {
func (kc *KubeClient) getKubeconfigSecretData(ctx context.Context, namespace, clusterName string) []byte {
GinkgoHelper()

secret, err := kc.Client.CoreV1().Secrets(kc.Namespace).Get(ctx, clusterName+"-kubeconfig", metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred(), "failed to get cluster: %q kubeconfig secret", clusterName)
secret, err := kc.Client.CoreV1().Secrets(namespace).Get(ctx, clusterName+"-kubeconfig", metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred(), "failed to get cluster: %q kubeconfig secret in %s namespace", clusterName, namespace)

secretData, ok := secret.Data["value"]
Expect(ok).To(BeTrue(), "kubeconfig secret %q has no 'value' key", clusterName)
Expand Down Expand Up @@ -157,23 +157,23 @@ func newKubeClient(configBytes []byte, namespace string) *KubeClient {
}

// GetDynamicClient returns a dynamic client for the given GroupVersionResource.
func (kc *KubeClient) GetDynamicClient(gvr schema.GroupVersionResource, namespaced bool) dynamic.ResourceInterface { //nolint:revive
func (kc *KubeClient) GetDynamicClient(gvr schema.GroupVersionResource, namespace string) dynamic.ResourceInterface {
GinkgoHelper()

client, err := dynamic.NewForConfig(kc.Config)
Expect(err).NotTo(HaveOccurred(), "failed to create dynamic client for resource: %s", gvr.String())

if !namespaced {
if namespace == "" {
return client.Resource(gvr)
}

return client.Resource(gvr).Namespace(kc.Namespace)
return client.Resource(gvr).Namespace(namespace)
}

func (kc *KubeClient) CreateOrUpdateUnstructuredObject(gvr schema.GroupVersionResource, obj *unstructured.Unstructured, namespaced bool) {
func (kc *KubeClient) CreateOrUpdateUnstructuredObject(gvr schema.GroupVersionResource, obj *unstructured.Unstructured, namespace string) {
GinkgoHelper()

client := kc.GetDynamicClient(gvr, namespaced)
client := kc.GetDynamicClient(gvr, namespace)

kind, name := status.ObjKindName(obj)

Expand All @@ -194,18 +194,22 @@ func (kc *KubeClient) CreateOrUpdateUnstructuredObject(gvr schema.GroupVersionRe
// namespace and returns a DeleteFunc to clean up the deployment.
// The DeleteFunc is a no-op if the deployment has already been deleted.
func (kc *KubeClient) CreateManagedCluster(
ctx context.Context, managedcluster *unstructured.Unstructured,
ctx context.Context, managedcluster *unstructured.Unstructured, namespace string,
) func() error {
GinkgoHelper()

kind := managedcluster.GetKind()
Expect(kind).To(Equal("ManagedCluster"))

if namespace != "" {
managedcluster.SetNamespace(namespace)
}

client := kc.GetDynamicClient(schema.GroupVersionResource{
Group: "hmc.mirantis.com",
Version: "v1alpha1",
Resource: "managedclusters",
}, true)
}, namespace)

_, err := client.Create(ctx, managedcluster, metav1.CreateOptions{})
if !apierrors.IsAlreadyExists(err) {
Expand All @@ -222,14 +226,14 @@ func (kc *KubeClient) CreateManagedCluster(
}

// GetCluster returns a Cluster resource by name.
func (kc *KubeClient) GetCluster(ctx context.Context, clusterName string) (*unstructured.Unstructured, error) {
func (kc *KubeClient) GetCluster(ctx context.Context, namespace, clusterName string) (*unstructured.Unstructured, error) {
gvr := schema.GroupVersionResource{
Group: "cluster.x-k8s.io",
Version: "v1beta1",
Resource: "clusters",
}

client := kc.GetDynamicClient(gvr, true)
client := kc.GetDynamicClient(gvr, namespace)

cluster, err := client.Get(ctx, clusterName, metav1.GetOptions{})
if err != nil {
Expand All @@ -242,9 +246,9 @@ func (kc *KubeClient) GetCluster(ctx context.Context, clusterName string) (*unst
// listResource returns a list of resources for the given GroupVersionResource
// affiliated with the given clusterName.
func (kc *KubeClient) listResource(
ctx context.Context, gvr schema.GroupVersionResource, clusterName string,
ctx context.Context, gvr schema.GroupVersionResource, namespace, clusterName string,
) ([]unstructured.Unstructured, error) {
client := kc.GetDynamicClient(gvr, true)
client := kc.GetDynamicClient(gvr, namespace)

resources, err := client.List(ctx, metav1.ListOptions{
LabelSelector: "cluster.x-k8s.io/cluster-name=" + clusterName,
Expand All @@ -257,38 +261,38 @@ func (kc *KubeClient) listResource(
}

// ListMachines returns a list of Machine resources for the given cluster.
func (kc *KubeClient) ListMachines(ctx context.Context, clusterName string) ([]unstructured.Unstructured, error) {
func (kc *KubeClient) ListMachines(ctx context.Context, namespace, clusterName string) ([]unstructured.Unstructured, error) {
GinkgoHelper()

return kc.listResource(ctx, schema.GroupVersionResource{
Group: "cluster.x-k8s.io",
Version: "v1beta1",
Resource: "machines",
}, clusterName)
}, namespace, clusterName)
}

// ListMachineDeployments returns a list of MachineDeployment resources for the
// given cluster.
func (kc *KubeClient) ListMachineDeployments(
ctx context.Context, clusterName string,
ctx context.Context, namespace, clusterName string,
) ([]unstructured.Unstructured, error) {
GinkgoHelper()

return kc.listResource(ctx, schema.GroupVersionResource{
Group: "cluster.x-k8s.io",
Version: "v1beta1",
Resource: "machinedeployments",
}, clusterName)
}, namespace, clusterName)
}

func (kc *KubeClient) ListK0sControlPlanes(
ctx context.Context, clusterName string,
ctx context.Context, namespace, clusterName string,
) ([]unstructured.Unstructured, error) {
GinkgoHelper()

return kc.listResource(ctx, schema.GroupVersionResource{
Group: "controlplane.cluster.x-k8s.io",
Version: "v1beta1",
Resource: "k0scontrolplanes",
}, clusterName)
}, namespace, clusterName)
}
2 changes: 1 addition & 1 deletion test/e2e/managedcluster/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func PopulateHostedTemplateVars(ctx context.Context, kc *kubeclient.KubeClient,
Group: "infrastructure.cluster.x-k8s.io",
Version: "v1beta2",
Resource: "awsclusters",
}, true)
}, managedcluster.Namespace)

awsCluster, err := c.Get(ctx, clusterName, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred(), "failed to get AWS cluster")
Expand Down
3 changes: 2 additions & 1 deletion test/e2e/managedcluster/azure/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (

hmc "github.com/Mirantis/hmc/api/v1alpha1"
"github.com/Mirantis/hmc/test/e2e/kubeclient"
"github.com/Mirantis/hmc/test/e2e/managedcluster"
)

func getAzureInfo(ctx context.Context, name string, kc *kubeclient.KubeClient) map[string]any {
Expand All @@ -41,7 +42,7 @@ func getAzureInfo(ctx context.Context, name string, kc *kubeclient.KubeClient) m
Resource: "azureclusters",
}

dc := kc.GetDynamicClient(resourceID, true)
dc := kc.GetDynamicClient(resourceID, managedcluster.Namespace)
list, err := dc.List(ctx, metav1.ListOptions{
LabelSelector: labels.SelectorFromSet(map[string]string{hmc.FluxHelmChartNameKey: name}).String(),
})
Expand Down
23 changes: 13 additions & 10 deletions test/e2e/managedcluster/clusteridentity/clusteridentity.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ type ClusterIdentity struct {
IdentityName string
SecretData map[string]string
Spec map[string]any
Namespaced bool
Namespace string
}

// New creates a ClusterIdentity resource, credential and associated secret for
// the given provider using the provided KubeClient and returns details about
// the created ClusterIdentity.
func New(kc *kubeclient.KubeClient, provider managedcluster.ProviderType) *ClusterIdentity {
func New(kc *kubeclient.KubeClient, provider managedcluster.ProviderType, namespace string) *ClusterIdentity {
GinkgoHelper()

var (
Expand Down Expand Up @@ -126,14 +126,17 @@ func New(kc *kubeclient.KubeClient, provider managedcluster.ProviderType) *Clust
IdentityName: identityName,
SecretData: secretStringData,
Spec: spec,
Namespaced: namespaced,
}

if namespaced {
ci.Namespace = namespace
}

validateSecretDataPopulated(secretStringData)
ci.waitForResourceCRD(kc)
ci.createSecret(kc)
ci.createClusterIdentity(kc)
ci.createCredential(kc)
ci.createCredential(kc, namespace)

return &ci
}
Expand Down Expand Up @@ -200,7 +203,7 @@ func (ci *ClusterIdentity) createSecret(kc *kubeclient.KubeClient) {
}
}

func (ci *ClusterIdentity) createCredential(kc *kubeclient.KubeClient) {
func (ci *ClusterIdentity) createCredential(kc *kubeclient.KubeClient, namespace string) {
GinkgoHelper()

credName := fmt.Sprintf("%s-cred", ci.IdentityName)
Expand All @@ -212,14 +215,14 @@ func (ci *ClusterIdentity) createCredential(kc *kubeclient.KubeClient) {
"kind": "Credential",
"metadata": map[string]any{
"name": credName,
"namespace": kc.Namespace,
"namespace": namespace,
},
"spec": map[string]any{
"identityRef": map[string]any{
"apiVersion": ci.GroupVersionResource.Group + "/" + ci.GroupVersionResource.Version,
"kind": ci.Kind,
"name": ci.IdentityName,
"namespace": kc.Namespace,
"namespace": ci.Namespace,
},
},
},
Expand All @@ -229,7 +232,7 @@ func (ci *ClusterIdentity) createCredential(kc *kubeclient.KubeClient) {
Group: "hmc.mirantis.com",
Version: "v1alpha1",
Resource: "credentials",
}, cred, true)
}, cred, namespace)
}

// createClusterIdentity creates a ClusterIdentity resource.
Expand All @@ -244,11 +247,11 @@ func (ci *ClusterIdentity) createClusterIdentity(kc *kubeclient.KubeClient) {
"kind": ci.Kind,
"metadata": map[string]any{
"name": ci.IdentityName,
"namespace": kc.Namespace,
"namespace": ci.Namespace,
},
"spec": ci.Spec,
},
}

kc.CreateOrUpdateUnstructuredObject(ci.GroupVersionResource, id, ci.Namespaced)
kc.CreateOrUpdateUnstructuredObject(ci.GroupVersionResource, id, ci.Namespace)
}
4 changes: 2 additions & 2 deletions test/e2e/managedcluster/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import (
// See: https://docs.k0smotron.io/stable/capi-aws/#prepare-the-aws-infra-provider
// Use Eventually as the resource might not be available immediately following
// a ManagedCluster creation.
func PatchHostedClusterReady(kc *kubeclient.KubeClient, provider ProviderType, clusterName string) {
func PatchHostedClusterReady(kc *kubeclient.KubeClient, provider ProviderType, namespace, clusterName string) {
GinkgoHelper()

ctx := context.Background()
Expand All @@ -61,7 +61,7 @@ func PatchHostedClusterReady(kc *kubeclient.KubeClient, provider ProviderType, c
Group: "infrastructure.cluster.x-k8s.io",
Version: version,
Resource: resource,
}, true)
}, namespace)

trueStatus := map[string]any{
"status": map[string]any{
Expand Down
11 changes: 7 additions & 4 deletions test/e2e/managedcluster/providervalidator.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import (
type ProviderValidator struct {
// Template is the name of the template being validated.
template Template
// Namespace is the namespace of the cluster to validate.
namespace string
// ClusterName is the name of the cluster to validate.
clusterName string
// ResourcesToValidate is a map of resource names to their validation
Expand All @@ -46,7 +48,7 @@ const (
ValidationActionDelete ValidationAction = "delete"
)

func NewProviderValidator(template Template, clusterName string, action ValidationAction) *ProviderValidator {
func NewProviderValidator(template Template, namespace, clusterName string, action ValidationAction) *ProviderValidator {
var (
resourcesToValidate map[string]resourceValidationFunc
resourceOrder []string
Expand Down Expand Up @@ -79,6 +81,7 @@ func NewProviderValidator(template Template, clusterName string, action Validati

return &ProviderValidator{
template: template,
namespace: namespace,
clusterName: clusterName,
resourcesToValidate: resourcesToValidate,
resourceOrder: resourceOrder,
Expand All @@ -103,12 +106,12 @@ func (p *ProviderValidator) Validate(ctx context.Context, kc *kubeclient.KubeCli
continue
}

if err := validator(ctx, kc, p.clusterName); err != nil {
_, _ = fmt.Fprintf(GinkgoWriter, "[%s/%s] validation error: %v\n", p.template, name, err)
if err := validator(ctx, kc, p.namespace, p.clusterName); err != nil {
_, _ = fmt.Fprintf(GinkgoWriter, "Template %s [%s/%s] validation error: %v\n", p.template, p.namespace, name, err)
return err
}

_, _ = fmt.Fprintf(GinkgoWriter, "[%s/%s] validation succeeded\n", p.template, name)
_, _ = fmt.Fprintf(GinkgoWriter, "Template %s [%s/%s] validation succeeded\n", p.template, p.namespace, name)
delete(p.resourcesToValidate, name)
}

Expand Down
12 changes: 6 additions & 6 deletions test/e2e/managedcluster/validate_deleted.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import (
)

// validateClusterDeleted validates that the Cluster resource has been deleted.
func validateClusterDeleted(ctx context.Context, kc *kubeclient.KubeClient, clusterName string) error {
func validateClusterDeleted(ctx context.Context, kc *kubeclient.KubeClient, namespace, clusterName string) error {
// Validate that the Cluster resource has been deleted
cluster, err := kc.GetCluster(ctx, clusterName)
cluster, err := kc.GetCluster(ctx, namespace, clusterName)
if err != nil && !apierrors.IsNotFound(err) {
return err
}
Expand Down Expand Up @@ -64,8 +64,8 @@ func validateClusterDeleted(ctx context.Context, kc *kubeclient.KubeClient, clus

// validateMachineDeploymentsDeleted validates that all MachineDeployments have
// been deleted.
func validateMachineDeploymentsDeleted(ctx context.Context, kc *kubeclient.KubeClient, clusterName string) error {
machineDeployments, err := kc.ListMachineDeployments(ctx, clusterName)
func validateMachineDeploymentsDeleted(ctx context.Context, kc *kubeclient.KubeClient, namespace, clusterName string) error {
machineDeployments, err := kc.ListMachineDeployments(ctx, namespace, clusterName)
if err != nil && !apierrors.IsNotFound(err) {
return err
}
Expand All @@ -84,8 +84,8 @@ func validateMachineDeploymentsDeleted(ctx context.Context, kc *kubeclient.KubeC

// validateK0sControlPlanesDeleted validates that all k0scontrolplanes have
// been deleted.
func validateK0sControlPlanesDeleted(ctx context.Context, kc *kubeclient.KubeClient, clusterName string) error {
controlPlanes, err := kc.ListK0sControlPlanes(ctx, clusterName)
func validateK0sControlPlanesDeleted(ctx context.Context, kc *kubeclient.KubeClient, namespace, clusterName string) error {
controlPlanes, err := kc.ListK0sControlPlanes(ctx, namespace, clusterName)
if err != nil && !apierrors.IsNotFound(err) {
return err
}
Expand Down
Loading

0 comments on commit cbd95cb

Please sign in to comment.