From 4cfeb799643525a84d2e145e1b951731612df795 Mon Sep 17 00:00:00 2001 From: Aniruddha Basak Date: Wed, 13 Mar 2024 20:46:10 +0530 Subject: [PATCH] Delete old object when cluster upgrade - Download old cluster stack release if not present in the pod Signed-off-by: Aniruddha Basak --- api/v1alpha1/conditions_const.go | 3 + cmd/main.go | 1 + .../controller/clusteraddon_controller.go | 218 +++++++++++++++--- pkg/kube/fake/kube.go | 59 +++++ pkg/kube/helpers.go | 33 +++ pkg/kube/kube.go | 105 +++++++++ pkg/kube/mocks/Client.go | 62 ++++- .../ferrol/1-27/cluster-addon/cni/Chart.yaml | 0 .../1-27/cluster-addon/cni/templates/cni.yaml | 0 .../ferrol/1-27/cluster-addon/cni/values.yaml | 0 .../cluster-addon/metrics-server/.helmignore | 0 .../cluster-addon/metrics-server/Chart.lock | 0 .../cluster-addon/metrics-server/Chart.yaml | 0 .../charts/metrics-server-3.11.0.tgz | Bin .../metrics-server/overwrite.yaml | 0 .../metrics-server/templates/ngnix.yaml | 101 ++++++++ .../cluster-addon/metrics-server/values.yaml | 0 .../ferrol/1-27/cluster-class}/.helmignore | 0 .../ferrol/1-27/cluster-class/Chart.yaml | 0 .../1-27/cluster-class/templates/_helpers.tpl | 0 .../templates/cluster-class.yaml | 0 .../templates/docker-cluster-template.yaml | 0 .../templates/docker-machine-template.yaml | 0 ...kubeadm-config-template-worker-docker.yaml | 0 .../kubeadm-control-plane-template.yaml | 0 .../ferrol/1-27/cluster-class/values.yaml | 0 .../docker/ferrol/1-27/clusteraddon.yaml | 0 .../1/docker/ferrol/1-27/csmctl.yaml | 7 + .../1-27/node-image/Dockerfile.controlplane | 0 .../ferrol/1-27/node-image/Dockerfile.worker | 0 .../ferrol/1-27/node-image/scripts/base.sh | 0 .../docker/ferrol/1-27/node-images.yaml | 0 .../docker/ferrol/1-27/topology-docker.yaml | 0 .../ferrol/1-27/cluster-addon/cni/Chart.yaml | 9 + .../1-27/cluster-addon/cni/templates/cni.yaml | 120 ++++++++++ .../ferrol/1-27/cluster-addon/cni/values.yaml | 0 .../cluster-addon/metrics-server}/.helmignore | 0 .../cluster-addon/metrics-server/Chart.lock | 6 + .../cluster-addon/metrics-server/Chart.yaml | 16 ++ .../charts/metrics-server-3.11.0.tgz | Bin 0 -> 8462 bytes .../metrics-server/overwrite.yaml | 4 + .../cluster-addon/metrics-server/values.yaml | 44 ++++ .../1-27/cluster-addon/ngnix/.helmignore | 23 ++ .../1-27/cluster-addon/ngnix/Chart.lock | 0 .../1-27/cluster-addon/ngnix/Chart.yaml | 0 .../ngnix/charts/nginx-15.10.1.tgz | Bin .../1-27/cluster-addon/ngnix/values.yaml | 0 .../ferrol/1-27/cluster-class/.helmignore | 23 ++ .../ferrol/1-27/cluster-class/Chart.yaml | 11 + .../1-27/cluster-class/templates/_helpers.tpl | 62 +++++ .../templates/cluster-class.yaml | 101 ++++++++ .../templates/docker-cluster-template.yaml | 8 + .../templates/docker-machine-template.yaml | 11 + ...kubeadm-config-template-worker-docker.yaml | 15 ++ .../kubeadm-control-plane-template.yaml | 29 +++ .../ferrol/1-27/cluster-class/values.yaml | 5 + .../2/docker/ferrol/1-27/clusteraddon.yaml | 26 +++ .../{ => 2}/docker/ferrol/1-27/csmctl.yaml | 0 .../1-27/node-image/Dockerfile.controlplane | 3 + .../ferrol/1-27/node-image/Dockerfile.worker | 3 + .../ferrol/1-27/node-image/scripts/base.sh | 46 ++++ .../2/docker/ferrol/1-27/node-images.yaml | 4 + .../2/docker/ferrol/1-27/topology-docker.yaml | 26 +++ .../docker/ferrol/1-27/metadata.yaml | 7 - 64 files changed, 1149 insertions(+), 42 deletions(-) create mode 100644 pkg/kube/fake/kube.go rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-addon/cni/Chart.yaml (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-addon/cni/templates/cni.yaml (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-addon/cni/values.yaml (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-addon/metrics-server/.helmignore (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.lock (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.yaml (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-addon/metrics-server/charts/metrics-server-3.11.0.tgz (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-addon/metrics-server/overwrite.yaml (100%) create mode 100644 test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/templates/ngnix.yaml rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-addon/metrics-server/values.yaml (100%) rename test/cluster-stacks/{docker/ferrol/1-27/cluster-addon/ngnix => 1/docker/ferrol/1-27/cluster-class}/.helmignore (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-class/Chart.yaml (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-class/templates/_helpers.tpl (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-class/templates/cluster-class.yaml (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-class/templates/docker-cluster-template.yaml (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-class/templates/docker-machine-template.yaml (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-class/templates/kubeadm-config-template-worker-docker.yaml (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-class/templates/kubeadm-control-plane-template.yaml (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/cluster-class/values.yaml (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/clusteraddon.yaml (100%) create mode 100644 test/cluster-stacks/1/docker/ferrol/1-27/csmctl.yaml rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/node-image/Dockerfile.controlplane (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/node-image/Dockerfile.worker (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/node-image/scripts/base.sh (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/node-images.yaml (100%) rename test/cluster-stacks/{ => 1}/docker/ferrol/1-27/topology-docker.yaml (100%) create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/cni/Chart.yaml create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/cni/templates/cni.yaml create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/cni/values.yaml rename test/cluster-stacks/{docker/ferrol/1-27/cluster-class => 2/docker/ferrol/1-27/cluster-addon/metrics-server}/.helmignore (100%) create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.lock create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.yaml create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/charts/metrics-server-3.11.0.tgz create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/overwrite.yaml create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/values.yaml create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/ngnix/.helmignore rename test/cluster-stacks/{ => 2}/docker/ferrol/1-27/cluster-addon/ngnix/Chart.lock (100%) rename test/cluster-stacks/{ => 2}/docker/ferrol/1-27/cluster-addon/ngnix/Chart.yaml (100%) rename test/cluster-stacks/{ => 2}/docker/ferrol/1-27/cluster-addon/ngnix/charts/nginx-15.10.1.tgz (100%) rename test/cluster-stacks/{ => 2}/docker/ferrol/1-27/cluster-addon/ngnix/values.yaml (100%) create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/.helmignore create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/Chart.yaml create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/_helpers.tpl create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/cluster-class.yaml create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/docker-cluster-template.yaml create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/docker-machine-template.yaml create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/kubeadm-config-template-worker-docker.yaml create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/kubeadm-control-plane-template.yaml create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/values.yaml create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/clusteraddon.yaml rename test/cluster-stacks/{ => 2}/docker/ferrol/1-27/csmctl.yaml (100%) create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/node-image/Dockerfile.controlplane create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/node-image/Dockerfile.worker create mode 100755 test/cluster-stacks/2/docker/ferrol/1-27/node-image/scripts/base.sh create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/node-images.yaml create mode 100644 test/cluster-stacks/2/docker/ferrol/1-27/topology-docker.yaml delete mode 100644 test/cluster-stacks/docker/ferrol/1-27/metadata.yaml diff --git a/api/v1alpha1/conditions_const.go b/api/v1alpha1/conditions_const.go index 8f138c7f2..2ea78dbf4 100644 --- a/api/v1alpha1/conditions_const.go +++ b/api/v1alpha1/conditions_const.go @@ -110,6 +110,9 @@ const ( // GitTokenOrEnvVariableNotSetReason is used when user don't specify the token or environment variable. GitTokenOrEnvVariableNotSetReason = "GitTokenOrEnvVariableNotSet" //#nosec + + // FailedCreateGithubClientReason is used when user don't specify the token or environment variable. + FailedCreateGithubClientReason = "FailedCreateGithubClient" //#nosec ) const ( diff --git a/cmd/main.go b/cmd/main.go index 17223f4c5..3f40f76c7 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -161,6 +161,7 @@ func main() { WatchFilterValue: watchFilterValue, KubeClientFactory: kube.NewFactory(), WorkloadClusterFactory: workloadcluster.NewFactory(), + GitHubClientFactory: gitFactory, }).SetupWithManager(ctx, mgr, controllerruntimecontroller.Options{MaxConcurrentReconciles: clusterAddonConcurrency}); err != nil { setupLog.Error(err, "unable to create controller", "controller", "ClusterAddon") os.Exit(1) diff --git a/internal/controller/clusteraddon_controller.go b/internal/controller/clusteraddon_controller.go index 1748b7c59..ca8daf6fc 100644 --- a/internal/controller/clusteraddon_controller.go +++ b/internal/controller/clusteraddon_controller.go @@ -29,14 +29,17 @@ import ( "path/filepath" "reflect" "strings" + "sync" "text/template" "time" csov1alpha1 "github.com/SovereignCloudStack/cluster-stack-operator/api/v1alpha1" "github.com/SovereignCloudStack/cluster-stack-operator/pkg/clusteraddon" + githubclient "github.com/SovereignCloudStack/cluster-stack-operator/pkg/github/client" "github.com/SovereignCloudStack/cluster-stack-operator/pkg/kube" "github.com/SovereignCloudStack/cluster-stack-operator/pkg/release" "github.com/SovereignCloudStack/cluster-stack-operator/pkg/workloadcluster" + "github.com/go-logr/logr" sprig "github.com/go-task/slim-sprig" "github.com/google/cel-go/cel" celtypes "github.com/google/cel-go/common/types" @@ -63,6 +66,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" "sigs.k8s.io/controller-runtime/pkg/source" @@ -80,10 +84,12 @@ type RestConfigSettings struct { type ClusterAddonReconciler struct { client.Client RestConfigSettings - ReleaseDirectory string - KubeClientFactory kube.Factory - WatchFilterValue string - WorkloadClusterFactory workloadcluster.Factory + ReleaseDirectory string + KubeClientFactory kube.Factory + GitHubClientFactory githubclient.Factory + WatchFilterValue string + WorkloadClusterFactory workloadcluster.Factory + clusterStackRelDownloadDirectoryMutex sync.Mutex } //+kubebuilder:rbac:groups=clusterstack.x-k8s.io,resources=clusteraddons,verbs=get;list;watch;create;update;patch;delete @@ -207,6 +213,8 @@ func (r *ClusterAddonReconciler) Reconcile(ctx context.Context, req reconcile.Re return reconcile.Result{}, fmt.Errorf("failed to get cluster addon config path: %w", err) } + logger := log.FromContext(ctx) + // Check whether current Helm chart has been applied in the workload cluster. If not, then we need to apply the helm chart (again). // the spec.clusterStack is only set after a Helm chart from a ClusterStack has been applied successfully. // If it is not set, the Helm chart has never been applied. @@ -270,6 +278,31 @@ func (r *ClusterAddonReconciler) Reconcile(ctx context.Context, req reconcile.Re return ctrl.Result{}, nil } else { + in.addonStagesInput, err = r.getAddonStagesInput(clusterAddon, in.restConfig, in.clusterAddonChartPath) + if err != nil { + return reconcile.Result{}, fmt.Errorf("failed to get addon stages input: %w", err) + } + + if clusterAddon.Spec.ClusterStack != "" { + oldClusterStackAddonChartPath, requeue, err := r.downloadOldClusterStackRelease(ctx, clusterAddon, logger) + if err != nil { + return reconcile.Result{}, fmt.Errorf("failed to download old cluster stack releases: %w", err) + } + if requeue { + return reconcile.Result{RequeueAfter: 10 * time.Second}, nil + } + + // src - /tmp/cluster-stacks/docker-ferrol-1-27-v1/docker-ferrol-1-27-cluster-addon-v1.tgz + // dst - /tmp/cluster-stacks/docker-ferrol-1-27-v1/docker-ferrol-1-27-cluster-addon-v1/ + in.oldDestinationClusterAddonChartDir = strings.TrimSuffix(oldClusterStackAddonChartPath, ".tgz") + + logger.Info("old cluster stack's cluster addon chart path", "path", in.oldDestinationClusterAddonChartDir) + + if err := unTarContent(oldClusterStackAddonChartPath, in.oldDestinationClusterAddonChartDir); err != nil { + return reconcile.Result{}, fmt.Errorf("failed to untar cluster addon chart: %q: %w", oldClusterStackAddonChartPath, err) + } + } + if clusterAddon.Spec.Hook != clusterAddon.Status.CurrentHook { clusterAddon.Status.HelmChartStatus = make(map[string]csov1alpha1.HelmChartStatusConditions) clusterAddon.Status.CurrentHook = clusterAddon.Spec.Hook @@ -297,11 +330,6 @@ func (r *ClusterAddonReconciler) Reconcile(ctx context.Context, req reconcile.Re return reconcile.Result{}, nil } - in.addonStagesInput, err = getAddonStagesInput(r, in.restConfig, in.clusterAddonChartPath) - if err != nil { - return reconcile.Result{}, fmt.Errorf("failed to get addon stages input: %w", err) - } - // clusteraddon.yaml in the release. clusterAddonConfig, err := clusteraddon.ParseClusterAddonConfig(in.clusterAddonConfigPath) if err != nil { @@ -394,14 +422,15 @@ type templateAndApplyClusterAddonInput struct { } type addonStagesInput struct { - kubeClient kube.Client - dynamicClient *dynamic.DynamicClient - discoverClient *discovery.DiscoveryClient - chartMap map[string]os.DirEntry - destinationClusterAddonChartDir string + kubeClient kube.Client + dynamicClient *dynamic.DynamicClient + discoverClient *discovery.DiscoveryClient + chartMap map[string]os.DirEntry + newDestinationClusterAddonChartDir string + oldDestinationClusterAddonChartDir string } -func getAddonStagesInput(r *ClusterAddonReconciler, restConfig *rest.Config, clusterAddonChart string) (addonStagesInput, error) { +func (r *ClusterAddonReconciler) getAddonStagesInput(clusterAddon *csov1alpha1.ClusterAddon, restConfig *rest.Config, clusterAddonChart string) (addonStagesInput, error) { var ( addonStages addonStagesInput err error @@ -420,15 +449,15 @@ func getAddonStagesInput(r *ClusterAddonReconciler, restConfig *rest.Config, clu // src - /tmp/cluster-stacks/docker-ferrol1-27-v1/docker-ferrol-27-cluster-addon-v1.tgz // dst - /tmp/cluster-stacks/docker-ferrol-1-27-v1/docker-ferrol-1-27-cluster-addon-v1/ - addonStages.destinationClusterAddonChartDir = strings.TrimSuffix(clusterAddonChart, ".tgz") - if err := unTarContent(clusterAddonChart, addonStages.destinationClusterAddonChartDir); err != nil { + addonStages.newDestinationClusterAddonChartDir = strings.TrimSuffix(clusterAddonChart, ".tgz") + if err := unTarContent(clusterAddonChart, addonStages.newDestinationClusterAddonChartDir); err != nil { return addonStagesInput{}, fmt.Errorf("failed to untar cluster addon chart: %q: %w", clusterAddonChart, err) } // Read all the helm charts in the un-tared cluster addon. - subDirs, err := os.ReadDir(addonStages.destinationClusterAddonChartDir) + subDirs, err := os.ReadDir(addonStages.newDestinationClusterAddonChartDir) if err != nil { - return addonStagesInput{}, fmt.Errorf("failed to read directories inside: %q: %w", addonStages.destinationClusterAddonChartDir, err) + return addonStagesInput{}, fmt.Errorf("failed to read directories inside: %q: %w", addonStages.newDestinationClusterAddonChartDir, err) } // Create a map for faster lookup @@ -468,9 +497,7 @@ func (r *ClusterAddonReconciler) templateAndApplyClusterAddonHelmChart(ctx conte func (r *ClusterAddonReconciler) executeStage(ctx context.Context, stage clusteraddon.Stage, in templateAndApplyClusterAddonInput) (bool, error) { var ( - newResources []*csov1alpha1.Resource shouldRequeue bool - buildTemplate []byte err error ) @@ -516,7 +543,7 @@ check: case csov1alpha1.ApplyingOrDeleting: if stage.Action == clusteraddon.Apply { - newResources, shouldRequeue, err = helmTemplateAndApply(ctx, in.kubeClient, in, stage.HelmChartName, buildTemplate, false) + shouldRequeue, err = helmTemplateAndApplyNewClusterStack(ctx, in, stage.HelmChartName) if err != nil { return false, fmt.Errorf("failed to helm template and apply: %w", err) } @@ -531,12 +558,13 @@ check: return true, nil } + in.clusterAddon.Status.HelmChartStatus[stage.HelmChartName] = csov1alpha1.WaitingForPostCondition goto check } else { // Delete part - newResources, shouldRequeue, err = helmTemplateAndDelete(ctx, in, stage.HelmChartName, buildTemplate) + shouldRequeue, err = helmTemplateAndDeleteNewClusterStack(ctx, in, stage.HelmChartName) if err != nil { return false, fmt.Errorf("failed to delete helm chart: %w", err) } @@ -571,20 +599,154 @@ check: return true, nil } - return false, fmt.Errorf("failed to get dynamic resource and evaluate cel expression for pre condition: %w", err) + return false, fmt.Errorf("failed to get dynamic resource and evaluate cel expression for post condition: %w", err) } } in.clusterAddon.Status.HelmChartStatus[stage.HelmChartName] = csov1alpha1.Done } - in.clusterAddon.Status.Resources = append(in.clusterAddon.Status.Resources, newResources...) - return false, nil } +// downloadOldClusterStackRelease downloads the old cluster stack if not present and returns release clusterAddon chart path if requeue and error. +func (r *ClusterAddonReconciler) downloadOldClusterStackRelease(ctx context.Context, clusterAddon *csov1alpha1.ClusterAddon, logger logr.Logger) (string, bool, error) { + // initiate github release. + gc, err := r.GitHubClientFactory.NewClient(ctx) + if err != nil { + isSet := conditions.IsFalse(clusterAddon, csov1alpha1.GitAPIAvailableCondition) + conditions.MarkFalse(clusterAddon, + csov1alpha1.GitAPIAvailableCondition, + csov1alpha1.FailedCreateGithubClientReason, + clusterv1.ConditionSeverityError, + err.Error(), + ) + record.Warnf(clusterAddon, "FailedCreateGithubClient", err.Error()) + + // give the github client a second change + if isSet { + return "", true, nil + } + return "", false, nil + } + + conditions.MarkTrue(clusterAddon, csov1alpha1.GitAPIAvailableCondition) + logger.Info("github client initialized") + + // check if old cluster stack release is present or not. + releaseAsset, download, err := release.New(release.ConvertFromClusterClassToClusterStackFormat(clusterAddon.Spec.ClusterStack), r.ReleaseDirectory) + if err != nil { + conditions.MarkFalse(clusterAddon, csov1alpha1.ClusterStackReleaseAssetsReadyCondition, csov1alpha1.IssueWithReleaseAssetsReason, clusterv1.ConditionSeverityError, err.Error()) + return "", true, nil + } + if download { + logger.Info("the old cluster stack is not present", "clusterstack", clusterAddon.Spec.ClusterStack) + // if download is true, it means that the release assets have not been downloaded yet + + conditions.MarkFalse(clusterAddon, csov1alpha1.ClusterStackReleaseAssetsReadyCondition, csov1alpha1.ReleaseAssetsNotDownloadedYetReason, clusterv1.ConditionSeverityInfo, "assets not downloaded yet") + + // this is the point where we download the release from github + // acquire lock so that only one reconcile loop can download the release + r.clusterStackRelDownloadDirectoryMutex.Lock() + + if err := downloadReleaseAssets(ctx, release.ConvertFromClusterClassToClusterStackFormat(clusterAddon.Spec.ClusterStack), releaseAsset.LocalDownloadPath, gc); err != nil { + return "", false, fmt.Errorf("failed to download release assets: %w", err) + } + + r.clusterStackRelDownloadDirectoryMutex.Unlock() + + // requeue to make sure release assets can be accessed + return "", true, nil + } + + if err := releaseAsset.CheckHelmCharts(); err != nil { + msg := fmt.Sprintf("failed to validate helm charts: %s", err.Error()) + conditions.MarkFalse( + clusterAddon, + csov1alpha1.ClusterStackReleaseAssetsReadyCondition, + csov1alpha1.IssueWithReleaseAssetsReason, + clusterv1.ConditionSeverityError, + msg, + ) + record.Warnf(clusterAddon, "ValidateHelmChartFailed", msg) + return "", false, nil + } + + // set downloaded condition if able to read metadata file + conditions.MarkTrue(clusterAddon, csov1alpha1.ClusterStackReleaseAssetsReadyCondition) + + return releaseAsset.ClusterAddonChartPath(), false, nil +} + +func helmTemplateAndApplyNewClusterStack(ctx context.Context, in templateAndApplyClusterAddonInput, helmChartName string) (bool, error) { + logger := log.FromContext(ctx) + + var ( + buildTemplate []byte + oldHelmTemplate []byte + err error + ) + + if in.oldDestinationClusterAddonChartDir != "" { + oldClusterStackSubDirPath := filepath.Join(in.oldDestinationClusterAddonChartDir, helmChartName) + oldHelmTemplate, err = helmTemplateClusterAddon(oldClusterStackSubDirPath, buildTemplate, true) + if err != nil { + return false, fmt.Errorf("failed to template old helm chart: %w", err) + } + logger.Info("oldClusterStackAddonChartPath v1", "path", oldClusterStackSubDirPath) + } + + newClusterStackSubDirPath := filepath.Join(in.newDestinationClusterAddonChartDir, helmChartName) + newHelmTemplate, err := helmTemplateClusterAddon(newClusterStackSubDirPath, buildTemplate, true) + if err != nil { + return false, fmt.Errorf("failed to template new helm chart: %w", err) + } + logger.Info("newClusterStackSubDirPath v1", "path", newClusterStackSubDirPath) + + shouldRequeue, err := in.kubeClient.ApplyNewClusterStack(ctx, oldHelmTemplate, newHelmTemplate) + if err != nil { + return false, fmt.Errorf("failed to apply objects from cluster addon Helm chart: %w", err) + } + + return shouldRequeue, nil +} + +func helmTemplateAndDeleteNewClusterStack(ctx context.Context, in templateAndApplyClusterAddonInput, helmChartName string) (bool, error) { + // logger := log.FromContext(ctx) + var ( + buildTemplate []byte + // oldHelmTemplate []byte + err error + ) + + // if in.oldDestinationClusterAddonChartDir != "" { + // oldClusterStackSubDirPath := filepath.Join(in.oldDestinationClusterAddonChartDir, helmChartName) + // oldHelmTemplate, err = helmTemplateClusterAddon(oldClusterStackSubDirPath, buildTemplate, true) + // if err != nil { + // return false, fmt.Errorf("failed to template old helm chart: %w", err) + // } + // logger.Info("oldClusterStackAddonChartPath v1", "path", oldClusterStackSubDirPath) + // } + + newClusterStackSubDirPath := filepath.Join(in.newDestinationClusterAddonChartDir, helmChartName) + newHelmTemplate, err := helmTemplateClusterAddon(newClusterStackSubDirPath, buildTemplate, true) + if err != nil { + return false, fmt.Errorf("failed to template new helm chart: %w", err) + } + // logger.Info("newClusterStackSubDirPath v1", "path", newClusterStackSubDirPath) + + shouldRequeue, err := in.kubeClient.DeleteNewClusterStack(ctx, newHelmTemplate) + if err != nil { + return false, fmt.Errorf("failed to delete objects from cluster addon Helm chart: %w", err) + } + + return shouldRequeue, nil +} + func helmTemplateAndApply(ctx context.Context, kubeClient kube.Client, in templateAndApplyClusterAddonInput, helmChartName string, buildTemplate []byte, shouldDelete bool) ([]*csov1alpha1.Resource, bool, error) { - subDirPath := filepath.Join(in.destinationClusterAddonChartDir, helmChartName) + subDirPath := filepath.Join(in.newDestinationClusterAddonChartDir, helmChartName) + loggger := log.FromContext(ctx) + loggger.Info("path of the subdir", "path", subDirPath) helmTemplate, err := helmTemplateClusterAddon(subDirPath, buildTemplate, true) if err != nil { return nil, false, fmt.Errorf("failed to template helm chart: %w", err) @@ -599,7 +761,7 @@ func helmTemplateAndApply(ctx context.Context, kubeClient kube.Client, in templa } func helmTemplateAndDelete(ctx context.Context, in templateAndApplyClusterAddonInput, helmChartName string, buildTemplate []byte) ([]*csov1alpha1.Resource, bool, error) { - subDirPath := filepath.Join(in.destinationClusterAddonChartDir, helmChartName) + subDirPath := filepath.Join(in.newDestinationClusterAddonChartDir, helmChartName) helmTemplate, err := helmTemplateClusterAddon(subDirPath, buildTemplate, true) if err != nil { diff --git a/pkg/kube/fake/kube.go b/pkg/kube/fake/kube.go new file mode 100644 index 000000000..de4f94cf6 --- /dev/null +++ b/pkg/kube/fake/kube.go @@ -0,0 +1,59 @@ +/* +Copyright 2023 The Kubernetes Authors. + +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 fake implements important interface like kube client. +package fake + +import ( + "context" + + csov1alpha1 "github.com/SovereignCloudStack/cluster-stack-operator/api/v1alpha1" + kubeclient "github.com/SovereignCloudStack/cluster-stack-operator/pkg/kube" + "k8s.io/client-go/rest" +) + +// kube is the struct for kube client. +type kube struct{} + +type factory struct{} + +// NewClient gives reference to the fake yaml client. +func (*factory) NewClient(_ string, _ *rest.Config) kubeclient.Client { + return &kube{} +} + +// NewFactory creates new fake kube client factories. +func NewFactory() kubeclient.Factory { + return &factory{} +} + +// Apply applies the given yaml object. +func (*kube) Apply(_ context.Context, _ []byte, _ []*csov1alpha1.Resource, _ bool) (_ []*csov1alpha1.Resource, _ bool, _ error) { + return nil, false, nil +} + +// Delete deletes the given yaml object. +func (*kube) Delete(_ context.Context, _ []byte, _ []*csov1alpha1.Resource) (_ []*csov1alpha1.Resource, _ bool, _ error) { + return nil, false, nil +} + +func (*kube) ApplyNewClusterStack(_ context.Context, _, _ []byte) (_ bool, _ error) { + return false, nil +} + +func (*kube) DeleteNewClusterStack(_ context.Context, _ []byte) (_ bool, _ error) { + return false, nil +} diff --git a/pkg/kube/helpers.go b/pkg/kube/helpers.go index e0fcfbdff..2ed87b32c 100644 --- a/pkg/kube/helpers.go +++ b/pkg/kube/helpers.go @@ -114,6 +114,16 @@ func getResourceMap(resources []*csov1alpha1.Resource) map[types.NamespacedName] return resourceMap } +func getResourceMapOfUnstructuredObjects(objects []*unstructured.Unstructured) map[types.NamespacedName]*unstructured.Unstructured { + objectMap := make(map[types.NamespacedName]*unstructured.Unstructured) + + for i, object := range objects { + objectMap[types.NamespacedName{Name: object.GetName(), Namespace: object.GetNamespace()}] = objects[i] + } + + return objectMap +} + func setLabel(target *unstructured.Unstructured, key, val string) error { labels, _, err := unstructured.NestedStringMap(target.Object, "metadata", "labels") if err != nil { @@ -235,6 +245,29 @@ func resourcesToBeDeleted(oldResources []*csov1alpha1.Resource, currentObjs []*u return toBeDeleted } +func resourcesToBeDeletedFromUnstructuredObjects(oldObjects, newObjects []*unstructured.Unstructured) []*unstructured.Unstructured { + toBeDeleted := make([]*unstructured.Unstructured, 0, len(oldObjects)) + + newObjectMap := make(map[types.NamespacedName]struct{}) + for _, newObj := range newObjects { + newObjectMap[types.NamespacedName{Name: newObj.GetName(), Namespace: newObj.GetNamespace()}] = struct{}{} + } + + for i, oldObj := range oldObjects { + nameSpacedName := types.NamespacedName{ + Name: oldObj.GetName(), + Namespace: oldObj.GetNamespace(), + } + + // delete resources that are not listed in the new objects anymore + if _, found := newObjectMap[nameSpacedName]; !found { + toBeDeleted = append(toBeDeleted, oldObjects[i]) + } + } + + return toBeDeleted +} + func deleteObject(kubeClientset kubernetes.Interface, namespace string, restConfig *rest.Config, obj runtime.Object) error { // Create a REST mapper that tracks information about the available resources in the cluster. groupResources, err := restmapper.GetAPIGroupResources(kubeClientset.Discovery()) diff --git a/pkg/kube/kube.go b/pkg/kube/kube.go index a5d5bba83..19807435b 100644 --- a/pkg/kube/kube.go +++ b/pkg/kube/kube.go @@ -39,6 +39,9 @@ type kube struct { type Client interface { Apply(ctx context.Context, template []byte, oldResources []*csov1alpha1.Resource, shouldDelete bool) (newResources []*csov1alpha1.Resource, shouldRequeue bool, err error) Delete(ctx context.Context, template []byte, oldResources []*csov1alpha1.Resource) (newResources []*csov1alpha1.Resource, shouldRequeue bool, err error) + + ApplyNewClusterStack(ctx context.Context, oldTemplate, newTemplate []byte) (shouldRequeue bool, err error) + DeleteNewClusterStack(ctx context.Context, template []byte) (shouldRequeue bool, err error) } // Factory creates new fake kube client factories. @@ -64,6 +67,108 @@ func (*factory) NewClient(namespace string, resCfg *rest.Config) Client { } } +func (k *kube) ApplyNewClusterStack(ctx context.Context, oldTemplate, newTemplate []byte) (shouldRequeue bool, err error) { + logger := log.FromContext(ctx) + + oldObjects, err := parseK8sYaml(oldTemplate) + if err != nil { + return false, fmt.Errorf("failed to parse old cluster stack template: %w", err) + } + logger.Info("oldObjects value", "val", oldObjects) + + newObjects, err := parseK8sYaml(newTemplate) + if err != nil { + return false, fmt.Errorf("failed to parse new cluster stack template: %w", err) + } + + // oldObjectMap := getResourceMapOfUnstructuredObjects(oldObjects) + for _, newObject := range newObjects { + // do nothing if found + // if _, found := oldObjectMap[types.NamespacedName{Name: newObject.GetName(), Namespace: newObject.GetNamespace()}]; found { + // continue + // } + + logger.Info("object to be applied", "object", newObject.GetName(), "kind", newObject.GetKind()) + + if err := setLabel(newObject, ObjectLabelKeyOwned, ObjectLabelValueOwned); err != nil { + return false, fmt.Errorf("error setting label: %w", err) + } + + // call the function and get dynamic.ResourceInterface + // getDynamicResourceInterface + dr, err := getDynamicResourceInterface(k.Namespace, k.RestConfig, newObject.GroupVersionKind()) + if err != nil { + reterr := fmt.Errorf("failed to get dynamic resource interface: %w", err) + logger.Error(reterr, "failed to get dynamic resource interface", "obj", newObject.GetObjectKind().GroupVersionKind()) + shouldRequeue = true + continue + } + + if _, err := dr.Apply(ctx, newObject.GetName(), newObject, metav1.ApplyOptions{FieldManager: "kubectl", Force: true}); err != nil { + reterr := fmt.Errorf("failed to apply object: %w", err) + logger.Error(reterr, "failed to apply object", "obj", newObject.GetObjectKind().GroupVersionKind(), "name", newObject.GetName(), "namespace", newObject.GetNamespace()) + shouldRequeue = true + } + } + + for _, object := range resourcesToBeDeletedFromUnstructuredObjects(oldObjects, newObjects) { + logger.Info("resource are being deleted", "kind", object.GetKind(), "name", object.GetName(), "namespace", object.GetNamespace()) + + dr, err := getDynamicResourceInterface(k.Namespace, k.RestConfig, object.GroupVersionKind()) + if err != nil { + return false, fmt.Errorf("failed to get dynamic resource interface: %w", err) + } + + if err := dr.Delete(ctx, object.GetName(), metav1.DeleteOptions{}); err != nil && !apierrors.IsNotFound(err) { + reterr := fmt.Errorf("failed to delete object: %w", err) + logger.Error(reterr, "failed to delete object", "obj", object.GroupVersionKind(), "namespacedName", fmt.Sprintf("%s/%s", object.GetNamespace(), object.GetName())) + // append resource to status and requeue again to be able to retry deletion + shouldRequeue = true + } + } + + return shouldRequeue, nil +} + +func (k *kube) DeleteNewClusterStack(ctx context.Context, template []byte) (shouldRequeue bool, err error) { + logger := log.FromContext(ctx) + + // oldObjects, err := parseK8sYaml(oldTemplate) + // if err != nil { + // return false, fmt.Errorf("failed to parse old cluster stack template: %w", err) + // } + + objects, err := parseK8sYaml(template) + if err != nil { + return false, fmt.Errorf("failed to parse new cluster stack template: %w", err) + } + + // oldObjectMap := getResourceMapOfUnstructuredObjects(objects) + for _, object := range objects { + // do nothing if synced + // if _, found := oldObjectMap[types.NamespacedName{Name: newObject.GetName(), Namespace: newObject.GetNamespace()}]; found { + // continue + // } + + logger.Info("object to be deleted", "object", object.GetName(), "kind", object.GetKind()) + + if err := setLabel(object, ObjectLabelKeyOwned, ObjectLabelValueOwned); err != nil { + return false, fmt.Errorf("error setting label: %w", err) + } + + dr, err := getDynamicResourceInterface(k.Namespace, k.RestConfig, object.GroupVersionKind()) + if err != nil { + return false, fmt.Errorf("failed to get dynamic resource interface: %w", err) + } + + if err := dr.Delete(ctx, object.GetName(), metav1.DeleteOptions{}); err != nil { + return true, fmt.Errorf("failed to delete object %q: %w", object.GetObjectKind().GroupVersionKind(), err) + } + } + + return shouldRequeue, nil +} + func (k *kube) Apply(ctx context.Context, template []byte, oldResources []*csov1alpha1.Resource, shouldDelete bool) (newResources []*csov1alpha1.Resource, shouldRequeue bool, err error) { logger := log.FromContext(ctx) diff --git a/pkg/kube/mocks/Client.go b/pkg/kube/mocks/Client.go index 971667332..07bca7f13 100644 --- a/pkg/kube/mocks/Client.go +++ b/pkg/kube/mocks/Client.go @@ -15,18 +15,18 @@ type Client struct { mock.Mock } -// Apply provides a mock function with given fields: ctx, template, oldResources, delete -func (_m *Client) Apply(ctx context.Context, template []byte, oldResources []*v1alpha1.Resource, delete bool) ([]*v1alpha1.Resource, bool, error) { - ret := _m.Called(ctx, template, oldResources, delete) +// Apply provides a mock function with given fields: ctx, template, oldResources, shouldDelete +func (_m *Client) Apply(ctx context.Context, template []byte, oldResources []*v1alpha1.Resource, shouldDelete bool) ([]*v1alpha1.Resource, bool, error) { + ret := _m.Called(ctx, template, oldResources, shouldDelete) var r0 []*v1alpha1.Resource var r1 bool var r2 error if rf, ok := ret.Get(0).(func(context.Context, []byte, []*v1alpha1.Resource, bool) ([]*v1alpha1.Resource, bool, error)); ok { - return rf(ctx, template, oldResources, delete) + return rf(ctx, template, oldResources, shouldDelete) } if rf, ok := ret.Get(0).(func(context.Context, []byte, []*v1alpha1.Resource, bool) []*v1alpha1.Resource); ok { - r0 = rf(ctx, template, oldResources, delete) + r0 = rf(ctx, template, oldResources, shouldDelete) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]*v1alpha1.Resource) @@ -34,13 +34,13 @@ func (_m *Client) Apply(ctx context.Context, template []byte, oldResources []*v1 } if rf, ok := ret.Get(1).(func(context.Context, []byte, []*v1alpha1.Resource, bool) bool); ok { - r1 = rf(ctx, template, oldResources, delete) + r1 = rf(ctx, template, oldResources, shouldDelete) } else { r1 = ret.Get(1).(bool) } if rf, ok := ret.Get(2).(func(context.Context, []byte, []*v1alpha1.Resource, bool) error); ok { - r2 = rf(ctx, template, oldResources, delete) + r2 = rf(ctx, template, oldResources, shouldDelete) } else { r2 = ret.Error(2) } @@ -48,6 +48,30 @@ func (_m *Client) Apply(ctx context.Context, template []byte, oldResources []*v1 return r0, r1, r2 } +// ApplyNewClusterStack provides a mock function with given fields: ctx, oldTemplate, newTemplate +func (_m *Client) ApplyNewClusterStack(ctx context.Context, oldTemplate []byte, newTemplate []byte) (bool, error) { + ret := _m.Called(ctx, oldTemplate, newTemplate) + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []byte, []byte) (bool, error)); ok { + return rf(ctx, oldTemplate, newTemplate) + } + if rf, ok := ret.Get(0).(func(context.Context, []byte, []byte) bool); ok { + r0 = rf(ctx, oldTemplate, newTemplate) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context, []byte, []byte) error); ok { + r1 = rf(ctx, oldTemplate, newTemplate) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // Delete provides a mock function with given fields: ctx, template, oldResources func (_m *Client) Delete(ctx context.Context, template []byte, oldResources []*v1alpha1.Resource) ([]*v1alpha1.Resource, bool, error) { ret := _m.Called(ctx, template, oldResources) @@ -81,6 +105,30 @@ func (_m *Client) Delete(ctx context.Context, template []byte, oldResources []*v return r0, r1, r2 } +// DeleteNewClusterStack provides a mock function with given fields: ctx, template +func (_m *Client) DeleteNewClusterStack(ctx context.Context, template []byte) (bool, error) { + ret := _m.Called(ctx, template) + + var r0 bool + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []byte) (bool, error)); ok { + return rf(ctx, template) + } + if rf, ok := ret.Get(0).(func(context.Context, []byte) bool); ok { + r0 = rf(ctx, template) + } else { + r0 = ret.Get(0).(bool) + } + + if rf, ok := ret.Get(1).(func(context.Context, []byte) error); ok { + r1 = rf(ctx, template) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // NewClient creates a new instance of Client. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. // The first argument is typically a *testing.T value. func NewClient(t interface { diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-addon/cni/Chart.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/cni/Chart.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-addon/cni/Chart.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/cni/Chart.yaml diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-addon/cni/templates/cni.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/cni/templates/cni.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-addon/cni/templates/cni.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/cni/templates/cni.yaml diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-addon/cni/values.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/cni/values.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-addon/cni/values.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/cni/values.yaml diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-addon/metrics-server/.helmignore b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/.helmignore similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-addon/metrics-server/.helmignore rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/.helmignore diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.lock b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.lock similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.lock rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.lock diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.yaml diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-addon/metrics-server/charts/metrics-server-3.11.0.tgz b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/charts/metrics-server-3.11.0.tgz similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-addon/metrics-server/charts/metrics-server-3.11.0.tgz rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/charts/metrics-server-3.11.0.tgz diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-addon/metrics-server/overwrite.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/overwrite.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-addon/metrics-server/overwrite.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/overwrite.yaml diff --git a/test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/templates/ngnix.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/templates/ngnix.yaml new file mode 100644 index 000000000..594cb5f6c --- /dev/null +++ b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/templates/ngnix.yaml @@ -0,0 +1,101 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: release-name-ngnix-7777 + namespace: "kube-system" + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ngnix + app.kubernetes.io/version: 1.25.3 + helm.sh/chart: ngnix-15.10.1 +spec: + replicas: 1 + revisionHistoryLimit: 10 + strategy: + rollingUpdate: {} + type: RollingUpdate + selector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: ngnix + template: + metadata: + labels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: ngnix + app.kubernetes.io/version: 1.25.3 + helm.sh/chart: ngnix-15.10.1 + annotations: + spec: + + shareProcessNamespace: false + serviceAccountName: release-name-ngnix + automountServiceAccountToken: false + affinity: + podAffinity: + + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/instance: release-name + app.kubernetes.io/name: ngnix + topologyKey: kubernetes.io/hostname + weight: 1 + nodeAffinity: + + hostNetwork: false + hostIPC: false + securityContext: + fsGroup: 1001 + fsGroupChangePolicy: Always + supplementalGroups: [] + sysctls: [] + containers: + - name: nginx + image: docker.io/bitnami/nginx:1.25.3-debian-11-r6 + imagePullPolicy: "IfNotPresent" + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + privileged: false + readOnlyRootFilesystem: false + runAsNonRoot: true + runAsUser: 1001 + seccompProfile: + type: RuntimeDefault + env: + - name: BITNAMI_DEBUG + value: "false" + - name: NGINX_HTTP_PORT_NUMBER + value: "8080" + envFrom: + ports: + - name: http + containerPort: 8080 + livenessProbe: + failureThreshold: 6 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + tcpSocket: + port: http + readinessProbe: + failureThreshold: 3 + initialDelaySeconds: 5 + periodSeconds: 5 + successThreshold: 1 + timeoutSeconds: 3 + tcpSocket: + port: http + resources: + limits: {} + requests: {} + volumeMounts: + volumes: diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-addon/metrics-server/values.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/values.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-addon/metrics-server/values.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-addon/metrics-server/values.yaml diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-addon/ngnix/.helmignore b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/.helmignore similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-addon/ngnix/.helmignore rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/.helmignore diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-class/Chart.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/Chart.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-class/Chart.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/Chart.yaml diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-class/templates/_helpers.tpl b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/templates/_helpers.tpl similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-class/templates/_helpers.tpl rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/templates/_helpers.tpl diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-class/templates/cluster-class.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/templates/cluster-class.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-class/templates/cluster-class.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/templates/cluster-class.yaml diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-class/templates/docker-cluster-template.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/templates/docker-cluster-template.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-class/templates/docker-cluster-template.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/templates/docker-cluster-template.yaml diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-class/templates/docker-machine-template.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/templates/docker-machine-template.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-class/templates/docker-machine-template.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/templates/docker-machine-template.yaml diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-class/templates/kubeadm-config-template-worker-docker.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/templates/kubeadm-config-template-worker-docker.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-class/templates/kubeadm-config-template-worker-docker.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/templates/kubeadm-config-template-worker-docker.yaml diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-class/templates/kubeadm-control-plane-template.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/templates/kubeadm-control-plane-template.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-class/templates/kubeadm-control-plane-template.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/templates/kubeadm-control-plane-template.yaml diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-class/values.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/values.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-class/values.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/cluster-class/values.yaml diff --git a/test/cluster-stacks/docker/ferrol/1-27/clusteraddon.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/clusteraddon.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/clusteraddon.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/clusteraddon.yaml diff --git a/test/cluster-stacks/1/docker/ferrol/1-27/csmctl.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/csmctl.yaml new file mode 100644 index 000000000..6b20cf03b --- /dev/null +++ b/test/cluster-stacks/1/docker/ferrol/1-27/csmctl.yaml @@ -0,0 +1,7 @@ +apiVersion: csmctl.clusterstack.x-k8s.io/v1alpha1 +config: + kubernetesVersion: v1.27.6 + clusterStackName: ferrol + provider: + type: docker + apiVersion: docker.csmctl.clusterstack.x-k8s.io/v1alpha1 diff --git a/test/cluster-stacks/docker/ferrol/1-27/node-image/Dockerfile.controlplane b/test/cluster-stacks/1/docker/ferrol/1-27/node-image/Dockerfile.controlplane similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/node-image/Dockerfile.controlplane rename to test/cluster-stacks/1/docker/ferrol/1-27/node-image/Dockerfile.controlplane diff --git a/test/cluster-stacks/docker/ferrol/1-27/node-image/Dockerfile.worker b/test/cluster-stacks/1/docker/ferrol/1-27/node-image/Dockerfile.worker similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/node-image/Dockerfile.worker rename to test/cluster-stacks/1/docker/ferrol/1-27/node-image/Dockerfile.worker diff --git a/test/cluster-stacks/docker/ferrol/1-27/node-image/scripts/base.sh b/test/cluster-stacks/1/docker/ferrol/1-27/node-image/scripts/base.sh similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/node-image/scripts/base.sh rename to test/cluster-stacks/1/docker/ferrol/1-27/node-image/scripts/base.sh diff --git a/test/cluster-stacks/docker/ferrol/1-27/node-images.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/node-images.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/node-images.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/node-images.yaml diff --git a/test/cluster-stacks/docker/ferrol/1-27/topology-docker.yaml b/test/cluster-stacks/1/docker/ferrol/1-27/topology-docker.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/topology-docker.yaml rename to test/cluster-stacks/1/docker/ferrol/1-27/topology-docker.yaml diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/cni/Chart.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/cni/Chart.yaml new file mode 100644 index 000000000..f04b67a8d --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/cni/Chart.yaml @@ -0,0 +1,9 @@ +apiVersion: v2 +type: application +description: CNI chart for kind +name: CNI +version: '0' +maintainers: + - name: Syself + email: info@syself.com + url: https://github.com/syself diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/cni/templates/cni.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/cni/templates/cni.yaml new file mode 100644 index 000000000..fbe82f541 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/cni/templates/cni.yaml @@ -0,0 +1,120 @@ +# kindnetd networking manifest +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: kindnet + name: kindnet + name: kindnet +rules: + - apiGroups: + - "" + resources: + - nodes + verbs: + - list + - watch + - patch + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: kindnet +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: kindnet +subjects: + - kind: ServiceAccount + name: kindnet + namespace: kube-system +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: kindnet + namespace: kube-system +--- +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: kindnet + namespace: kube-system + labels: + tier: node + app: kindnet + k8s-app: kindnet +spec: + selector: + matchLabels: + app: kindnet + template: + metadata: + labels: + tier: node + app: kindnet + k8s-app: kindnet + spec: + hostNetwork: true + tolerations: + - operator: Exists + effect: NoSchedule + serviceAccountName: kindnet + containers: + - name: kindnet-cni + image: kindest/kindnetd:v20230511-dc714da8 + env: + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + # We're using the dualstack CIDRs here. The order doesn't matter for kindnet as the loops are run concurrently. + # REF: https://github.com/kubernetes-sigs/kind/blob/3dbeb894e3092a336ab4278d3823e73a1d66aff7/images/kindnetd/cmd/kindnetd/main.go#L149-L175 + - name: POD_SUBNET + value: '${DOCKER_POD_CIDRS},${DOCKER_POD_IPV6_CIDRS}' + volumeMounts: + - name: cni-cfg + mountPath: /etc/cni/net.d + - name: xtables-lock + mountPath: /run/xtables.lock + readOnly: false + - name: lib-modules + mountPath: /lib/modules + readOnly: true + resources: + requests: + cpu: "100m" + memory: "50Mi" + limits: + cpu: "100m" + memory: "50Mi" + securityContext: + privileged: false + capabilities: + add: ["NET_RAW", "NET_ADMIN"] + volumes: + - name: cni-bin + hostPath: + path: /opt/cni/bin + type: DirectoryOrCreate + - name: cni-cfg + hostPath: + path: /etc/cni/net.d + type: DirectoryOrCreate + - name: xtables-lock + hostPath: + path: /run/xtables.lock + type: FileOrCreate + - name: lib-modules + hostPath: + path: /lib/modules diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/cni/values.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/cni/values.yaml new file mode 100644 index 000000000..e69de29bb diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-class/.helmignore b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/.helmignore similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-class/.helmignore rename to test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/.helmignore diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.lock b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.lock new file mode 100644 index 000000000..dcf1105c2 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: metrics-server + repository: https://kubernetes-sigs.github.io/metrics-server/ + version: 3.11.0 +digest: sha256:d92caa34d06b047b0390aa33a6f5d15d4fe0566143625204ebbbc69085133c4e +generated: "2024-01-08T18:57:56.42493498+05:30" diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.yaml new file mode 100644 index 000000000..1079e6f15 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/Chart.yaml @@ -0,0 +1,16 @@ +apiVersion: v2 +type: application +description: | + This chart installs and configures: + * Docker Ferrol Cluster Class +name: docker-ferrol-1-27-cluster-addon +version: << .ClusterAddonVersion >> +maintainers: + - name: Syself + email: info@syself.com + url: https://github.com/syself +dependencies: + - name: "metrics-server" + version: "3.11.0" + repository: "https://kubernetes-sigs.github.io/metrics-server/" + alias: "metrics-server" diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/charts/metrics-server-3.11.0.tgz b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/charts/metrics-server-3.11.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8860457ec1efe286aefd1237d6a403256c933800 GIT binary patch literal 8462 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 literal 0 HcmV?d00001 diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/overwrite.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/overwrite.yaml new file mode 100644 index 000000000..30a4ded93 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/overwrite.yaml @@ -0,0 +1,4 @@ +metrics-server: + commonLabels: + domain: "{{ .Cluster.spec.controlPlaneEndpoint.host }}" + clusterAddonVersion: "v2" diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/values.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/values.yaml new file mode 100644 index 000000000..17847d617 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/metrics-server/values.yaml @@ -0,0 +1,44 @@ +metrics-server: + fullnameOverride: metrics-server + replicas: 1 + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 0 + maxUnavailable: 1 + + podDisruptionBudget: + apiVersion: policy/v1 + enabled: true + minAvailable: 1 + + tolerations: + - key: node-role.kubernetes.io/master + effect: NoSchedule + - key: CriticalAddonsOnly + operator: Exists + + service: + labels: + kubernetes.io/cluster-service: "true" + kubernetes.io/name: "metrics-server" + + defaultArgs: + - --cert-dir=/tmp + - --kubelet-preferred-address-types=ExternalIP,Hostname + - --kubelet-use-node-status-port + - --metric-resolution=15s + + args: + - --kubelet-insecure-tls + + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: app.kubernetes.io/name + operator: In + values: + - metrics-server + topologyKey: "kubernetes.io/hostname" diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/ngnix/.helmignore b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/ngnix/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/ngnix/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-addon/ngnix/Chart.lock b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/ngnix/Chart.lock similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-addon/ngnix/Chart.lock rename to test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/ngnix/Chart.lock diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-addon/ngnix/Chart.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/ngnix/Chart.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-addon/ngnix/Chart.yaml rename to test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/ngnix/Chart.yaml diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-addon/ngnix/charts/nginx-15.10.1.tgz b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/ngnix/charts/nginx-15.10.1.tgz similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-addon/ngnix/charts/nginx-15.10.1.tgz rename to test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/ngnix/charts/nginx-15.10.1.tgz diff --git a/test/cluster-stacks/docker/ferrol/1-27/cluster-addon/ngnix/values.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/ngnix/values.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/cluster-addon/ngnix/values.yaml rename to test/cluster-stacks/2/docker/ferrol/1-27/cluster-addon/ngnix/values.yaml diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/.helmignore b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/Chart.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/Chart.yaml new file mode 100644 index 000000000..233c13441 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/Chart.yaml @@ -0,0 +1,11 @@ +apiVersion: v2 +description: | + This chart installs and configures: + * Docker Ferrol Cluster Class +maintainers: + - name: Syself + email: info@syself.com + url: https://github.com/syself +name: docker-ferrol-1-27-cluster-class +type: application +version: << .ClusterAddonVersion >> diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/_helpers.tpl b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/_helpers.tpl new file mode 100644 index 000000000..2339c1256 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "cluster-class.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "cluster-class.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "cluster-class.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "cluster-class.labels" -}} +helm.sh/chart: {{ include "cluster-class.chart" . }} +{{ include "cluster-class.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "cluster-class.selectorLabels" -}} +app.kubernetes.io/name: {{ include "cluster-class.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "cluster-class.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "cluster-class.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/cluster-class.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/cluster-class.yaml new file mode 100644 index 000000000..3f6cb505a --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/cluster-class.yaml @@ -0,0 +1,101 @@ +apiVersion: cluster.x-k8s.io/v1beta1 +kind: ClusterClass +metadata: + name: {{ .Release.Name }}-{{ .Chart.Version }} + namespace: {{.Release.Namespace}} +spec: + controlPlane: + ref: + apiVersion: controlplane.cluster.x-k8s.io/v1beta1 + kind: KubeadmControlPlaneTemplate + name: {{ .Release.Name }}-{{ .Chart.Version }}-control-plane + namespace: {{ .Release.Namespace }} + machineInfrastructure: + ref: + kind: DockerMachineTemplate + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + name: {{ .Release.Name }}-{{ .Chart.Version }}-machinetemplate-docker + namespace: {{ .Release.Namespace }} + infrastructure: + ref: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: DockerClusterTemplate + name: {{ .Release.Name }}-{{ .Chart.Version }}-cluster + namespace: {{ .Release.Namespace }} + workers: + machineDeployments: + - class: workeramd64 + template: + bootstrap: + ref: + apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 + kind: KubeadmConfigTemplate + name: {{ .Release.Name }}-{{ .Chart.Version }}-worker-bootstraptemplate-docker + namespace: {{ .Release.Namespace }} + infrastructure: + ref: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: DockerMachineTemplate + name: {{ .Release.Name }}-{{ .Chart.Version }}-machinetemplate-docker + namespace: {{ .Release.Namespace }} + variables: + - name: imageRepository + required: true + schema: + openAPIV3Schema: + type: string + default: "" + example: "registry.k8s.io" + description: "imageRepository sets the container registry to pull images from. If empty, nothing will be set and the from of kubeadm will be used." + patches: + - name: imageRepository + description: "Sets the imageRepository used for the KubeadmControlPlane." + enabledIf: '{{ ne .imageRepository "" }}' + definitions: + - selector: + apiVersion: controlplane.cluster.x-k8s.io/v1beta1 + kind: KubeadmControlPlaneTemplate + matchResources: + controlPlane: true + jsonPatches: + - op: add + path: "/spec/template/spec/kubeadmConfigSpec/clusterConfiguration/imageRepository" + valueFrom: + variable: imageRepository + - name: customImage + description: "Sets the container image that is used for running dockerMachines for the controlplane and worker machineDeployments." + definitions: + - selector: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: DockerMachineTemplate + matchResources: + machineDeploymentClass: + names: + - workeramd64 + jsonPatches: + - op: add + path: "/spec/template/spec/customImage" + value: {{ (index .Values.images.controlPlane 0).name }} + - selector: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: DockerMachineTemplate + matchResources: + controlPlane: true + jsonPatches: + - op: add + path: "/spec/template/spec/customImage" + value: {{ (index .Values.images.controlPlane 0).name }} + - name: DockerMachineTemplateWorker + description: "Sets the container image that is used for running dockerMachines for the worker machineDeployments." + definitions: + - selector: + apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 + kind: DockerMachineTemplate + matchResources: + machineDeploymentClass: + names: + - workeramd64 + jsonPatches: + - op: add + path: "/spec/template/spec/customImage" + value: {{ (index .Values.images.worker 0).name }} diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/docker-cluster-template.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/docker-cluster-template.yaml new file mode 100644 index 000000000..0bdf7120d --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/docker-cluster-template.yaml @@ -0,0 +1,8 @@ +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: DockerClusterTemplate +metadata: + name: {{ .Release.Name }}-{{ .Chart.Version }}-cluster + namespace: {{ .Release.Namespace }} +spec: + template: + spec: {} diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/docker-machine-template.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/docker-machine-template.yaml new file mode 100644 index 000000000..bc4c6cc6c --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/docker-machine-template.yaml @@ -0,0 +1,11 @@ +apiVersion: infrastructure.cluster.x-k8s.io/v1beta1 +kind: DockerMachineTemplate +metadata: + name: {{ .Release.Name }}-{{ .Chart.Version }}-machinetemplate-docker + namespace: {{ .Release.Namespace }} +spec: + template: + spec: + extraMounts: + - containerPath: "/var/run/docker.sock" + hostPath: "/var/run/docker.sock" diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/kubeadm-config-template-worker-docker.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/kubeadm-config-template-worker-docker.yaml new file mode 100644 index 000000000..861ccec42 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/kubeadm-config-template-worker-docker.yaml @@ -0,0 +1,15 @@ +apiVersion: bootstrap.cluster.x-k8s.io/v1beta1 +kind: KubeadmConfigTemplate +metadata: + name: {{ .Release.Name }}-{{ .Chart.Version }}-worker-bootstraptemplate-docker + namespace: {{ .Release.Namespace }} +spec: + template: + spec: + joinConfiguration: + nodeRegistration: + # We have to set the criSocket to containerd as kubeadm defaults to docker runtime if both containerd and docker sockets are found + criSocket: unix:///var/run/containerd/containerd.sock + kubeletExtraArgs: + eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%' + fail-swap-on: "false" diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/kubeadm-control-plane-template.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/kubeadm-control-plane-template.yaml new file mode 100644 index 000000000..c76866e72 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/templates/kubeadm-control-plane-template.yaml @@ -0,0 +1,29 @@ +apiVersion: controlplane.cluster.x-k8s.io/v1beta1 +kind: KubeadmControlPlaneTemplate +metadata: + name: {{ .Release.Name }}-{{ .Chart.Version }}-control-plane + namespace: {{ .Release.Namespace }} +spec: + template: + spec: + kubeadmConfigSpec: + clusterConfiguration: + controllerManager: + extraArgs: { enable-hostpath-provisioner: 'true' } + apiServer: + # host.docker.internal is required by kubetest when running on MacOS because of the way ports are proxied. + certSANs: [localhost, 127.0.0.1, 0.0.0.0, host.docker.internal] + initConfiguration: + nodeRegistration: + # We have to set the criSocket to containerd as kubeadm defaults to docker runtime if both containerd and docker sockets are found + criSocket: unix:///var/run/containerd/containerd.sock + kubeletExtraArgs: + eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%' + fail-swap-on: "false" + joinConfiguration: + nodeRegistration: + # We have to set the criSocket to containerd as kubeadm defaults to docker runtime if both containerd and docker sockets are found + criSocket: unix:///var/run/containerd/containerd.sock + kubeletExtraArgs: + eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%' + fail-swap-on: "false" diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/values.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/values.yaml new file mode 100644 index 000000000..eb2bb4117 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/cluster-class/values.yaml @@ -0,0 +1,5 @@ +images: + controlPlane: + - name: ghcr.io/sovereigncloudstack/docker-ferrol-1-27-controlplaneamd64:v1 + worker: + - name: ghcr.io/sovereigncloudstack/docker-ferrol-1-27-workeramd64:v1 diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/clusteraddon.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/clusteraddon.yaml new file mode 100644 index 000000000..8f5753a04 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/clusteraddon.yaml @@ -0,0 +1,26 @@ +apiVersion: clusteraddonconfig.x-k8s.io/v1alpha1 +clusterAddonVersion: clusteraddons.clusterstack.x-k8s.io/v1alpha1 +addonStages: + AfterControlPlaneInitialized: + - helmChartName: cni + action: apply + - helmChartName: metrics-server + action: apply + BeforeClusterUpgrade: + - helmChartName: metrics-server + action: apply + - helmChartName: ngnix + action: apply + waitForPostCondition: + objects: + - key: msdeployment + apiVersion: apps/v1 + kind: Deployment + name: metrics-server + namespace: kube-system + - key: ngnix + apiVersion: apps/v1 + kind: Deployment + name: cluster-addon-ngnix + namespace: kube-system + conditions: msdeployment.spec.replicas == ngnix.spec.replicas diff --git a/test/cluster-stacks/docker/ferrol/1-27/csmctl.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/csmctl.yaml similarity index 100% rename from test/cluster-stacks/docker/ferrol/1-27/csmctl.yaml rename to test/cluster-stacks/2/docker/ferrol/1-27/csmctl.yaml diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/node-image/Dockerfile.controlplane b/test/cluster-stacks/2/docker/ferrol/1-27/node-image/Dockerfile.controlplane new file mode 100644 index 000000000..589301562 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/node-image/Dockerfile.controlplane @@ -0,0 +1,3 @@ +FROM kindest/node:v1.27.3 AS base +# This is an example. For a real infrastructure provider, you +# would have some scripts to create a custom machine image. \ No newline at end of file diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/node-image/Dockerfile.worker b/test/cluster-stacks/2/docker/ferrol/1-27/node-image/Dockerfile.worker new file mode 100644 index 000000000..d2ce96d6f --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/node-image/Dockerfile.worker @@ -0,0 +1,3 @@ +FROM kindest/node:v1.27.3 AS base +# This is an example. For a real infrastructure provider, you +# would have some scripts to create a custom machine image. diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/node-image/scripts/base.sh b/test/cluster-stacks/2/docker/ferrol/1-27/node-image/scripts/base.sh new file mode 100755 index 000000000..f74932578 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/node-image/scripts/base.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# Copyright 2024 The Kubernetes Authors. +# +# 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. + +set -o errexit +set -o nounset +set -o pipefail + +echo '--> Starting Base Installation.' +# Set locale +# localectl set-locale LANG=en_US.UTF-8 +# localectl set-locale LANGUAGE=en_US.UTF-8 + +# Suppress "WARNING: apt does not have a stable CLI interface. Use with caution in scripts." +echo 'Binary::apt::Apt::Cmd::Disable-Script-Warning "true";' >/etc/apt/apt.conf.d/disable-script-warning +export DEBIAN_FRONTEND=noninteractive + +# update all packages +apt update -y && apt -y upgrade && apt -y dist-upgrade + +# install basic tooling +apt -y install \ + at jq unzip wget socat mtr logrotate apt-transport-https network-manager + +# Install yq +YQ_VERSION=v4.30.5 #https://github.com/mikefarah/yq +YQ_BINARY=yq_linux_amd64 +wget -q https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/${YQ_BINARY} -O /usr/bin/yq && + chmod +x /usr/bin/yq + +echo '--> Starting Base Configuration.' + +## disable swap +sed -i '/swap/d' /etc/fstab diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/node-images.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/node-images.yaml new file mode 100644 index 000000000..b19d1b715 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/node-images.yaml @@ -0,0 +1,4 @@ +apiVersion: docker.infrastructure.clusterstack.x-k8s.io/v1alpha1 +dockerImages: + - controlplaneamd64 + - workeramd64 diff --git a/test/cluster-stacks/2/docker/ferrol/1-27/topology-docker.yaml b/test/cluster-stacks/2/docker/ferrol/1-27/topology-docker.yaml new file mode 100644 index 000000000..148838411 --- /dev/null +++ b/test/cluster-stacks/2/docker/ferrol/1-27/topology-docker.yaml @@ -0,0 +1,26 @@ +apiVersion: cluster.x-k8s.io/v1beta1 +kind: Cluster +metadata: + name: "${CLUSTER_NAME}" + namespace: "${NAMESPACE}" +spec: + clusterNetwork: + services: + cidrBlocks: ["10.128.0.0/12"] + pods: + cidrBlocks: ["192.168.0.0/16"] + serviceDomain: "cluster.local" + topology: + class: docker-ferrol-1-27-v2 + controlPlane: + metadata: {} + replicas: 1 + variables: + - name: imageRepository + value: "" + version: v1.27.3 + workers: + machineDeployments: + - class: workeramd64 + name: md-0 + replicas: 1 diff --git a/test/cluster-stacks/docker/ferrol/1-27/metadata.yaml b/test/cluster-stacks/docker/ferrol/1-27/metadata.yaml deleted file mode 100644 index e59ea27a2..000000000 --- a/test/cluster-stacks/docker/ferrol/1-27/metadata.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: metadata.clusterstack.x-k8s.io/v1alpha1 -versions: - clusterStack: v2 - kubernetes: v1.27.3 - components: - clusterAddon: v2 - nodeImage: v2