diff --git a/.obs/chartfile/crds/values.yaml b/.obs/chartfile/crds/values.yaml new file mode 100644 index 000000000..df3affc3c --- /dev/null +++ b/.obs/chartfile/crds/values.yaml @@ -0,0 +1,12 @@ +image: + empty: rancher/pause:3.1 + repository: "rancher/elemental-operator" + tag: "%VERSION%" + imagePullPolicy: IfNotPresent + +global: + cattle: + systemDefaultRegistry: "" + +# used only if systemDefaultRegistry is empty +registryUrl: "%%IMG_REPO%%" diff --git a/charts/crds/templates/_helpers.tpl b/charts/crds/templates/_helpers.tpl new file mode 100644 index 000000000..ee1e6fe7d --- /dev/null +++ b/charts/crds/templates/_helpers.tpl @@ -0,0 +1,17 @@ +{{- define "system_default_registry" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{- printf "%s/" .Values.global.cattle.systemDefaultRegistry -}} +{{- else -}} +{{- "" -}} +{{- end -}} +{{- end -}} + +{{- define "registry_url" -}} +{{- if .Values.global.cattle.systemDefaultRegistry -}} +{{ include "system_default_registry" . }} +{{- else if .Values.registryUrl -}} +{{- printf "%s/" .Values.registryUrl -}} +{{- else -}} +{{- "" -}} +{{- end -}} +{{- end -}} diff --git a/charts/crds/templates/cluster_role.yaml b/charts/crds/templates/cluster_role.yaml new file mode 100644 index 000000000..1b02241db --- /dev/null +++ b/charts/crds/templates/cluster_role.yaml @@ -0,0 +1,15 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: '{{ .Release.Name }}' +rules: +- apiGroups: + - elemental.cattle.io + resources: + - machineinventories + verbs: + - get + - list + - patch + - update diff --git a/charts/crds/templates/cluster_role_binding.yaml b/charts/crds/templates/cluster_role_binding.yaml new file mode 100644 index 000000000..e68c7bc96 --- /dev/null +++ b/charts/crds/templates/cluster_role_binding.yaml @@ -0,0 +1,13 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Release.Name }} +subjects: +- kind: ServiceAccount + name: {{ .Release.Name }} + namespace: {{.Release.Namespace}} + diff --git a/charts/crds/templates/predelete_job.yaml b/charts/crds/templates/predelete_job.yaml new file mode 100644 index 000000000..3b437c279 --- /dev/null +++ b/charts/crds/templates/predelete_job.yaml @@ -0,0 +1,18 @@ +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ .Release.Name }} + annotations: + "helm.sh/hook": pre-delete + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + spec: + containers: + - name: {{ .Release.Name }} + imagePullPolicy: "{{ .Values.image.imagePullPolicy }}" + image: {{ template "registry_url" . }}{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }} + args: + - cleanup + serviceAccountName: {{ .Release.Name }} + restartPolicy: Never diff --git a/charts/crds/templates/serviceaccount.yaml b/charts/crds/templates/serviceaccount.yaml new file mode 100644 index 000000000..cb203d6f6 --- /dev/null +++ b/charts/crds/templates/serviceaccount.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Release.Name }} diff --git a/charts/crds/values.yaml b/charts/crds/values.yaml new file mode 100644 index 000000000..baba55431 --- /dev/null +++ b/charts/crds/values.yaml @@ -0,0 +1,12 @@ +image: + empty: rancher/pause:3.1 + repository: "rancher/elemental-operator" + tag: latest + imagePullPolicy: IfNotPresent + +global: + cattle: + systemDefaultRegistry: "" + +# used only if systemDefaultRegistry is empty +registryUrl: "" diff --git a/cmd/operator/cleanup/root.go b/cmd/operator/cleanup/root.go new file mode 100644 index 000000000..c779ab44c --- /dev/null +++ b/cmd/operator/cleanup/root.go @@ -0,0 +1,94 @@ +/* +Copyright © 2022 - 2023 SUSE LLC + +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 cleanup + +import ( + "os" + + "github.com/spf13/cobra" + ctrl "sigs.k8s.io/controller-runtime" + client "sigs.k8s.io/controller-runtime/pkg/client" + runtimeconfig "sigs.k8s.io/controller-runtime/pkg/client/config" + + elementalv1 "github.com/rancher/elemental-operator/api/v1beta1" +) + +// +kubebuilder:rbac:groups=elemental.cattle.io,resources=machineinventories,verbs=get;list;update;patch + +var ( + //scheme = runtime.NewScheme() + cleanupLog = ctrl.Log.WithName("cleanup") +) + +func NewCleanupCommand() *cobra.Command { + + cmd := &cobra.Command{ + Use: "cleanup", + Short: "Removes existing finalizers so CRDs deletion will not leave resources pending on finalizers management", + Args: cobra.NoArgs, + Run: func(_ *cobra.Command, _ []string) { + cleanupRun() + }, + } + + return cmd +} + +func cleanupRun() { + cleanupLog.Info("starting registration") + + ctx := ctrl.SetupSignalHandler() + + restConfig, err := runtimeconfig.GetConfig() + if err != nil { + cleanupLog.Error(err, "failed to find kubeconfig") + os.Exit(1) + } + + cl, err := client.New(restConfig, client.Options{ + //Scheme: scheme, + }) + if err != nil { + cleanupLog.Error(err, "error building restconfig") + os.Exit(1) + } + + inventoryList := &elementalv1.MachineInventoryList{} + + err = cl.List(ctx, inventoryList, &client.ListOptions{}) + if err != nil { + cleanupLog.Error(err, "failed getting MachineInventoryList") + os.Exit(1) + } + + var errs []error + cleanupLog.Info("Cleaning MachineInventory resources") + for _, i := range inventoryList.Items { + cleanupLog.Info("Removing finalizers", "name", i.Name) + patchBase := client.MergeFrom(i.DeepCopy()) + i.Finalizers = []string{} + err = cl.Patch(ctx, &i, patchBase) + if err != nil { + cleanupLog.Error(err, "failed patching MachineInventory", "name", i.Name) + errs = append(errs, err) + } + } + if errs != nil { + cleanupLog.Error(err, "failed patching some resources") + os.Exit(1) + } +} diff --git a/cmd/operator/main.go b/cmd/operator/main.go index f5c6ded36..246e5c17f 100644 --- a/cmd/operator/main.go +++ b/cmd/operator/main.go @@ -21,6 +21,7 @@ import ( "k8s.io/klog/v2/klogr" ctrl "sigs.k8s.io/controller-runtime" + "github.com/rancher/elemental-operator/cmd/operator/cleanup" displaycmd "github.com/rancher/elemental-operator/cmd/operator/display" downloadcmd "github.com/rancher/elemental-operator/cmd/operator/download" operatorcmd "github.com/rancher/elemental-operator/cmd/operator/operator" @@ -41,6 +42,7 @@ func main() { operatorcmd.NewOperatorCommand(), displaycmd.NewDisplayCommand(), downloadcmd.NewDownloadCommand(), + cleanup.NewCleanupCommand(), NewVersionCommand(), )