Skip to content

Commit

Permalink
Support patching other hosted clusters with a common patching helper
Browse files Browse the repository at this point in the history
Signed-off-by: Kyle Squizzato <ksquizzato@mirantis.com>
  • Loading branch information
squizzi committed Oct 2, 2024
1 parent 325a344 commit 25aef1d
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 49 deletions.
41 changes: 6 additions & 35 deletions test/e2e/managedcluster/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,12 @@ package aws

import (
"context"
"encoding/json"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/dynamic"

"github.com/Mirantis/hmc/test/e2e/kubeclient"
"github.com/Mirantis/hmc/test/e2e/managedcluster"
Expand All @@ -38,7 +35,12 @@ import (
func PopulateHostedTemplateVars(ctx context.Context, kc *kubeclient.KubeClient, clusterName string) {
GinkgoHelper()

c := getAWSClusterClient(kc)
c := kc.GetDynamicClient(schema.GroupVersionResource{
Group: "infrastructure.cluster.x-k8s.io",
Version: "v1beta2",
Resource: "awsclusters",
}, true)

awsCluster, err := c.Get(ctx, clusterName, metav1.GetOptions{})
Expect(err).NotTo(HaveOccurred(), "failed to get AWS cluster")

Expand Down Expand Up @@ -69,34 +71,3 @@ func PopulateHostedTemplateVars(ctx context.Context, kc *kubeclient.KubeClient,
GinkgoT().Setenv(managedcluster.EnvVarAWSSubnetAvailabilityZone, subnetAZ)
GinkgoT().Setenv(managedcluster.EnvVarAWSSecurityGroupID, securityGroupID)
}

func PatchAWSClusterReady(ctx context.Context, kc *kubeclient.KubeClient, clusterName string) error {
GinkgoHelper()

c := getAWSClusterClient(kc)

trueStatus := map[string]any{
"status": map[string]any{
"ready": true,
},
}

patchBytes, err := json.Marshal(trueStatus)
Expect(err).NotTo(HaveOccurred(), "failed to marshal patch bytes")

_, err = c.Patch(ctx, clusterName, types.MergePatchType,
patchBytes, metav1.PatchOptions{}, "status")
if err != nil {
return err
}

return nil
}

func getAWSClusterClient(kc *kubeclient.KubeClient) dynamic.ResourceInterface {
return kc.GetDynamicClient(schema.GroupVersionResource{
Group: "infrastructure.cluster.x-k8s.io",
Version: "v1beta2",
Resource: "awsclusters",
}, true)
}
84 changes: 84 additions & 0 deletions test/e2e/managedcluster/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2024
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package managedcluster

import (
"context"
"encoding/json"
"fmt"
"time"

"github.com/Mirantis/hmc/test/e2e/kubeclient"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
)

// PatchHostedClusterReady patches a hosted clusters' infrastructure resource
// as Ready depending on the given provider.
// 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) {
GinkgoHelper()

ctx := context.Background()

var (
version string
resource string
)

switch provider {
case ProviderAWS:
version = "v1beta2"
resource = "awsclusters"
case ProviderAzure:
version = "v1beta1"
resource = "azureclusters"
case ProviderVSphere:
version = "v1beta1"
resource = "vsphereclusters"
default:
Fail(fmt.Sprintf("unsupported provider: %s", provider))
}

c := kc.GetDynamicClient(schema.GroupVersionResource{
Group: "infrastructure.cluster.x-k8s.io",
Version: version,
Resource: resource,
}, true)

trueStatus := map[string]any{
"status": map[string]any{
"ready": true,
},
}

patchBytes, err := json.Marshal(trueStatus)
Expect(err).NotTo(HaveOccurred(), "failed to marshal patch bytes")

Eventually(func() error {
_, err = c.Patch(ctx, clusterName, types.MergePatchType,
patchBytes, metav1.PatchOptions{}, "status")
if err != nil {
return err
}
_, _ = fmt.Fprintf(GinkgoWriter, "Patch succeeded\n")
return nil
}).WithTimeout(time.Minute).WithPolling(5 * time.Second).Should(Succeed())
}
15 changes: 2 additions & 13 deletions test/e2e/provider_aws_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ var _ = Describe("AWS Templates", Label("provider:cloud", "provider:aws"), Order
Expect(os.Unsetenv("KUBECONFIG")).To(Succeed())

templateBy(managedcluster.TemplateAWSHostedCP, "validating that the controller is ready")
standaloneClient = kc.NewFromCluster(context.Background(), internalutils.DefaultSystemNamespace, clusterName)
Eventually(func() error {
err := verifyControllersUp(standaloneClient)
if err != nil {
Expand All @@ -124,7 +125,6 @@ var _ = Describe("AWS Templates", Label("provider:cloud", "provider:aws"), Order
}).WithTimeout(15 * time.Minute).WithPolling(10 * time.Second).Should(Succeed())

// Ensure AWS credentials are set in the standalone cluster.
standaloneClient = kc.NewFromCluster(context.Background(), internalutils.DefaultSystemNamespace, clusterName)
clusteridentity.New(standaloneClient, managedcluster.ProviderAWS)

// Populate the environment variables required for the hosted
Expand All @@ -138,19 +138,8 @@ var _ = Describe("AWS Templates", Label("provider:cloud", "provider:aws"), Order
// Deploy the hosted cluster on top of the standalone cluster.
hostedDeleteFunc = standaloneClient.CreateManagedCluster(context.Background(), hd)

// Patch the AWSCluster resource as Ready, see:
// https://docs.k0smotron.io/stable/capi-aws/#prepare-the-aws-infra-provider
// Use Eventually as the AWSCluster might not be available
// immediately.
templateBy(managedcluster.TemplateAWSHostedCP, "Patching AWSCluster to ready")
Eventually(func() error {
if err := aws.PatchAWSClusterReady(context.Background(), standaloneClient, hd.GetName()); err != nil {
_, _ = fmt.Fprintf(GinkgoWriter, "failed to patch AWSCluster to ready: %v, retrying...\n", err)
return err
}
_, _ = fmt.Fprintf(GinkgoWriter, "Patch succeeded\n")
return nil
}).WithTimeout(time.Minute).WithPolling(5 * time.Second).Should(Succeed())
managedcluster.PatchHostedClusterReady(standaloneClient, managedcluster.ProviderAWS, hdName)

// Verify the hosted cluster is running/ready.
templateBy(managedcluster.TemplateAWSHostedCP, "waiting for infrastructure to deploy successfully")
Expand Down
4 changes: 3 additions & 1 deletion test/e2e/provider_azure_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,10 @@ var _ = Context("Azure Templates", Label("provider:cloud", "provider:azure"), Or
templateBy(managedcluster.TemplateAzureHostedCP, "creating a ManagedCluster")
hostedDeleteFunc = standaloneClient.CreateManagedCluster(context.Background(), hd)

templateBy(managedcluster.TemplateAzureHostedCP, "waiting for infrastructure to deploy successfully")
templateBy(managedcluster.TemplateAWSHostedCP, "Patching AzureCluster to ready")
managedcluster.PatchHostedClusterReady(standaloneClient, managedcluster.ProviderAzure, hdName)

templateBy(managedcluster.TemplateAzureHostedCP, "waiting for infrastructure to deploy successfully")
deploymentValidator = managedcluster.NewProviderValidator(
managedcluster.TemplateAzureHostedCP,
hdName,
Expand Down

0 comments on commit 25aef1d

Please sign in to comment.