Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

render cleanup hook job using cluster chart #288

Merged
merged 1 commit into from
Sep 24, 2024

Conversation

glitchcrab
Copy link
Member

towards https://github.com/giantswarm/giantswarm/issues/31417

This pr:

Uses the cluster chart to render the helmreleases cleanup hook.

Trigger e2e tests

/run cluster-test-suites

@glitchcrab glitchcrab requested a review from a team as a code owner September 24, 2024 12:27
@glitchcrab glitchcrab self-assigned this Sep 24, 2024
@@ -167,7 +167,7 @@ Properties within the `.global.providerSpecific` object
| **Property** | **Description** | **More Details** |
| :----------- | :-------------- | :--------------- |
| `baseDomain` | **Base DNS domain**|**Type:** `string`<br/>|
| `cluster` | **Cluster** - Helm values for the provider-independent cluster chart.|**Type:** `object`<br/>**Default:** `{"internal":{"advancedConfiguration":{"controlPlane":{"apiServer":{"extraArgs":{"requestheader-allowed-names":"front-proxy-client"}}}}},"providerIntegration":{"apps":{"capiNodeLabeler":{"enable":true},"certExporter":{"configTemplateName":"vSphereCertExporterHelmValues","enable":true},"certManager":{"configTemplateName":"vSphereCertManagerHelmValues","enable":true},"chartOperatorExtensions":{"enable":true},"cilium":{"configTemplateName":"vSphereCiliumHelmValues","enable":true},"ciliumServiceMonitors":{"enable":true},"coreDns":{"enable":true},"etcdKubernetesResourcesCountExporter":{"enable":true},"k8sDnsNodeCache":{"enable":true},"metricsServer":{"enable":true},"netExporter":{"enable":true},"networkPolicies":{"configTemplateName":"vSphereNetworkPoliciesHelmValues","enable":true},"nodeExporter":{"configTemplateName":"vSphereNodeExporterHelmValues","enable":true},"observabilityBundle":{"enable":true},"observabilityPolicies":{"enable":true},"securityBundle":{"enable":true},"teleportKubeAgent":{"enable":true},"verticalPodAutoscaler":{"enable":true},"verticalPodAutoscalerCrd":{"enable":true}},"controlPlane":{"kubeadmConfig":{"files":[{"contentFrom":{"secret":{"key":"content","name":"kubevip-pod","prependClusterNameAsPrefix":true}},"path":"/etc/kubernetes/manifests/kube-vip.yaml","permissions":"0600"}]},"resources":{"infrastructureMachineTemplate":{"group":"infrastructure.cluster.x-k8s.io","kind":"VSphereMachineTemplate","version":"v1beta1"},"infrastructureMachineTemplateSpecTemplateName":"controlplane-vspheremachinetemplate-spec"}},"environmentVariables":{"hostName":"COREOS_CUSTOM_HOSTNAME","ipv4":"COREOS_CUSTOM_IPV4"},"kubeadmConfig":{"enableGiantswarmUser":true,"files":[{"contentFrom":{"secret":{"key":"set-hostname.sh","name":"provider-specific-files-1","prependClusterNameAsPrefix":true}},"path":"/opt/bin/set-hostname.sh","permissions":"0755"}],"ignition":{"containerLinuxConfig":{"additionalConfig":{"systemd":{"units":[{"contents":{"install":{"wantedBy":["multi-user.target"]},"unit":{"description":"VMWare metadata agent"}},"dropins":[{"contents":"[Unit]\nAfter=nss-lookup.target\nAfter=network-online.target\nWants=network-online.target\n[Service]\nType=oneshot\nRestart=on-failure\nRemainAfterExit=yes\nEnvironment=OUTPUT=/run/metadata/coreos\nExecStart=/usr/bin/mkdir --parent /run/metadata\nExecStart=/usr/bin/bash -cv 'echo \"COREOS_CUSTOM_HOSTNAME=$(\"$(find /usr/bin /usr/share/oem -name vmtoolsd -type f -executable 2\u003e/dev/null | head -n 1)\" --cmd \"info-get guestinfo.metadata\" | base64 -d | awk \\'/local-hostname/ {print $2}\\' | tr -d \\'\"\\')\" \u003e\u003e ${OUTPUT}'\nExecStart=/usr/bin/bash -cv 'echo \"COREOS_CUSTOM_IPV4=$(\"$(find /usr/bin /usr/share/oem -name vmtoolsd -type f -executable 2\u003e/dev/null | head -n 1)\" --cmd \"info-get guestinfo.ip\")\" \u003e\u003e ${OUTPUT}'","name":"10-coreos-metadata.conf"}],"enabled":true,"name":"coreos-metadata.service"},{"contents":{"install":{"wantedBy":["multi-user.target"]},"unit":{"description":"Set machine hostname"}},"dropins":[{"contents":"[Unit]\nRequires=coreos-metadata.service\nAfter=coreos-metadata.service\nBefore=teleport.service\n[Service]\nType=oneshot\nRemainAfterExit=yes\nEnvironmentFile=/run/metadata/coreos\nExecStart=/opt/bin/set-hostname.sh","name":"10-set-hostname.conf"}],"enabled":true,"name":"set-hostname.service"},{"contents":{"install":{"wantedBy":["default.target"]},"unit":{"description":"Disable TCP segmentation offloading"}},"dropins":[{"contents":"[Unit]\nAfter=network.target\n[Service]\nType=oneshot\nRemainAfterExit=yes\nExecStart=/usr/sbin/ethtool -K ens192 tx-udp_tnl-csum-segmentation off\nExecStart=/usr/sbin/ethtool -K ens192 tx-udp_tnl-segmentation off","name":"10-ethtool-segmentation.conf"}],"enabled":true,"name":"ethtool-segmentation.service"}]}}}},"postKubeadmCommands":["usermod -aG root nobody"]},"kubernetesVersion":"1.27.14","pauseProperties":{"global.connectivity.network.controlPlaneEndpoint.host":""},"provider":"vsphere","resourcesApi":{"bastionResourceEnabled":false,"cleanupHelmReleaseResourcesEnabled":false,"clusterResourceEnabled":true,"controlPlaneResourceEnabled":true,"helmRepositoryResourcesEnabled":true,"infrastructureCluster":{"group":"infrastructure.cluster.x-k8s.io","kind":"VSphereCluster","version":"v1beta1"},"machineHealthCheckResourceEnabled":true,"machinePoolResourcesEnabled":false,"nodePoolKind":"MachineDeployment"},"workers":{"defaultNodePools":{"def00":{"cloneMode":"linkedClone","memoryMiB":16896,"network":{},"numCPUs":6,"replicas":2,"resourcePool":"*/Resources","template":"flatcar-stable-3815.2.2-kube-v1.27.14-gs"}}}}}`|
| `cluster` | **Cluster** - Helm values for the provider-independent cluster chart.|**Type:** `object`<br/>**Default:** `{"internal":{"advancedConfiguration":{"controlPlane":{"apiServer":{"extraArgs":{"requestheader-allowed-names":"front-proxy-client"}}}}},"providerIntegration":{"apps":{"capiNodeLabeler":{"enable":true},"certExporter":{"configTemplateName":"vSphereCertExporterHelmValues","enable":true},"certManager":{"configTemplateName":"vSphereCertManagerHelmValues","enable":true},"chartOperatorExtensions":{"enable":true},"cilium":{"configTemplateName":"vSphereCiliumHelmValues","enable":true},"ciliumServiceMonitors":{"enable":true},"coreDns":{"enable":true},"etcdKubernetesResourcesCountExporter":{"enable":true},"k8sDnsNodeCache":{"enable":true},"metricsServer":{"enable":true},"netExporter":{"enable":true},"networkPolicies":{"configTemplateName":"vSphereNetworkPoliciesHelmValues","enable":true},"nodeExporter":{"configTemplateName":"vSphereNodeExporterHelmValues","enable":true},"observabilityBundle":{"enable":true},"observabilityPolicies":{"enable":true},"securityBundle":{"enable":true},"teleportKubeAgent":{"enable":true},"verticalPodAutoscaler":{"enable":true},"verticalPodAutoscalerCrd":{"enable":true}},"controlPlane":{"kubeadmConfig":{"files":[{"contentFrom":{"secret":{"key":"content","name":"kubevip-pod","prependClusterNameAsPrefix":true}},"path":"/etc/kubernetes/manifests/kube-vip.yaml","permissions":"0600"}]},"resources":{"infrastructureMachineTemplate":{"group":"infrastructure.cluster.x-k8s.io","kind":"VSphereMachineTemplate","version":"v1beta1"},"infrastructureMachineTemplateSpecTemplateName":"controlplane-vspheremachinetemplate-spec"}},"environmentVariables":{"hostName":"COREOS_CUSTOM_HOSTNAME","ipv4":"COREOS_CUSTOM_IPV4"},"kubeadmConfig":{"enableGiantswarmUser":true,"files":[{"contentFrom":{"secret":{"key":"set-hostname.sh","name":"provider-specific-files-1","prependClusterNameAsPrefix":true}},"path":"/opt/bin/set-hostname.sh","permissions":"0755"}],"ignition":{"containerLinuxConfig":{"additionalConfig":{"systemd":{"units":[{"contents":{"install":{"wantedBy":["multi-user.target"]},"unit":{"description":"VMWare metadata agent"}},"dropins":[{"contents":"[Unit]\nAfter=nss-lookup.target\nAfter=network-online.target\nWants=network-online.target\n[Service]\nType=oneshot\nRestart=on-failure\nRemainAfterExit=yes\nEnvironment=OUTPUT=/run/metadata/coreos\nExecStart=/usr/bin/mkdir --parent /run/metadata\nExecStart=/usr/bin/bash -cv 'echo \"COREOS_CUSTOM_HOSTNAME=$(\"$(find /usr/bin /usr/share/oem -name vmtoolsd -type f -executable 2\u003e/dev/null | head -n 1)\" --cmd \"info-get guestinfo.metadata\" | base64 -d | awk \\'/local-hostname/ {print $2}\\' | tr -d \\'\"\\')\" \u003e\u003e ${OUTPUT}'\nExecStart=/usr/bin/bash -cv 'echo \"COREOS_CUSTOM_IPV4=$(\"$(find /usr/bin /usr/share/oem -name vmtoolsd -type f -executable 2\u003e/dev/null | head -n 1)\" --cmd \"info-get guestinfo.ip\")\" \u003e\u003e ${OUTPUT}'","name":"10-coreos-metadata.conf"}],"enabled":true,"name":"coreos-metadata.service"},{"contents":{"install":{"wantedBy":["multi-user.target"]},"unit":{"description":"Set machine hostname"}},"dropins":[{"contents":"[Unit]\nRequires=coreos-metadata.service\nAfter=coreos-metadata.service\nBefore=teleport.service\n[Service]\nType=oneshot\nRemainAfterExit=yes\nEnvironmentFile=/run/metadata/coreos\nExecStart=/opt/bin/set-hostname.sh","name":"10-set-hostname.conf"}],"enabled":true,"name":"set-hostname.service"},{"contents":{"install":{"wantedBy":["default.target"]},"unit":{"description":"Disable TCP segmentation offloading"}},"dropins":[{"contents":"[Unit]\nAfter=network.target\n[Service]\nType=oneshot\nRemainAfterExit=yes\nExecStart=/usr/sbin/ethtool -K ens192 tx-udp_tnl-csum-segmentation off\nExecStart=/usr/sbin/ethtool -K ens192 tx-udp_tnl-segmentation off","name":"10-ethtool-segmentation.conf"}],"enabled":true,"name":"ethtool-segmentation.service"}]}}}},"postKubeadmCommands":["usermod -aG root nobody"]},"kubernetesVersion":"1.27.14","pauseProperties":{"global.connectivity.network.controlPlaneEndpoint.host":""},"provider":"vsphere","resourcesApi":{"bastionResourceEnabled":false,"cleanupHelmReleaseResourcesEnabled":true,"clusterResourceEnabled":true,"controlPlaneResourceEnabled":true,"helmRepositoryResourcesEnabled":true,"infrastructureCluster":{"group":"infrastructure.cluster.x-k8s.io","kind":"VSphereCluster","version":"v1beta1"},"machineHealthCheckResourceEnabled":true,"machinePoolResourcesEnabled":false,"nodePoolKind":"MachineDeployment"},"workers":{"defaultNodePools":{"def00":{"cloneMode":"linkedClone","memoryMiB":16896,"network":{},"numCPUs":6,"replicas":2,"resourcePool":"*/Resources","template":"flatcar-stable-3815.2.2-kube-v1.27.14-gs"}}}}}`|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😅

@tinkerers-ci
Copy link

tinkerers-ci bot commented Sep 24, 2024

cluster-test-suites

Run name pr-cluster-vsphere-288-cluster-test-suitesb5rrd
Commit SHA 1e7e631
Result Failed ❌

📋 View full results in Tekton Dashboard

Rerun trigger:
/run cluster-test-suites


Tip

To only re-run the failed test suites you can provide a TARGET_SUITES parameter with your trigger that points to the directory path of the test suites to run, e.g. /run cluster-test-suites TARGET_SUITES=./providers/capa/standard to re-run the CAPA standard test suite. This supports multiple test suites with each path separated by a comma.

@glitchcrab glitchcrab added the skip/ci Instructs pr-gatekeeper to ignore any required PR checks label Sep 24, 2024
@glitchcrab
Copy link
Member Author

i'm going to ignore the test failure there - it looks like tekton did something stupid for one suite - the rest passed just fine.

Copy link
Contributor

There were differences in the rendered Helm template, please check! ⚠️

Output
=== Differences when rendered with values file helm/cluster-vsphere/ci/test-wc-values.yaml ===

(file level)
  - four documents removed:
    ---
    # Source: cluster-vsphere/templates/helmreleases/cleanup-helmreleases-hook-job.yaml
    # Because cluster provider resources are often deleted before flux has a chance
    # to uninstall helm releases for all deleted HelmRelease CRs they become
    # leftovers because there is still flux finalizer on them. This looks like
    # following:
    #
    #     $ kubectl get helmrelease -n org-multi-project
    #     NAME                           AGE     READY   STATUS
    #     pawe1-cilium                   99m     False   failed to get last release revision
    #     pawe1-cloud-provider-vsphere   99m     False   failed to get last release revision
    #
    # Both HelmRelease CRs in this case have deletionTimestamp and finalizers set,
    # e.g.:
    #
    #     deletionTimestamp: "2023-03-02T14:34:49Z"
    #     finalizers:
    #       - finalizers.fluxcd.io
    #
    # To work around this, post-delete Job deletes all finalizers on all HelmRelease
    # CRs created with this chart.
    #
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: release-name-cleanup-helmreleases-hook
      namespace: org-giantswarm
      annotations:
        helm.sh/hook: post-delete
        helm.sh/hook-delete-policy: "before-hook-creation,hook-succeeded,hook-failed"
        helm.sh/hook-weight: "-1"
      labels:
        app: cluster-vsphere
        app.kubernetes.io/managed-by: Helm
        cluster.x-k8s.io/cluster-name: release-name
        giantswarm.io/cluster: release-name
        giantswarm.io/organization: giantswarm
        application.giantswarm.io/team: rocket
        app.kubernetes.io/version: 0.63.0
        helm.sh/chart: cluster-vsphere-0.63.0
    # Source: cluster-vsphere/templates/helmreleases/cleanup-helmreleases-hook-job.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: release-name-cleanup-helmreleases-hook
      namespace: org-giantswarm
      annotations:
        helm.sh/hook: post-delete
        helm.sh/hook-delete-policy: "before-hook-creation,hook-succeeded,hook-failed"
        helm.sh/hook-weight: "-1"
      labels:
        app: cluster-vsphere
        app.kubernetes.io/managed-by: Helm
        cluster.x-k8s.io/cluster-name: release-name
        giantswarm.io/cluster: release-name
        giantswarm.io/organization: giantswarm
        application.giantswarm.io/team: rocket
        app.kubernetes.io/version: 0.63.0
        helm.sh/chart: cluster-vsphere-0.63.0
    rules:
    - apiGroups:
      - helm.toolkit.fluxcd.io
      resources:
      - helmreleases
      verbs:
      - get
      - list
      - patch
    - apiGroups:
      - source.toolkit.fluxcd.io
      resources:
      - helmcharts
      verbs:
      - get
      - list
      - patch
      - delete
    # Source: cluster-vsphere/templates/helmreleases/cleanup-helmreleases-hook-job.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: release-name-cleanup-helmreleases-hook
      namespace: org-giantswarm
      annotations:
        helm.sh/hook: post-delete
        helm.sh/hook-delete-policy: "before-hook-creation,hook-succeeded,hook-failed"
        helm.sh/hook-weight: "-1"
      labels:
        app: cluster-vsphere
        app.kubernetes.io/managed-by: Helm
        cluster.x-k8s.io/cluster-name: release-name
        giantswarm.io/cluster: release-name
        giantswarm.io/organization: giantswarm
        application.giantswarm.io/team: rocket
        app.kubernetes.io/version: 0.63.0
        helm.sh/chart: cluster-vsphere-0.63.0
    subjects:
    - kind: ServiceAccount
      name: release-name-cleanup-helmreleases-hook
      namespace: org-giantswarm
    roleRef:
      kind: Role
      name: release-name-cleanup-helmreleases-hook
      apiGroup: rbac.authorization.k8s.io
    # Source: cluster-vsphere/templates/helmreleases/cleanup-helmreleases-hook-job.yaml
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: release-name-cleanup-helmreleases-hook
      namespace: org-giantswarm
      annotations:
        helm.sh/hook: post-delete
        helm.sh/hook-delete-policy: before-hook-creation
        helm.sh/hook-weight: 0
      labels:
        app: cluster-vsphere
        app.kubernetes.io/managed-by: Helm
        cluster.x-k8s.io/cluster-name: release-name
        giantswarm.io/cluster: release-name
        giantswarm.io/organization: giantswarm
        application.giantswarm.io/team: rocket
        app.kubernetes.io/version: 0.63.0
        helm.sh/chart: cluster-vsphere-0.63.0
    spec:
      ttlSecondsAfterFinished: 86400 # 24h
      template:
        metadata:
          name: release-name-cleanup-helmreleases-hook
          namespace: org-giantswarm
          labels:
            app: cluster-vsphere
            app.kubernetes.io/managed-by: Helm
            cluster.x-k8s.io/cluster-name: release-name
            giantswarm.io/cluster: release-name
            giantswarm.io/organization: giantswarm
            application.giantswarm.io/team: rocket
            app.kubernetes.io/version: 0.63.0
            helm.sh/chart: cluster-vsphere-0.63.0
            cnp: release-name-cleanup-helmreleases-hook
        spec:
          restartPolicy: Never
          serviceAccountName: release-name-cleanup-helmreleases-hook
          securityContext:
            runAsUser: 1000
            runAsGroup: 1000
            runAsNonRoot: true
            seccompProfile:
              type: RuntimeDefault
          containers:
          - name: post-delete-job
            image: "gsoci.azurecr.io/giantswarm/kubectl:1.27.14"
            command:
            - /bin/sh
            - "-xc"
            - |
              NAMESPACE="org-giantswarm"
              CLUSTER_NAME="release-name"
              
              for release in $(kubectl get HelmRelease -n ${NAMESPACE} -l "giantswarm.io/cluster=${CLUSTER_NAME}" -o json | jq -r '.items[].metadata.name'); do
                echo "Patching helmrelease $release to remove finalizers"
                kubectl patch -n ${NAMESPACE} helmrelease "${release}" --type=merge -p '{"metadata": {"finalizers": []}}'
              done
              
              for chart in $(kubectl get HelmChart -n ${NAMESPACE} -o json | jq -r ".items[] | select(.spec.sourceRef.name == \"${CLUSTER_NAME}-default\" or .spec.sourceRef.name == \"${CLUSTER_NAME}-cluster\") | .metadata.name"); do
                echo "Patching helmchart $chart to remove finalizers"
                kubectl patch -n ${NAMESPACE} helmchart "${chart}" --type=merge -p '{"metadata": {"finalizers": []}}'
                echo "Deleting helmchart $chart"
                kubectl delete -n ${NAMESPACE} helmchart "${chart}" --ignore-not-found=true
              done
              
              echo "Unpausing cluster ${CLUSTER_NAME} to allow deletion..."
              kubectl patch -n ${NAMESPACE} cluster.cluster.x-k8s.io "${CLUSTER_NAME}" --type=merge -p '{"spec": {"paused": false}}'
              
            securityContext:
              allowPrivilegeEscalation: false
              capabilities:
                drop:
                - ALL
              seccompProfile:
                type: RuntimeDefault
              readOnlyRootFilesystem: true
            resources:
              requests:
                memory: 64Mi
                cpu: 10m
              limits:
                memory: 256Mi
                cpu: 100m
    
  
    ---
    # Source: cluster-vsphere/charts/cluster/templates/apps/helmreleases-cleanup/serviceaccount.yaml
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: test-helmreleases-cleanup
      namespace: org-giantswarm
      annotations:
        helm.sh/hook: post-delete
        helm.sh/hook-delete-policy: "before-hook-creation,hook-succeeded,hook-failed"
        helm.sh/hook-weight: "-1"
      labels:
        # deprecated: "app: cluster-vsphere" label is deprecated and it will be removed after upgrading
    # to Kubernetes 1.25. We still need it here because existing ClusterResourceSet selectors
    # need this label on the Cluster resource.
    app: cluster-vsphere
        app.kubernetes.io/name: cluster
        app.kubernetes.io/version: 1.2.1
        app.kubernetes.io/part-of: cluster-vsphere
        app.kubernetes.io/instance: release-name
        app.kubernetes.io/managed-by: Helm
        helm.sh/chart: cluster-1.2.1
        application.giantswarm.io/team: turtles
        giantswarm.io/cluster: test
        giantswarm.io/organization: giantswarm
        giantswarm.io/service-priority: highest
        cluster.x-k8s.io/cluster-name: test
        cluster.x-k8s.io/watch-filter: capi
    # Source: cluster-vsphere/charts/cluster/templates/apps/helmreleases-cleanup/role.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: test-helmreleases-cleanup
      namespace: org-giantswarm
      annotations:
        helm.sh/hook: post-delete
        helm.sh/hook-delete-policy: "before-hook-creation,hook-succeeded,hook-failed"
        helm.sh/hook-weight: "-1"
      labels:
        # deprecated: "app: cluster-vsphere" label is deprecated and it will be removed after upgrading
    # to Kubernetes 1.25. We still need it here because existing ClusterResourceSet selectors
    # need this label on the Cluster resource.
    app: cluster-vsphere
        app.kubernetes.io/name: cluster
        app.kubernetes.io/version: 1.2.1
        app.kubernetes.io/part-of: cluster-vsphere
        app.kubernetes.io/instance: release-name
        app.kubernetes.io/managed-by: Helm
        helm.sh/chart: cluster-1.2.1
        application.giantswarm.io/team: turtles
        giantswarm.io/cluster: test
        giantswarm.io/organization: giantswarm
        giantswarm.io/service-priority: highest
        cluster.x-k8s.io/cluster-name: test
        cluster.x-k8s.io/watch-filter: capi
    rules:
    - apiGroups:
      - helm.toolkit.fluxcd.io
      resources:
      - helmreleases
      verbs:
      - list
      - get
      - patch
    # Source: cluster-vsphere/charts/cluster/templates/apps/helmreleases-cleanup/rolebinding.yaml
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: test-helmreleases-cleanup
      namespace: org-giantswarm
      annotations:
        helm.sh/hook: post-delete
        helm.sh/hook-delete-policy: "before-hook-creation,hook-succeeded,hook-failed"
        helm.sh/hook-weight: "-1"
      labels:
        # deprecated: "app: cluster-vsphere" label is deprecated and it will be removed after upgrading
    # to Kubernetes 1.25. We still need it here because existing ClusterResourceSet selectors
    # need this label on the Cluster resource.
    app: cluster-vsphere
        app.kubernetes.io/name: cluster
        app.kubernetes.io/version: 1.2.1
        app.kubernetes.io/part-of: cluster-vsphere
        app.kubernetes.io/instance: release-name
        app.kubernetes.io/managed-by: Helm
        helm.sh/chart: cluster-1.2.1
        application.giantswarm.io/team: turtles
        giantswarm.io/cluster: test
        giantswarm.io/organization: giantswarm
        giantswarm.io/service-priority: highest
        cluster.x-k8s.io/cluster-name: test
        cluster.x-k8s.io/watch-filter: capi
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: test-helmreleases-cleanup
    subjects:
    - kind: ServiceAccount
      name: test-helmreleases-cleanup
      namespace: org-giantswarm
    # Source: cluster-vsphere/charts/cluster/templates/apps/helmreleases-cleanup/job.yaml
    #
    # Because cluster resources are often deleted before Flux has a chance to uninstall the Helm releases for all deleted HelmRelease CRs,
    # they become leftovers because there is still a Flux finalizer on them.
    #
    # This looks as follows:
    #
    #     $ kubectl get helmreleases --namespace org-multi-project
    #     NAME                           AGE     READY   STATUS
    #     pawe1-cilium                   99m     False   failed to get last release revision
    #     pawe1-cloud-provider-vsphere   99m     False   failed to get last release revision
    #
    # Both HelmRelease CRs in this case have a deletion timestamp and finalizer set, e.g.:
    #
    #     deletionTimestamp: "2023-03-02T14:34:49Z"
    #     finalizers:
    #     - finalizers.fluxcd.io
    #
    # To work around this, this post-delete hook suspends all HelmRelease CRs created with this chart.
    #
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: test-helmreleases-cleanup
      namespace: org-giantswarm
      annotations:
        helm.sh/hook: post-delete
        helm.sh/hook-delete-policy: before-hook-creation
        helm.sh/hook-weight: 0
      labels:
        # deprecated: "app: cluster-vsphere" label is deprecated and it will be removed after upgrading
    # to Kubernetes 1.25. We still need it here because existing ClusterResourceSet selectors
    # need this label on the Cluster resource.
    app: cluster-vsphere
        app.kubernetes.io/name: cluster
        app.kubernetes.io/version: 1.2.1
        app.kubernetes.io/part-of: cluster-vsphere
        app.kubernetes.io/instance: release-name
        app.kubernetes.io/managed-by: Helm
        helm.sh/chart: cluster-1.2.1
        application.giantswarm.io/team: turtles
        giantswarm.io/cluster: test
        giantswarm.io/organization: giantswarm
        giantswarm.io/service-priority: highest
        cluster.x-k8s.io/cluster-name: test
        cluster.x-k8s.io/watch-filter: capi
    spec:
      template:
        metadata:
          labels:
            # deprecated: "app: cluster-vsphere" label is deprecated and it will be removed after upgrading
    # to Kubernetes 1.25. We still need it here because existing ClusterResourceSet selectors
    # need this label on the Cluster resource.
    app: cluster-vsphere
            app.kubernetes.io/name: cluster
            app.kubernetes.io/version: 1.2.1
            app.kubernetes.io/part-of: cluster-vsphere
            app.kubernetes.io/instance: release-name
            app.kubernetes.io/managed-by: Helm
            helm.sh/chart: cluster-1.2.1
            application.giantswarm.io/team: turtles
            giantswarm.io/cluster: test
            giantswarm.io/organization: giantswarm
            giantswarm.io/service-priority: highest
            cluster.x-k8s.io/cluster-name: test
            cluster.x-k8s.io/watch-filter: capi
        spec:
          serviceAccountName: test-helmreleases-cleanup
          containers:
          - name: kubectl
            image: "gsoci.azurecr.io/giantswarm/kubectl:1.27.14"
            securityContext:
              runAsNonRoot: true
              runAsUser: 1000
              runAsGroup: 1000
              allowPrivilegeEscalation: false
              seccompProfile:
                type: RuntimeDefault
              capabilities:
                drop:
                - ALL
              readOnlyRootFilesystem: true
            env:
            - name: NAMESPACE
              value: org-giantswarm
            - name: CLUSTER
              value: test
            command:
            - /bin/sh
            args:
            - "-c"
            - |
              # Print namespace & cluster.
              echo "# Namespace: ${NAMESPACE} | Cluster: ${CLUSTER}"
              
              # Get releases.
              releases="$(kubectl get helmreleases.helm.toolkit.fluxcd.io --namespace "${NAMESPACE}" --selector giantswarm.io/cluster="${CLUSTER}" --output name)"
              
              # Check releases.
              if [ -n "${releases}" ]
              then
                # Patch releases.
                kubectl patch --namespace "${NAMESPACE}" ${releases} --type merge --patch '{ "spec": { "suspend": true } }'
              else
                # Print info.
                echo "No releases to patch found."
              fi
              
            resources:
              requests:
                cpu: 10m
                memory: 64Mi
              limits:
                cpu: 100m
                memory: 256Mi
          restartPolicy: Never
      ttlSecondsAfterFinished: 86400 # 24h
    
  

@glitchcrab glitchcrab merged commit d7e9d24 into main Sep 24, 2024
13 checks passed
@glitchcrab glitchcrab deleted the cluster/migrate-helmreleases branch September 24, 2024 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
skip/ci Instructs pr-gatekeeper to ignore any required PR checks
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants