From 35c8c3f9c072daf116c4e27358775ff4c13c3bb9 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 7 Feb 2022 14:00:15 +0200 Subject: [PATCH 01/69] add callhome object --- api/v1/ibmblockcsi_types.go | 20 +- .../csi.ibm.com_v1_ibmblockcsi_cr.yaml | 17 ++ controllers/ibmblockcsi_controller.go | 27 ++- .../internal/ibmblockcsi/ibmblockcsi.go | 7 + controllers/syncer/csi_call_home.go | 211 ++++++++++++++++++ pkg/config/resources.go | 1 + 6 files changed, 281 insertions(+), 2 deletions(-) create mode 100644 controllers/syncer/csi_call_home.go diff --git a/api/v1/ibmblockcsi_types.go b/api/v1/ibmblockcsi_types.go index 281fd5c3a..106045047 100644 --- a/api/v1/ibmblockcsi_types.go +++ b/api/v1/ibmblockcsi_types.go @@ -51,7 +51,7 @@ type CSISidecar struct { type IBMBlockCSISpec struct { Controller IBMBlockCSIControllerSpec `json:"controller"` Node IBMBlockCSINodeSpec `json:"node"` - + CallHome IBMBlockCSICallHomeSpec `json:"callHome"` // +kubebuilder:validation:Optional Sidecars []CSISidecar `json:"sidecars,omitempty"` @@ -112,12 +112,30 @@ type IBMBlockCSINodeSpec struct { Tolerations []corev1.Toleration `json:"tolerations,omitempty"` } +// IBMBlockCSICallHomeSpec defines the desired state of IBMBlockCSINode +type IBMBlockCSICallHomeSpec struct { + Repository string `json:"repository"` + Tag string `json:"tag"` + + ImagePullSecrets []string `json:"imagePullSecrets,omitempty"` + + // +kubebuilder:validation:Optional + ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy"` + + // +kubebuilder:validation:Optional + Affinity *corev1.Affinity `json:"affinity,omitempty"` + + // +kubebuilder:validation:Optional + Tolerations []corev1.Toleration `json:"tolerations,omitempty"` +} + // IBMBlockCSIStatus defines the observed state of IBMBlockCSI type IBMBlockCSIStatus struct { // Phase is the driver running phase Phase DriverPhase `json:"phase"` ControllerReady bool `json:"controllerReady"` NodeReady bool `json:"nodeReady"` + CallHomeReady bool `json:"callHomeReady"` // Version is the current driver version Version string `json:"version"` diff --git a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml index 621291aba..bb6fc51e0 100644 --- a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml +++ b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml @@ -44,6 +44,23 @@ spec: - amd64 - s390x - ppc64le + callHome: + repository: registry.access.redhat.com/ubi8/python-38 + tag: "1-77" + imagePullPolicy: IfNotPresent + secret: demo-secret + secretNamespace: default + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - s390x + - ppc64le # tolerations: # - effect: NoSchedule diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 81321214c..1bb834602 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -193,6 +193,11 @@ func (r *IBMBlockCSIReconciler) Reconcile(ctx context.Context, req ctrl.Request) return reconcile.Result{}, err } + csiCallHomeSyncer := clustersyncer.NewCSICallHomeSyncer(r.Client, r.Scheme, instance) + if err := syncer.Sync(context.TODO(), csiCallHomeSyncer, r.Recorder); err != nil { + return reconcile.Result{}, err + } + if err := r.updateStatus(instance, originalStatus); err != nil { return reconcile.Result{}, err } @@ -308,10 +313,16 @@ func (r *IBMBlockCSIReconciler) updateStatus(instance *ibmblockcsi.IBMBlockCSI, return err } + callHomeDeployment, err := r.getCallHomeDeployment(instance) + if err != nil { + return err + } + instance.Status.ControllerReady = r.isControllerReady(controllerStatefulset) instance.Status.NodeReady = r.isNodeReady(nodeDaemonSet) + instance.Status.CallHomeReady = r.isCallHomeReady(callHomeDeployment) phase := csiv1.DriverPhaseNone - if instance.Status.ControllerReady && instance.Status.NodeReady { + if instance.Status.ControllerReady && instance.Status.NodeReady && instance.Status.CallHomeReady { phase = csiv1.DriverPhaseRunning } else { if !instance.Status.ControllerReady { @@ -533,6 +544,16 @@ func (r *IBMBlockCSIReconciler) getNodeDaemonSet(instance *ibmblockcsi.IBMBlockC return node, err } +func (r *IBMBlockCSIReconciler) getCallHomeDeployment(instance *ibmblockcsi.IBMBlockCSI) (*appsv1.Deployment, error) { + CallHome := &appsv1.Deployment{} + err := r.Get(context.TODO(), types.NamespacedName{ + Name: oconfig.GetNameForResource(oconfig.CallHome, instance.Name), + Namespace: instance.Namespace, + }, CallHome) + + return CallHome, err +} + func (r *IBMBlockCSIReconciler) isControllerReady(controller *appsv1.StatefulSet) bool { return controller.Status.ReadyReplicas == controller.Status.Replicas } @@ -541,6 +562,10 @@ func (r *IBMBlockCSIReconciler) isNodeReady(node *appsv1.DaemonSet) bool { return node.Status.DesiredNumberScheduled == node.Status.NumberAvailable } +func (r *IBMBlockCSIReconciler) isCallHomeReady(callHome *appsv1.Deployment) bool { + return callHome.Status.ReadyReplicas == callHome.Status.Replicas +} + func (r *IBMBlockCSIReconciler) reconcileClusterRole(instance *ibmblockcsi.IBMBlockCSI) error { logger := log.WithValues("Resource Type", "ClusterRole") diff --git a/controllers/internal/ibmblockcsi/ibmblockcsi.go b/controllers/internal/ibmblockcsi/ibmblockcsi.go index a28c5511f..0fd8ab0fb 100644 --- a/controllers/internal/ibmblockcsi/ibmblockcsi.go +++ b/controllers/internal/ibmblockcsi/ibmblockcsi.go @@ -127,6 +127,13 @@ func (c *IBMBlockCSI) GetCSINodeImage() string { return c.Spec.Node.Repository + ":" + c.Spec.Node.Tag } +func (c *IBMBlockCSI) GetCallHomeImage() string { + if c.Spec.CallHome.Tag == "" { + return c.Spec.CallHome.Repository + } + return c.Spec.CallHome.Repository + ":" + c.Spec.CallHome.Tag +} + func (c *IBMBlockCSI) GetDefaultSidecarImageByName(name string) string { if sidecar, found := config.DefaultSidecarsByName[name]; found { return fmt.Sprintf("%s:%s", sidecar.Repository, sidecar.Tag) diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go new file mode 100644 index 000000000..d437c7cd2 --- /dev/null +++ b/controllers/syncer/csi_call_home.go @@ -0,0 +1,211 @@ +/** + * Copyright 2019 IBM Corp. + * + * 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 syncer + +import ( + "github.com/imdario/mergo" + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + + "github.com/IBM/ibm-block-csi-operator/controllers/internal/ibmblockcsi" + "github.com/IBM/ibm-block-csi-operator/pkg/config" + "github.com/IBM/ibm-block-csi-operator/pkg/util/boolptr" + "github.com/presslabs/controller-util/mergo/transformers" + "github.com/presslabs/controller-util/syncer" +) + +const ( + callHomeContainerName = "ibm-block-call-home" + callHomeLivenessProbeContainerName = "liveness-probe" +) + +type callHomeSyncer struct { + driver *ibmblockcsi.IBMBlockCSI + obj runtime.Object +} + +// NewCSICallHomeSyncer returns a syncer for CSI controller +func NewCSICallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmblockcsi.IBMBlockCSI) syncer.Interface { + obj := &appsv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: config.GetNameForResource(config.CallHome, driver.Name), + Namespace: driver.Namespace, + Annotations: driver.GetAnnotations("", ""), + Labels: driver.GetLabels(), + }, + } + + sync := &callHomeSyncer{ + driver: driver, + obj: obj, + } + + return syncer.NewObjectSyncer(config.CallHome.String(), driver.Unwrap(), obj, c, func() error { + return sync.SyncFn() + }) +} + +func (s *callHomeSyncer) SyncFn() error { + out := s.obj.(*appsv1.Deployment) + + out.Spec.Selector = metav1.SetAsLabelSelector(s.driver.GetCSIControllerSelectorLabels()) + + err := mergo.Merge(&out.Spec.Template.Spec, s.ensurePodSpec(), mergo.WithTransformers(transformers.PodSpec)) + if err != nil { + return err + } + + return nil +} + +func (s *callHomeSyncer) ensurePodSpec() corev1.PodSpec { + fsGroup := config.ControllerUserID + return corev1.PodSpec{ + Containers: s.ensureContainersSpec(), + Volumes: s.ensureVolumes(), + SecurityContext: &corev1.PodSecurityContext{ + FSGroup: &fsGroup, + RunAsUser: &fsGroup, + }, + ImagePullSecrets: s.getImagePullSecrets(), + Affinity: s.driver.Spec.CallHome.Affinity, + Tolerations: s.driver.Spec.CallHome.Tolerations, + } +} + +func (s *callHomeSyncer) getImagePullSecrets() []corev1.LocalObjectReference { + var secrets []corev1.LocalObjectReference + for _, s := range s.driver.Spec.CallHome.ImagePullSecrets { + secrets = append(secrets, corev1.LocalObjectReference{Name: s}) + } + return secrets +} + +func (s *callHomeSyncer) ensureContainersSpec() []corev1.Container { + callHomePlugin := s.ensureContainer(callHomeContainerName, + s.driver.GetCallHomeImage(), + []string{"--csi-endpoint=$(CSI_ENDPOINT)"}, + ) + + callHomePlugin.Resources = ensureResources("40m", "800m", "40Mi", "400Mi") + + healthPort := s.driver.Spec.HealthPort + if healthPort == 0 { + healthPort = controllerContainerDefaultHealthPortNumber + } + + callHomePlugin.Ports = ensurePorts(corev1.ContainerPort{ + Name: controllerContainerHealthPortName, + ContainerPort: int32(healthPort), + }) + callHomePlugin.ImagePullPolicy = s.driver.Spec.CallHome.ImagePullPolicy + + return []corev1.Container{ + callHomePlugin, + } +} + +func (s *callHomeSyncer) ensureContainer(name, image string, args []string) corev1.Container { + sc := &corev1.SecurityContext{AllowPrivilegeEscalation: boolptr.False()} + fillSecurityContextCapabilities(sc) + return corev1.Container{ + Name: name, + Image: image, + Args: args, + //EnvFrom: s.getEnvSourcesFor(name), + Env: s.getEnvFor(name), + VolumeMounts: s.getVolumeMountsFor(name), + SecurityContext: sc, + Resources: ensureDefaultResources(), + } +} + +func (s *callHomeSyncer) envVarFromSecret(sctName, name, key string, opt bool) corev1.EnvVar { + env := corev1.EnvVar{ + Name: name, + ValueFrom: &corev1.EnvVarSource{ + SecretKeyRef: &corev1.SecretKeySelector{ + LocalObjectReference: corev1.LocalObjectReference{ + Name: sctName, + }, + Key: key, + Optional: &opt, + }, + }, + } + return env +} + +func (s *callHomeSyncer) getEnvFor(name string) []corev1.EnvVar { + + switch name { + case callHomeContainerName: + return []corev1.EnvVar{ + { + Name: "CSI_ENDPOINT", + Value: config.CSIEndpoint, + }, + { + Name: "CSI_LOGLEVEL", + Value: config.DefaultLogLevel, + }, + } + + case provisionerContainerName, attacherContainerName, snapshotterContainerName, + resizerContainerName, replicatorContainerName: + return []corev1.EnvVar{ + { + Name: "ADDRESS", + Value: config.ControllerSocketPath, + }, + } + } + return nil +} + +func (s *callHomeSyncer) getVolumeMountsFor(name string) []corev1.VolumeMount { + switch name { + case controllerContainerName, provisionerContainerName, attacherContainerName, snapshotterContainerName, + resizerContainerName, replicatorContainerName: + return []corev1.VolumeMount{ + { + Name: socketVolumeName, + MountPath: config.ControllerSocketVolumeMountPath, + }, + } + + case controllerLivenessProbeContainerName: + return []corev1.VolumeMount{ + { + Name: socketVolumeName, + MountPath: config.ControllerLivenessProbeContainerSocketVolumeMountPath, + }, + } + } + return nil +} + +func (s *callHomeSyncer) ensureVolumes() []corev1.Volume { + return []corev1.Volume{ + ensureVolume(socketVolumeName, corev1.VolumeSource{ + EmptyDir: &corev1.EmptyDirVolumeSource{}, + }), + } +} diff --git a/pkg/config/resources.go b/pkg/config/resources.go index de43d5435..cb6fc842e 100644 --- a/pkg/config/resources.go +++ b/pkg/config/resources.go @@ -28,6 +28,7 @@ func (rn ResourceName) String() string { const ( CSIController ResourceName = "csi-controller" CSINode ResourceName = "csi-node" + CallHome ResourceName = "call-home" NodeAgent ResourceName = "ibm-node-agent" CSIControllerServiceAccount ResourceName = "csi-controller-sa" CSINodeServiceAccount ResourceName = "csi-node-sa" From 680c65fd5f199d31a989d085cf9ebe5f31eee32d Mon Sep 17 00:00:00 2001 From: arbelnat Date: Tue, 8 Feb 2022 11:56:48 +0200 Subject: [PATCH 02/69] update file with generate --- api/v1/zz_generated.deepcopy.go | 33 ++ .../crd/bases/csi.ibm.com_ibmblockcsis.yaml | 505 ++++++++++++++++++ .../generated/ibm-block-csi-operator.yaml | 505 ++++++++++++++++++ 3 files changed, 1043 insertions(+) diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 385209cdf..3cf75bcff 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -67,6 +67,38 @@ func (in *IBMBlockCSI) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IBMBlockCSICallHomeSpec) DeepCopyInto(out *IBMBlockCSICallHomeSpec) { + *out = *in + if in.ImagePullSecrets != nil { + in, out := &in.ImagePullSecrets, &out.ImagePullSecrets + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Affinity != nil { + in, out := &in.Affinity, &out.Affinity + *out = new(corev1.Affinity) + (*in).DeepCopyInto(*out) + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]corev1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IBMBlockCSICallHomeSpec. +func (in *IBMBlockCSICallHomeSpec) DeepCopy() *IBMBlockCSICallHomeSpec { + if in == nil { + return nil + } + out := new(IBMBlockCSICallHomeSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IBMBlockCSIControllerSpec) DeepCopyInto(out *IBMBlockCSIControllerSpec) { *out = *in @@ -158,6 +190,7 @@ func (in *IBMBlockCSISpec) DeepCopyInto(out *IBMBlockCSISpec) { *out = *in in.Controller.DeepCopyInto(&out.Controller) in.Node.DeepCopyInto(&out.Node) + in.CallHome.DeepCopyInto(&out.CallHome) if in.Sidecars != nil { in, out := &in.Sidecars, &out.Sidecars *out = make([]CSISidecar, len(*in)) diff --git a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml index ef01c5cb9..8c5d8d120 100644 --- a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml +++ b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml @@ -38,6 +38,507 @@ spec: spec: description: IBMBlockCSISpec defines the desired state of IBMBlockCSI properties: + callHome: + description: IBMBlockCSICallHomeSpec defines the desired state of IBMBlockCSINode + properties: + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + items: + description: A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull a container image + type: string + imagePullSecrets: + items: + type: string + type: array + repository: + type: string + tag: + type: string + tolerations: + items: + description: The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + required: + - repository + - tag + type: object controller: description: IBMBlockCSIControllerSpec defines the desired state of IBMBlockCSIController properties: @@ -1060,12 +1561,15 @@ spec: type: object type: array required: + - callHome - controller - node type: object status: description: IBMBlockCSIStatus defines the observed state of IBMBlockCSI properties: + callHomeReady: + type: boolean controllerReady: type: boolean nodeReady: @@ -1077,6 +1581,7 @@ spec: description: Version is the current driver version type: string required: + - callHomeReady - controllerReady - nodeReady - phase diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index 5ddd40b09..338dfe326 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -38,6 +38,507 @@ spec: spec: description: IBMBlockCSISpec defines the desired state of IBMBlockCSI properties: + callHome: + description: IBMBlockCSICallHomeSpec defines the desired state of IBMBlockCSINode + properties: + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + items: + description: A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull a container image + type: string + imagePullSecrets: + items: + type: string + type: array + repository: + type: string + tag: + type: string + tolerations: + items: + description: The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + required: + - repository + - tag + type: object controller: description: IBMBlockCSIControllerSpec defines the desired state of IBMBlockCSIController properties: @@ -1060,12 +1561,15 @@ spec: type: object type: array required: + - callHome - controller - node type: object status: description: IBMBlockCSIStatus defines the observed state of IBMBlockCSI properties: + callHomeReady: + type: boolean controllerReady: type: boolean nodeReady: @@ -1077,6 +1581,7 @@ spec: description: Version is the current driver version type: string required: + - callHomeReady - controllerReady - nodeReady - phase From e859d8e2fc71e1aa9dca18e0877d56447b62d733 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Tue, 8 Feb 2022 13:59:24 +0200 Subject: [PATCH 03/69] labels test --- controllers/internal/ibmblockcsi/ibmblockcsi.go | 4 ++++ controllers/syncer/csi_call_home.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/controllers/internal/ibmblockcsi/ibmblockcsi.go b/controllers/internal/ibmblockcsi/ibmblockcsi.go index 0fd8ab0fb..cae8943f3 100644 --- a/controllers/internal/ibmblockcsi/ibmblockcsi.go +++ b/controllers/internal/ibmblockcsi/ibmblockcsi.go @@ -105,6 +105,10 @@ func (c *IBMBlockCSI) GetCSINodeSelectorLabels() labels.Set { return c.GetSelectorLabels(config.CSINode.String()) } +func (c *IBMBlockCSI) GetCallHomeSelectorLabels() labels.Set { + return c.GetSelectorLabels(config.CallHome.String()) +} + func (c *IBMBlockCSI) GetCSIControllerPodLabels() labels.Set { return labels.Merge(c.GetLabels(), c.GetCSIControllerSelectorLabels()) } diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index d437c7cd2..d5c7141c4 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -65,7 +65,7 @@ func NewCSICallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmbl func (s *callHomeSyncer) SyncFn() error { out := s.obj.(*appsv1.Deployment) - out.Spec.Selector = metav1.SetAsLabelSelector(s.driver.GetCSIControllerSelectorLabels()) + out.Spec.Selector = metav1.SetAsLabelSelector(s.driver.GetCallHomeSelectorLabels()) err := mergo.Merge(&out.Spec.Template.Spec, s.ensurePodSpec(), mergo.WithTransformers(transformers.PodSpec)) if err != nil { From 43481206ee7d25b1872fe3cbc3f2104fe93fe5bd Mon Sep 17 00:00:00 2001 From: arbelnat Date: Tue, 8 Feb 2022 14:17:20 +0200 Subject: [PATCH 04/69] remove labels test --- controllers/syncer/csi_call_home.go | 1 - 1 file changed, 1 deletion(-) diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index d5c7141c4..21b32cd73 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -48,7 +48,6 @@ func NewCSICallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmbl Name: config.GetNameForResource(config.CallHome, driver.Name), Namespace: driver.Namespace, Annotations: driver.GetAnnotations("", ""), - Labels: driver.GetLabels(), }, } From fe7ed59685a48d46feb18bbab11e4d7dba84bd57 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Tue, 8 Feb 2022 14:49:46 +0200 Subject: [PATCH 05/69] deployment to StatefulSet --- controllers/ibmblockcsi_controller.go | 12 ++++++------ controllers/syncer/csi_call_home.go | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 1bb834602..3bec67d27 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -193,7 +193,7 @@ func (r *IBMBlockCSIReconciler) Reconcile(ctx context.Context, req ctrl.Request) return reconcile.Result{}, err } - csiCallHomeSyncer := clustersyncer.NewCSICallHomeSyncer(r.Client, r.Scheme, instance) + csiCallHomeSyncer := clustersyncer.NewCallHomeSyncer(r.Client, r.Scheme, instance) if err := syncer.Sync(context.TODO(), csiCallHomeSyncer, r.Recorder); err != nil { return reconcile.Result{}, err } @@ -313,14 +313,14 @@ func (r *IBMBlockCSIReconciler) updateStatus(instance *ibmblockcsi.IBMBlockCSI, return err } - callHomeDeployment, err := r.getCallHomeDeployment(instance) + callHomeStatefulset, err := r.getCallHomeStatefulset(instance) if err != nil { return err } instance.Status.ControllerReady = r.isControllerReady(controllerStatefulset) instance.Status.NodeReady = r.isNodeReady(nodeDaemonSet) - instance.Status.CallHomeReady = r.isCallHomeReady(callHomeDeployment) + instance.Status.CallHomeReady = r.isCallHomeReady(callHomeStatefulset) phase := csiv1.DriverPhaseNone if instance.Status.ControllerReady && instance.Status.NodeReady && instance.Status.CallHomeReady { phase = csiv1.DriverPhaseRunning @@ -544,8 +544,8 @@ func (r *IBMBlockCSIReconciler) getNodeDaemonSet(instance *ibmblockcsi.IBMBlockC return node, err } -func (r *IBMBlockCSIReconciler) getCallHomeDeployment(instance *ibmblockcsi.IBMBlockCSI) (*appsv1.Deployment, error) { - CallHome := &appsv1.Deployment{} +func (r *IBMBlockCSIReconciler) getCallHomeStatefulset(instance *ibmblockcsi.IBMBlockCSI) (*appsv1.StatefulSet, error) { + CallHome := &appsv1.StatefulSet{} err := r.Get(context.TODO(), types.NamespacedName{ Name: oconfig.GetNameForResource(oconfig.CallHome, instance.Name), Namespace: instance.Namespace, @@ -562,7 +562,7 @@ func (r *IBMBlockCSIReconciler) isNodeReady(node *appsv1.DaemonSet) bool { return node.Status.DesiredNumberScheduled == node.Status.NumberAvailable } -func (r *IBMBlockCSIReconciler) isCallHomeReady(callHome *appsv1.Deployment) bool { +func (r *IBMBlockCSIReconciler) isCallHomeReady(callHome *appsv1.StatefulSet) bool { return callHome.Status.ReadyReplicas == callHome.Status.Replicas } diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index 21b32cd73..da2e3265f 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -41,9 +41,9 @@ type callHomeSyncer struct { obj runtime.Object } -// NewCSICallHomeSyncer returns a syncer for CSI controller -func NewCSICallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmblockcsi.IBMBlockCSI) syncer.Interface { - obj := &appsv1.Deployment{ +// NewCallHomeSyncer returns a syncer for call home +func NewCallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmblockcsi.IBMBlockCSI) syncer.Interface { + obj := &appsv1.StatefulSet{ ObjectMeta: metav1.ObjectMeta{ Name: config.GetNameForResource(config.CallHome, driver.Name), Namespace: driver.Namespace, @@ -62,7 +62,7 @@ func NewCSICallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmbl } func (s *callHomeSyncer) SyncFn() error { - out := s.obj.(*appsv1.Deployment) + out := s.obj.(*appsv1.StatefulSet) out.Spec.Selector = metav1.SetAsLabelSelector(s.driver.GetCallHomeSelectorLabels()) From b3e4347528ddad9413eb3348a63e2287222d3492 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Tue, 8 Feb 2022 15:10:07 +0200 Subject: [PATCH 06/69] deployment to StatefulSet --- api/v1/ibmblockcsi_types.go | 6 +- api/v1/zz_generated.deepcopy.go | 64 +++++++++---------- .../crd/bases/csi.ibm.com_ibmblockcsis.yaml | 2 +- controllers/ibmblockcsi_controller.go | 4 +- .../internal/ibmblockcsi/ibmblockcsi.go | 4 ++ controllers/syncer/csi_call_home.go | 8 ++- .../generated/ibm-block-csi-operator.yaml | 2 +- 7 files changed, 50 insertions(+), 40 deletions(-) diff --git a/api/v1/ibmblockcsi_types.go b/api/v1/ibmblockcsi_types.go index 106045047..4adcf28c8 100644 --- a/api/v1/ibmblockcsi_types.go +++ b/api/v1/ibmblockcsi_types.go @@ -51,7 +51,7 @@ type CSISidecar struct { type IBMBlockCSISpec struct { Controller IBMBlockCSIControllerSpec `json:"controller"` Node IBMBlockCSINodeSpec `json:"node"` - CallHome IBMBlockCSICallHomeSpec `json:"callHome"` + CallHome IBMBlockCallHomeSpec `json:"callHome"` // +kubebuilder:validation:Optional Sidecars []CSISidecar `json:"sidecars,omitempty"` @@ -112,8 +112,8 @@ type IBMBlockCSINodeSpec struct { Tolerations []corev1.Toleration `json:"tolerations,omitempty"` } -// IBMBlockCSICallHomeSpec defines the desired state of IBMBlockCSINode -type IBMBlockCSICallHomeSpec struct { +// IBMBlockCallHomeSpec defines the desired state of IBMBlockCSICallHome +type IBMBlockCallHomeSpec struct { Repository string `json:"repository"` Tag string `json:"tag"` diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 3cf75bcff..cb37904a1 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -67,38 +67,6 @@ func (in *IBMBlockCSI) DeepCopyObject() runtime.Object { return nil } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *IBMBlockCSICallHomeSpec) DeepCopyInto(out *IBMBlockCSICallHomeSpec) { - *out = *in - if in.ImagePullSecrets != nil { - in, out := &in.ImagePullSecrets, &out.ImagePullSecrets - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Affinity != nil { - in, out := &in.Affinity, &out.Affinity - *out = new(corev1.Affinity) - (*in).DeepCopyInto(*out) - } - if in.Tolerations != nil { - in, out := &in.Tolerations, &out.Tolerations - *out = make([]corev1.Toleration, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IBMBlockCSICallHomeSpec. -func (in *IBMBlockCSICallHomeSpec) DeepCopy() *IBMBlockCSICallHomeSpec { - if in == nil { - return nil - } - out := new(IBMBlockCSICallHomeSpec) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IBMBlockCSIControllerSpec) DeepCopyInto(out *IBMBlockCSIControllerSpec) { *out = *in @@ -227,3 +195,35 @@ func (in *IBMBlockCSIStatus) DeepCopy() *IBMBlockCSIStatus { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IBMBlockCallHomeSpec) DeepCopyInto(out *IBMBlockCallHomeSpec) { + *out = *in + if in.ImagePullSecrets != nil { + in, out := &in.ImagePullSecrets, &out.ImagePullSecrets + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Affinity != nil { + in, out := &in.Affinity, &out.Affinity + *out = new(corev1.Affinity) + (*in).DeepCopyInto(*out) + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]corev1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IBMBlockCallHomeSpec. +func (in *IBMBlockCallHomeSpec) DeepCopy() *IBMBlockCallHomeSpec { + if in == nil { + return nil + } + out := new(IBMBlockCallHomeSpec) + in.DeepCopyInto(out) + return out +} diff --git a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml index 8c5d8d120..eabf83a72 100644 --- a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml +++ b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml @@ -39,7 +39,7 @@ spec: description: IBMBlockCSISpec defines the desired state of IBMBlockCSI properties: callHome: - description: IBMBlockCSICallHomeSpec defines the desired state of IBMBlockCSINode + description: IBMBlockCallHomeSpec defines the desired state of IBMBlockCSICallHome properties: affinity: description: Affinity is a group of affinity scheduling rules. diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 3bec67d27..969525982 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -193,8 +193,8 @@ func (r *IBMBlockCSIReconciler) Reconcile(ctx context.Context, req ctrl.Request) return reconcile.Result{}, err } - csiCallHomeSyncer := clustersyncer.NewCallHomeSyncer(r.Client, r.Scheme, instance) - if err := syncer.Sync(context.TODO(), csiCallHomeSyncer, r.Recorder); err != nil { + callHomeSyncer := clustersyncer.NewCallHomeSyncer(r.Client, r.Scheme, instance) + if err := syncer.Sync(context.TODO(), callHomeSyncer, r.Recorder); err != nil { return reconcile.Result{}, err } diff --git a/controllers/internal/ibmblockcsi/ibmblockcsi.go b/controllers/internal/ibmblockcsi/ibmblockcsi.go index cae8943f3..8ebbf91ca 100644 --- a/controllers/internal/ibmblockcsi/ibmblockcsi.go +++ b/controllers/internal/ibmblockcsi/ibmblockcsi.go @@ -117,6 +117,10 @@ func (c *IBMBlockCSI) GetCSINodePodLabels() labels.Set { return labels.Merge(c.GetLabels(), c.GetCSINodeSelectorLabels()) } +func (c *IBMBlockCSI) GetCallHomePodLabels() labels.Set { + return labels.Merge(c.GetLabels(), c.GetCallHomeSelectorLabels()) +} + func (c *IBMBlockCSI) GetCSIControllerImage() string { if c.Spec.Controller.Tag == "" { return c.Spec.Controller.Repository diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index da2e3265f..5a9ddd37c 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -48,6 +48,7 @@ func NewCallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmblock Name: config.GetNameForResource(config.CallHome, driver.Name), Namespace: driver.Namespace, Annotations: driver.GetAnnotations("", ""), + Labels: driver.GetLabels(), }, } @@ -64,7 +65,12 @@ func NewCallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmblock func (s *callHomeSyncer) SyncFn() error { out := s.obj.(*appsv1.StatefulSet) - out.Spec.Selector = metav1.SetAsLabelSelector(s.driver.GetCallHomeSelectorLabels()) + out.Spec.Selector = metav1.SetAsLabelSelector(s.driver.GetCSINodeSelectorLabels()) + out.Spec.ServiceName = config.GetNameForResource(config.CallHome, s.driver.Name) + + // ensure template + out.Spec.Template.ObjectMeta.Labels = s.driver.GetCSIControllerPodLabels() + out.Spec.Template.ObjectMeta.Annotations = s.driver.GetAnnotations("", "") err := mergo.Merge(&out.Spec.Template.Spec, s.ensurePodSpec(), mergo.WithTransformers(transformers.PodSpec)) if err != nil { diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index 338dfe326..61f49bef3 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -39,7 +39,7 @@ spec: description: IBMBlockCSISpec defines the desired state of IBMBlockCSI properties: callHome: - description: IBMBlockCSICallHomeSpec defines the desired state of IBMBlockCSINode + description: IBMBlockCallHomeSpec defines the desired state of IBMBlockCSICallHome properties: affinity: description: Affinity is a group of affinity scheduling rules. From 4388be00a1969eb4f390d3a0686f717d074732b7 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Tue, 8 Feb 2022 16:49:18 +0200 Subject: [PATCH 07/69] defaults --- controllers/ibmblockcsi_controller.go | 4 ++-- controllers/internal/ibmblockcsi/default_setter.go | 8 ++++++++ controllers/syncer/csi_call_home.go | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 969525982..6bdb33a0a 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -313,7 +313,7 @@ func (r *IBMBlockCSIReconciler) updateStatus(instance *ibmblockcsi.IBMBlockCSI, return err } - callHomeStatefulset, err := r.getCallHomeStatefulset(instance) + callHomeStatefulset, err := r.getCallHomeStatefulSet(instance) if err != nil { return err } @@ -544,7 +544,7 @@ func (r *IBMBlockCSIReconciler) getNodeDaemonSet(instance *ibmblockcsi.IBMBlockC return node, err } -func (r *IBMBlockCSIReconciler) getCallHomeStatefulset(instance *ibmblockcsi.IBMBlockCSI) (*appsv1.StatefulSet, error) { +func (r *IBMBlockCSIReconciler) getCallHomeStatefulSet(instance *ibmblockcsi.IBMBlockCSI) (*appsv1.StatefulSet, error) { CallHome := &appsv1.StatefulSet{} err := r.Get(context.TODO(), types.NamespacedName{ Name: oconfig.GetNameForResource(oconfig.CallHome, instance.Name), diff --git a/controllers/internal/ibmblockcsi/default_setter.go b/controllers/internal/ibmblockcsi/default_setter.go index 3dd27726c..5dc5e0f14 100644 --- a/controllers/internal/ibmblockcsi/default_setter.go +++ b/controllers/internal/ibmblockcsi/default_setter.go @@ -82,6 +82,14 @@ func (c *IBMBlockCSI) setDefaults() bool { changed = true } + if c.Spec.CallHome.Repository != config.DefaultCr.Spec.CallHome.Repository || + c.Spec.CallHome.Tag != config.DefaultCr.Spec.CallHome.Tag { + c.Spec.CallHome.Repository = config.DefaultCr.Spec.CallHome.Repository + c.Spec.CallHome.Tag = config.DefaultCr.Spec.CallHome.Tag + + changed = true + } + changed = c.setDefaultSidecars() || changed return changed diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index 5a9ddd37c..10e73b52c 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -65,11 +65,11 @@ func NewCallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmblock func (s *callHomeSyncer) SyncFn() error { out := s.obj.(*appsv1.StatefulSet) - out.Spec.Selector = metav1.SetAsLabelSelector(s.driver.GetCSINodeSelectorLabels()) + out.Spec.Selector = metav1.SetAsLabelSelector(s.driver.GetCallHomeSelectorLabels()) out.Spec.ServiceName = config.GetNameForResource(config.CallHome, s.driver.Name) // ensure template - out.Spec.Template.ObjectMeta.Labels = s.driver.GetCSIControllerPodLabels() + out.Spec.Template.ObjectMeta.Labels = s.driver.GetCallHomePodLabels() out.Spec.Template.ObjectMeta.Annotations = s.driver.GetAnnotations("", "") err := mergo.Merge(&out.Spec.Template.Spec, s.ensurePodSpec(), mergo.WithTransformers(transformers.PodSpec)) From 2d8b65dd57b31393c652616efb968eb093309e4c Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 9 Feb 2022 11:14:45 +0200 Subject: [PATCH 08/69] test adding secret --- api/v1/ibmblockcsi_types.go | 3 + .../crd/bases/csi.ibm.com_ibmblockcsis.yaml | 3 + controllers/syncer/csi_call_home.go | 72 ++++++++----------- .../generated/ibm-block-csi-operator.yaml | 3 + 4 files changed, 40 insertions(+), 41 deletions(-) diff --git a/api/v1/ibmblockcsi_types.go b/api/v1/ibmblockcsi_types.go index 4adcf28c8..8bed74771 100644 --- a/api/v1/ibmblockcsi_types.go +++ b/api/v1/ibmblockcsi_types.go @@ -117,6 +117,9 @@ type IBMBlockCallHomeSpec struct { Repository string `json:"repository"` Tag string `json:"tag"` + SecretName string `json:"secretName"` + + // +kubebuilder:validation:Optional ImagePullSecrets []string `json:"imagePullSecrets,omitempty"` // +kubebuilder:validation:Optional diff --git a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml index eabf83a72..ff5ec0581 100644 --- a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml +++ b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml @@ -511,6 +511,8 @@ spec: type: array repository: type: string + secretName: + type: string tag: type: string tolerations: @@ -537,6 +539,7 @@ spec: type: array required: - repository + - secretName - tag type: object controller: diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index 10e73b52c..7c0627b08 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -32,8 +32,8 @@ import ( ) const ( - callHomeContainerName = "ibm-block-call-home" - callHomeLivenessProbeContainerName = "liveness-probe" + callHomeContainerName = "ibm-block-call-home" + secretVolumeName = "secret-dir" ) type callHomeSyncer struct { @@ -131,10 +131,9 @@ func (s *callHomeSyncer) ensureContainer(name, image string, args []string) core sc := &corev1.SecurityContext{AllowPrivilegeEscalation: boolptr.False()} fillSecurityContextCapabilities(sc) return corev1.Container{ - Name: name, - Image: image, - Args: args, - //EnvFrom: s.getEnvSourcesFor(name), + Name: name, + Image: image, + Args: args, Env: s.getEnvFor(name), VolumeMounts: s.getVolumeMountsFor(name), SecurityContext: sc, @@ -160,57 +159,48 @@ func (s *callHomeSyncer) envVarFromSecret(sctName, name, key string, opt bool) c func (s *callHomeSyncer) getEnvFor(name string) []corev1.EnvVar { - switch name { - case callHomeContainerName: - return []corev1.EnvVar{ - { - Name: "CSI_ENDPOINT", - Value: config.CSIEndpoint, - }, - { - Name: "CSI_LOGLEVEL", - Value: config.DefaultLogLevel, - }, - } - - case provisionerContainerName, attacherContainerName, snapshotterContainerName, - resizerContainerName, replicatorContainerName: - return []corev1.EnvVar{ - { - Name: "ADDRESS", - Value: config.ControllerSocketPath, - }, - } + return []corev1.EnvVar{ + { + Name: "CSI_ENDPOINT", + Value: config.CSIEndpoint, + }, + { + Name: "CSI_LOGLEVEL", + Value: config.DefaultLogLevel, + }, + s.envVarFromSecret( + s.driver.Spec.CallHome.SecretName, + "CALL_HOME_SECRET_USERNAME", + "username", + false, + ), + s.envVarFromSecret( + s.driver.Spec.CallHome.SecretName, + "CALL_HOME_SECRET_PASSWORD", + "password", + false, + ), } - return nil + } func (s *callHomeSyncer) getVolumeMountsFor(name string) []corev1.VolumeMount { switch name { - case controllerContainerName, provisionerContainerName, attacherContainerName, snapshotterContainerName, - resizerContainerName, replicatorContainerName: + case callHomeContainerName: return []corev1.VolumeMount{ { - Name: socketVolumeName, + Name: secretVolumeName, MountPath: config.ControllerSocketVolumeMountPath, }, } - - case controllerLivenessProbeContainerName: - return []corev1.VolumeMount{ - { - Name: socketVolumeName, - MountPath: config.ControllerLivenessProbeContainerSocketVolumeMountPath, - }, - } } return nil } func (s *callHomeSyncer) ensureVolumes() []corev1.Volume { return []corev1.Volume{ - ensureVolume(socketVolumeName, corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{}, + ensureVolume(secretVolumeName, corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{SecretName: s.driver.Spec.CallHome.SecretName}, }), } } diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index 61f49bef3..bc5450ec5 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -511,6 +511,8 @@ spec: type: array repository: type: string + secretName: + type: string tag: type: string tolerations: @@ -537,6 +539,7 @@ spec: type: array required: - repository + - secretName - tag type: object controller: From 6b36db96bfff7c4eb07d1eba01f5e2a0c317289e Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 9 Feb 2022 11:29:29 +0200 Subject: [PATCH 09/69] add management_address env var --- controllers/syncer/csi_call_home.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index 7c0627b08..a01231f13 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -180,6 +180,12 @@ func (s *callHomeSyncer) getEnvFor(name string) []corev1.EnvVar { "password", false, ), + s.envVarFromSecret( + s.driver.Spec.CallHome.SecretName, + "CALL_HOME_SECRET_MANAGEMENT_ADDRESS", + "management_address", + false, + ), } } From c50a75cd902dee8f2daff8b25d825ad9f49f038f Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 9 Feb 2022 15:20:36 +0200 Subject: [PATCH 10/69] naming and consts --- api/v1/ibmblockcsi_types.go | 6 +- api/v1/zz_generated.deepcopy.go | 64 +++++++++---------- .../crd/bases/csi.ibm.com_ibmblockcsis.yaml | 2 +- .../csi.ibm.com_v1_ibmblockcsi_cr.yaml | 3 +- controllers/syncer/csi_call_home.go | 19 +++--- .../generated/ibm-block-csi-operator.yaml | 2 +- pkg/config/constants.go | 11 ++-- 7 files changed, 56 insertions(+), 51 deletions(-) diff --git a/api/v1/ibmblockcsi_types.go b/api/v1/ibmblockcsi_types.go index 8bed74771..9e1a1713f 100644 --- a/api/v1/ibmblockcsi_types.go +++ b/api/v1/ibmblockcsi_types.go @@ -51,7 +51,7 @@ type CSISidecar struct { type IBMBlockCSISpec struct { Controller IBMBlockCSIControllerSpec `json:"controller"` Node IBMBlockCSINodeSpec `json:"node"` - CallHome IBMBlockCallHomeSpec `json:"callHome"` + CallHome IBMBlockCSICallHomeSpec `json:"callHome"` // +kubebuilder:validation:Optional Sidecars []CSISidecar `json:"sidecars,omitempty"` @@ -112,8 +112,8 @@ type IBMBlockCSINodeSpec struct { Tolerations []corev1.Toleration `json:"tolerations,omitempty"` } -// IBMBlockCallHomeSpec defines the desired state of IBMBlockCSICallHome -type IBMBlockCallHomeSpec struct { +// IBMBlockCSICallHomeSpec defines the desired state of IBMBlockCSICallHome +type IBMBlockCSICallHomeSpec struct { Repository string `json:"repository"` Tag string `json:"tag"` diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index cb37904a1..3cf75bcff 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -67,6 +67,38 @@ func (in *IBMBlockCSI) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IBMBlockCSICallHomeSpec) DeepCopyInto(out *IBMBlockCSICallHomeSpec) { + *out = *in + if in.ImagePullSecrets != nil { + in, out := &in.ImagePullSecrets, &out.ImagePullSecrets + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Affinity != nil { + in, out := &in.Affinity, &out.Affinity + *out = new(corev1.Affinity) + (*in).DeepCopyInto(*out) + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make([]corev1.Toleration, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IBMBlockCSICallHomeSpec. +func (in *IBMBlockCSICallHomeSpec) DeepCopy() *IBMBlockCSICallHomeSpec { + if in == nil { + return nil + } + out := new(IBMBlockCSICallHomeSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IBMBlockCSIControllerSpec) DeepCopyInto(out *IBMBlockCSIControllerSpec) { *out = *in @@ -195,35 +227,3 @@ func (in *IBMBlockCSIStatus) DeepCopy() *IBMBlockCSIStatus { in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *IBMBlockCallHomeSpec) DeepCopyInto(out *IBMBlockCallHomeSpec) { - *out = *in - if in.ImagePullSecrets != nil { - in, out := &in.ImagePullSecrets, &out.ImagePullSecrets - *out = make([]string, len(*in)) - copy(*out, *in) - } - if in.Affinity != nil { - in, out := &in.Affinity, &out.Affinity - *out = new(corev1.Affinity) - (*in).DeepCopyInto(*out) - } - if in.Tolerations != nil { - in, out := &in.Tolerations, &out.Tolerations - *out = make([]corev1.Toleration, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IBMBlockCallHomeSpec. -func (in *IBMBlockCallHomeSpec) DeepCopy() *IBMBlockCallHomeSpec { - if in == nil { - return nil - } - out := new(IBMBlockCallHomeSpec) - in.DeepCopyInto(out) - return out -} diff --git a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml index ff5ec0581..0bfe1ea8f 100644 --- a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml +++ b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml @@ -39,7 +39,7 @@ spec: description: IBMBlockCSISpec defines the desired state of IBMBlockCSI properties: callHome: - description: IBMBlockCallHomeSpec defines the desired state of IBMBlockCSICallHome + description: IBMBlockCSICallHomeSpec defines the desired state of IBMBlockCSICallHome properties: affinity: description: Affinity is a group of affinity scheduling rules. diff --git a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml index bb6fc51e0..5d0325f8c 100644 --- a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml +++ b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml @@ -48,8 +48,7 @@ spec: repository: registry.access.redhat.com/ubi8/python-38 tag: "1-77" imagePullPolicy: IfNotPresent - secret: demo-secret - secretNamespace: default + secretName: demo-secret affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index a01231f13..a95423d4e 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -32,8 +32,11 @@ import ( ) const ( - callHomeContainerName = "ibm-block-call-home" - secretVolumeName = "secret-dir" + callHomeContainerName = "ibm-block-call-home" + secretVolumeName = "secret-dir" + secretUsernameKey = "username" + secretPasswordKey = "password" + secretManagementAddressKey = "management_address" ) type callHomeSyncer struct { @@ -170,20 +173,20 @@ func (s *callHomeSyncer) getEnvFor(name string) []corev1.EnvVar { }, s.envVarFromSecret( s.driver.Spec.CallHome.SecretName, - "CALL_HOME_SECRET_USERNAME", - "username", + config.EnvCallHomeSecretUsername, + secretUsernameKey, false, ), s.envVarFromSecret( s.driver.Spec.CallHome.SecretName, - "CALL_HOME_SECRET_PASSWORD", - "password", + config.EnvCALLHomeSecretPassword, + secretPasswordKey, false, ), s.envVarFromSecret( s.driver.Spec.CallHome.SecretName, - "CALL_HOME_SECRET_MANAGEMENT_ADDRESS", - "management_address", + config.EnvCALLHomeSecretManagementAddress, + secretManagementAddressKey, false, ), } diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index bc5450ec5..ef463d4e4 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -39,7 +39,7 @@ spec: description: IBMBlockCSISpec defines the desired state of IBMBlockCSI properties: callHome: - description: IBMBlockCallHomeSpec defines the desired state of IBMBlockCSICallHome + description: IBMBlockCSICallHomeSpec defines the desired state of IBMBlockCSICallHome properties: affinity: description: Affinity is a group of affinity scheduling rules. diff --git a/pkg/config/constants.go b/pkg/config/constants.go index e1d93ca59..95589f5cf 100644 --- a/pkg/config/constants.go +++ b/pkg/config/constants.go @@ -27,10 +27,13 @@ const ( NodeAgentRepository = "ibmcom/ibm-node-agent" - ENVIscsiAgentPort = "ISCSI_AGENT_PORT" - ENVEndpoint = "ENDPOINT" - ENVNodeName = "NODE_NAME" - ENVKubeVersion = "KUBE_VERSION" + ENVIscsiAgentPort = "ISCSI_AGENT_PORT" + ENVEndpoint = "ENDPOINT" + ENVNodeName = "NODE_NAME" + ENVKubeVersion = "KUBE_VERSION" + EnvCallHomeSecretUsername = "CALL_HOME_SECRET_USERNAME" + EnvCALLHomeSecretPassword = "CALL_HOME_SECRET_PASSWORD" + EnvCALLHomeSecretManagementAddress = "CALL_HOME_SECRET_MANAGEMENT_ADDRESS" CSINodeDriverRegistrar = "csi-node-driver-registrar" CSIProvisioner = "csi-provisioner" From 73bdb405516ec0c7e2f153d734597d02f01c7abf Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 14 Feb 2022 15:11:35 +0200 Subject: [PATCH 11/69] CallHome is Optional --- api/v1/ibmblockcsi_types.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api/v1/ibmblockcsi_types.go b/api/v1/ibmblockcsi_types.go index 9e1a1713f..369365082 100644 --- a/api/v1/ibmblockcsi_types.go +++ b/api/v1/ibmblockcsi_types.go @@ -51,7 +51,9 @@ type CSISidecar struct { type IBMBlockCSISpec struct { Controller IBMBlockCSIControllerSpec `json:"controller"` Node IBMBlockCSINodeSpec `json:"node"` - CallHome IBMBlockCSICallHomeSpec `json:"callHome"` + + // +kubebuilder:validation:Optional + CallHome IBMBlockCSICallHomeSpec `json:"callHome"` // +kubebuilder:validation:Optional Sidecars []CSISidecar `json:"sidecars,omitempty"` From e9c4c1917ace8802efd42f1178bdb7894ee05dd4 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 14 Feb 2022 15:17:53 +0200 Subject: [PATCH 12/69] update gen --- config/crd/bases/csi.ibm.com_ibmblockcsis.yaml | 1 - deploy/installer/generated/ibm-block-csi-operator.yaml | 1 - 2 files changed, 2 deletions(-) diff --git a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml index 0bfe1ea8f..d3e9b0106 100644 --- a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml +++ b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml @@ -1564,7 +1564,6 @@ spec: type: object type: array required: - - callHome - controller - node type: object diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index ef463d4e4..cab39d14c 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -1564,7 +1564,6 @@ spec: type: object type: array required: - - callHome - controller - node type: object From e7be547182c81c39c5319358be4592c1cd6d94a8 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Tue, 15 Feb 2022 11:29:26 +0200 Subject: [PATCH 13/69] remove imagePullSecrets --- api/v1/ibmblockcsi_types.go | 4 +-- api/v1/zz_generated.deepcopy.go | 5 --- .../crd/bases/csi.ibm.com_ibmblockcsis.yaml | 4 --- .../csi.ibm.com_v1_ibmblockcsi_cr.yaml | 34 ++++++++++--------- controllers/syncer/csi_call_home.go | 15 ++------ .../generated/ibm-block-csi-operator.yaml | 4 --- 6 files changed, 22 insertions(+), 44 deletions(-) diff --git a/api/v1/ibmblockcsi_types.go b/api/v1/ibmblockcsi_types.go index 369365082..7f80c2c72 100644 --- a/api/v1/ibmblockcsi_types.go +++ b/api/v1/ibmblockcsi_types.go @@ -54,6 +54,7 @@ type IBMBlockCSISpec struct { // +kubebuilder:validation:Optional CallHome IBMBlockCSICallHomeSpec `json:"callHome"` + // +kubebuilder:validation:Optional Sidecars []CSISidecar `json:"sidecars,omitempty"` @@ -121,9 +122,6 @@ type IBMBlockCSICallHomeSpec struct { SecretName string `json:"secretName"` - // +kubebuilder:validation:Optional - ImagePullSecrets []string `json:"imagePullSecrets,omitempty"` - // +kubebuilder:validation:Optional ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy"` diff --git a/api/v1/zz_generated.deepcopy.go b/api/v1/zz_generated.deepcopy.go index 3cf75bcff..88761722e 100644 --- a/api/v1/zz_generated.deepcopy.go +++ b/api/v1/zz_generated.deepcopy.go @@ -70,11 +70,6 @@ func (in *IBMBlockCSI) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IBMBlockCSICallHomeSpec) DeepCopyInto(out *IBMBlockCSICallHomeSpec) { *out = *in - if in.ImagePullSecrets != nil { - in, out := &in.ImagePullSecrets, &out.ImagePullSecrets - *out = make([]string, len(*in)) - copy(*out, *in) - } if in.Affinity != nil { in, out := &in.Affinity, &out.Affinity *out = new(corev1.Affinity) diff --git a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml index d3e9b0106..8a0e83fc1 100644 --- a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml +++ b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml @@ -505,10 +505,6 @@ spec: imagePullPolicy: description: PullPolicy describes a policy for if/when to pull a container image type: string - imagePullSecrets: - items: - type: string - type: array repository: type: string secretName: diff --git a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml index 5d0325f8c..9cc55f793 100644 --- a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml +++ b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml @@ -44,22 +44,24 @@ spec: - amd64 - s390x - ppc64le - callHome: - repository: registry.access.redhat.com/ubi8/python-38 - tag: "1-77" - imagePullPolicy: IfNotPresent - secretName: demo-secret - affinity: - nodeAffinity: - requiredDuringSchedulingIgnoredDuringExecution: - nodeSelectorTerms: - - matchExpressions: - - key: kubernetes.io/arch - operator: In - values: - - amd64 - - s390x - - ppc64le + + # callHome is a statefulSet with ibm-block-csi-call-home container +# callHome: +# repository: registry.access.redhat.com/ubi8/python-38 +# tag: "1-77" +# imagePullPolicy: IfNotPresent +# secretName: demo-secret +# affinity: +# nodeAffinity: +# requiredDuringSchedulingIgnoredDuringExecution: +# nodeSelectorTerms: +# - matchExpressions: +# - key: kubernetes.io/arch +# operator: In +# values: +# - amd64 +# - s390x +# - ppc64le # tolerations: # - effect: NoSchedule diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index a95423d4e..8670fc4ba 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -32,7 +32,7 @@ import ( ) const ( - callHomeContainerName = "ibm-block-call-home" + callHomeContainerName = "ibm-block-csi-call-home" secretVolumeName = "secret-dir" secretUsernameKey = "username" secretPasswordKey = "password" @@ -92,20 +92,11 @@ func (s *callHomeSyncer) ensurePodSpec() corev1.PodSpec { FSGroup: &fsGroup, RunAsUser: &fsGroup, }, - ImagePullSecrets: s.getImagePullSecrets(), - Affinity: s.driver.Spec.CallHome.Affinity, - Tolerations: s.driver.Spec.CallHome.Tolerations, + Affinity: s.driver.Spec.CallHome.Affinity, + Tolerations: s.driver.Spec.CallHome.Tolerations, } } -func (s *callHomeSyncer) getImagePullSecrets() []corev1.LocalObjectReference { - var secrets []corev1.LocalObjectReference - for _, s := range s.driver.Spec.CallHome.ImagePullSecrets { - secrets = append(secrets, corev1.LocalObjectReference{Name: s}) - } - return secrets -} - func (s *callHomeSyncer) ensureContainersSpec() []corev1.Container { callHomePlugin := s.ensureContainer(callHomeContainerName, s.driver.GetCallHomeImage(), diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index cab39d14c..c9c7d8221 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -505,10 +505,6 @@ spec: imagePullPolicy: description: PullPolicy describes a policy for if/when to pull a container image type: string - imagePullSecrets: - items: - type: string - type: array repository: type: string secretName: From efdcba139d83e34d3b3e4093ad674dda51603a5f Mon Sep 17 00:00:00 2001 From: arbelnat Date: Tue, 15 Feb 2022 15:30:02 +0200 Subject: [PATCH 14/69] test with cronjob --- controllers/ibmblockcsi_controller.go | 13 +++++++------ controllers/syncer/csi_call_home.go | 19 +++++++++++-------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 6bdb33a0a..69766f70d 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -19,6 +19,7 @@ package controllers import ( "context" "fmt" + batchv1 "k8s.io/api/batch/v1" "os" "reflect" "strings" @@ -313,14 +314,14 @@ func (r *IBMBlockCSIReconciler) updateStatus(instance *ibmblockcsi.IBMBlockCSI, return err } - callHomeStatefulset, err := r.getCallHomeStatefulSet(instance) + callHomeCronJob, err := r.getCallHomeCronJob(instance) if err != nil { return err } instance.Status.ControllerReady = r.isControllerReady(controllerStatefulset) instance.Status.NodeReady = r.isNodeReady(nodeDaemonSet) - instance.Status.CallHomeReady = r.isCallHomeReady(callHomeStatefulset) + instance.Status.CallHomeReady = r.isCallHomeReady(callHomeCronJob) phase := csiv1.DriverPhaseNone if instance.Status.ControllerReady && instance.Status.NodeReady && instance.Status.CallHomeReady { phase = csiv1.DriverPhaseRunning @@ -544,8 +545,8 @@ func (r *IBMBlockCSIReconciler) getNodeDaemonSet(instance *ibmblockcsi.IBMBlockC return node, err } -func (r *IBMBlockCSIReconciler) getCallHomeStatefulSet(instance *ibmblockcsi.IBMBlockCSI) (*appsv1.StatefulSet, error) { - CallHome := &appsv1.StatefulSet{} +func (r *IBMBlockCSIReconciler) getCallHomeCronJob(instance *ibmblockcsi.IBMBlockCSI) (*batchv1.CronJob, error) { + CallHome := &batchv1.CronJob{} err := r.Get(context.TODO(), types.NamespacedName{ Name: oconfig.GetNameForResource(oconfig.CallHome, instance.Name), Namespace: instance.Namespace, @@ -562,8 +563,8 @@ func (r *IBMBlockCSIReconciler) isNodeReady(node *appsv1.DaemonSet) bool { return node.Status.DesiredNumberScheduled == node.Status.NumberAvailable } -func (r *IBMBlockCSIReconciler) isCallHomeReady(callHome *appsv1.StatefulSet) bool { - return callHome.Status.ReadyReplicas == callHome.Status.Replicas +func (r *IBMBlockCSIReconciler) isCallHomeReady(callHome *batchv1.CronJob) bool { + return len(callHome.Status.Active) == len(callHome.Status.Active) } func (r *IBMBlockCSIReconciler) reconcileClusterRole(instance *ibmblockcsi.IBMBlockCSI) error { diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index 8670fc4ba..4fc4a0291 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -18,7 +18,7 @@ package syncer import ( "github.com/imdario/mergo" - appsv1 "k8s.io/api/apps/v1" + batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -46,7 +46,7 @@ type callHomeSyncer struct { // NewCallHomeSyncer returns a syncer for call home func NewCallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmblockcsi.IBMBlockCSI) syncer.Interface { - obj := &appsv1.StatefulSet{ + obj := &batchv1.CronJob{ ObjectMeta: metav1.ObjectMeta{ Name: config.GetNameForResource(config.CallHome, driver.Name), Namespace: driver.Namespace, @@ -66,16 +66,19 @@ func NewCallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmblock } func (s *callHomeSyncer) SyncFn() error { - out := s.obj.(*appsv1.StatefulSet) + out := s.obj.(*batchv1.CronJob) - out.Spec.Selector = metav1.SetAsLabelSelector(s.driver.GetCallHomeSelectorLabels()) - out.Spec.ServiceName = config.GetNameForResource(config.CallHome, s.driver.Name) + out.Spec.JobTemplate.Spec.Selector = metav1.SetAsLabelSelector(s.driver.GetCallHomeSelectorLabels()) + //out.Spec.ServiceName = config.GetNameForResource(config.CallHome, s.driver.Name) + + //Run once a day at midnight + out.Spec.Schedule = "0 0 * * *" // ensure template - out.Spec.Template.ObjectMeta.Labels = s.driver.GetCallHomePodLabels() - out.Spec.Template.ObjectMeta.Annotations = s.driver.GetAnnotations("", "") + out.Spec.JobTemplate.ObjectMeta.Labels = s.driver.GetCallHomePodLabels() + out.Spec.JobTemplate.ObjectMeta.Annotations = s.driver.GetAnnotations("", "") - err := mergo.Merge(&out.Spec.Template.Spec, s.ensurePodSpec(), mergo.WithTransformers(transformers.PodSpec)) + err := mergo.Merge(&out.Spec.JobTemplate.Spec.Template.Spec, s.ensurePodSpec(), mergo.WithTransformers(transformers.PodSpec)) if err != nil { return err } From d868343b2bf4f23715f26b21f0d73676f76e8b01 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 16 Feb 2022 11:34:06 +0200 Subject: [PATCH 15/69] test with cronjob, remove selctor and add batch to role and RestartPolicy --- config/rbac/role.yaml | 1 + controllers/syncer/csi_call_home.go | 7 ++++--- deploy/installer/generated/ibm-block-csi-operator.yaml | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 4b670c6ef..6fd1bd28b 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -112,6 +112,7 @@ rules: - watch - apiGroups: - apps + - batch resourceNames: - ibm-block-csi-operator resources: diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index 4fc4a0291..befc86d31 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -68,7 +68,7 @@ func NewCallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmblock func (s *callHomeSyncer) SyncFn() error { out := s.obj.(*batchv1.CronJob) - out.Spec.JobTemplate.Spec.Selector = metav1.SetAsLabelSelector(s.driver.GetCallHomeSelectorLabels()) + //out.Spec.JobTemplate.Spec.Selector = metav1.SetAsLabelSelector(s.driver.GetCallHomeSelectorLabels()) //out.Spec.ServiceName = config.GetNameForResource(config.CallHome, s.driver.Name) //Run once a day at midnight @@ -95,8 +95,9 @@ func (s *callHomeSyncer) ensurePodSpec() corev1.PodSpec { FSGroup: &fsGroup, RunAsUser: &fsGroup, }, - Affinity: s.driver.Spec.CallHome.Affinity, - Tolerations: s.driver.Spec.CallHome.Tolerations, + Affinity: s.driver.Spec.CallHome.Affinity, + Tolerations: s.driver.Spec.CallHome.Tolerations, + RestartPolicy: "OnFailure", } } diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index c9c7d8221..a2b4d382b 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -1722,6 +1722,7 @@ rules: - watch - apiGroups: - apps + - batch resourceNames: - ibm-block-csi-operator resources: From 1cef0d97be18faa2ab2e07952fecb47612650317 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 16 Feb 2022 12:02:03 +0200 Subject: [PATCH 16/69] Schedule from CR --- api/v1/ibmblockcsi_types.go | 4 ++++ config/crd/bases/csi.ibm.com_ibmblockcsis.yaml | 3 +++ controllers/syncer/csi_call_home.go | 10 +++++++++- deploy/installer/generated/ibm-block-csi-operator.yaml | 3 +++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/api/v1/ibmblockcsi_types.go b/api/v1/ibmblockcsi_types.go index 7f80c2c72..607c2c0d0 100644 --- a/api/v1/ibmblockcsi_types.go +++ b/api/v1/ibmblockcsi_types.go @@ -125,6 +125,10 @@ type IBMBlockCSICallHomeSpec struct { // +kubebuilder:validation:Optional ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy"` + // The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. + // +kubebuilder:validation:Optional + Schedule string `json:"schedule" protobuf:"bytes,1,opt,name=schedule"` + // +kubebuilder:validation:Optional Affinity *corev1.Affinity `json:"affinity,omitempty"` diff --git a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml index 8a0e83fc1..8375ecaf5 100644 --- a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml +++ b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml @@ -507,6 +507,9 @@ spec: type: string repository: type: string + schedule: + description: The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. + type: string secretName: type: string tag: diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index befc86d31..400f3b482 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -37,6 +37,7 @@ const ( secretUsernameKey = "username" secretPasswordKey = "password" secretManagementAddressKey = "management_address" + defaultCronSchedule = "0 0 * *" ) type callHomeSyncer struct { @@ -72,7 +73,7 @@ func (s *callHomeSyncer) SyncFn() error { //out.Spec.ServiceName = config.GetNameForResource(config.CallHome, s.driver.Name) //Run once a day at midnight - out.Spec.Schedule = "0 0 * * *" + out.Spec.Schedule = s.getCallHomeSchedule() // ensure template out.Spec.JobTemplate.ObjectMeta.Labels = s.driver.GetCallHomePodLabels() @@ -86,6 +87,13 @@ func (s *callHomeSyncer) SyncFn() error { return nil } +func (s *callHomeSyncer) getCallHomeSchedule() string { + if s.driver.Spec.CallHome.Schedule == "" { + return defaultCronSchedule + } + return s.driver.Spec.CallHome.Schedule +} + func (s *callHomeSyncer) ensurePodSpec() corev1.PodSpec { fsGroup := config.ControllerUserID return corev1.PodSpec{ diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index a2b4d382b..afe0af81e 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -507,6 +507,9 @@ spec: type: string repository: type: string + schedule: + description: The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. + type: string secretName: type: string tag: From e23dfe31cbd72c6c654b722274c2552f9869215b Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 16 Feb 2022 15:15:32 +0200 Subject: [PATCH 17/69] job's pod labels SuccessfulJobsHistoryLimit to 1 --- controllers/syncer/csi_call_home.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index 400f3b482..4a3cf9303 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -78,6 +78,9 @@ func (s *callHomeSyncer) SyncFn() error { // ensure template out.Spec.JobTemplate.ObjectMeta.Labels = s.driver.GetCallHomePodLabels() out.Spec.JobTemplate.ObjectMeta.Annotations = s.driver.GetAnnotations("", "") + out.Spec.JobTemplate.Spec.Template.ObjectMeta.Labels = s.driver.GetCallHomePodLabels() + defaultSuccessfulJobsHistoryLimit := int32(1) + out.Spec.SuccessfulJobsHistoryLimit = &defaultSuccessfulJobsHistoryLimit err := mergo.Merge(&out.Spec.JobTemplate.Spec.Template.Spec, s.ensurePodSpec(), mergo.WithTransformers(transformers.PodSpec)) if err != nil { From 9e0954c15e4eed933ae9da4b1ec6d79f0563b8e3 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 20 Feb 2022 10:16:02 +0200 Subject: [PATCH 18/69] adding call home ClusterRole --- config/rbac/role.yaml | 2 +- controllers/ibmblockcsi_controller.go | 2 + .../ibmblockcsi/static_resource_generator.go | 46 +++++++++++++++++++ controllers/syncer/csi_call_home.go | 24 ++++------ .../generated/ibm-block-csi-operator.yaml | 2 +- pkg/config/resources.go | 3 ++ 6 files changed, 62 insertions(+), 17 deletions(-) diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 6fd1bd28b..a1dd5875c 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -112,7 +112,6 @@ rules: - watch - apiGroups: - apps - - batch resourceNames: - ibm-block-csi-operator resources: @@ -121,6 +120,7 @@ rules: - update - apiGroups: - csi.ibm.com + - batch resources: - '*' verbs: diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 69766f70d..971bc1f4e 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -645,6 +645,7 @@ func (r *IBMBlockCSIReconciler) getClusterRoles(instance *ibmblockcsi.IBMBlockCS csiAddonsReplicator := instance.GenerateCSIAddonsReplicatorClusterRole() controllerSCC := instance.GenerateSCCForControllerClusterRole() nodeSCC := instance.GenerateSCCForNodeClusterRole() + callHomeSCC := instance.GenerateSCCForCallHomeClusterRole() return []*rbacv1.ClusterRole{ externalProvisioner, @@ -654,6 +655,7 @@ func (r *IBMBlockCSIReconciler) getClusterRoles(instance *ibmblockcsi.IBMBlockCS csiAddonsReplicator, controllerSCC, nodeSCC, + callHomeSCC, } } diff --git a/controllers/internal/ibmblockcsi/static_resource_generator.go b/controllers/internal/ibmblockcsi/static_resource_generator.go index 6c3e4aee2..efc48eb1b 100644 --- a/controllers/internal/ibmblockcsi/static_resource_generator.go +++ b/controllers/internal/ibmblockcsi/static_resource_generator.go @@ -48,6 +48,7 @@ const ( volumeReplicationsStatusResource string = "volumereplications/status" eventsResource string = "events" nodesResource string = "nodes" + namespaceResource string = "namespace" csiNodesResource string = "csinodes" secretsResource string = "secrets" securityContextConstraintsResource string = "securitycontextconstraints" @@ -107,6 +108,16 @@ func (c *IBMBlockCSI) GenerateNodeServiceAccount() *corev1.ServiceAccount { ImagePullSecrets: secrets, } } +func (c *IBMBlockCSI) GenerateCallHomeServiceAccount() *corev1.ServiceAccount { + + return &corev1.ServiceAccount{ + ObjectMeta: metav1.ObjectMeta{ + Name: config.GetNameForResource(config.CallHomeServiceAccount, c.Name), + Namespace: c.Namespace, + Labels: c.GetLabels(), + }, + } +} func (c *IBMBlockCSI) GenerateExternalProvisionerClusterRole() *rbacv1.ClusterRole { return &rbacv1.ClusterRole{ @@ -470,6 +481,21 @@ func (c *IBMBlockCSI) GenerateSCCForNodeClusterRole() *rbacv1.ClusterRole { } } +func (c *IBMBlockCSI) GenerateSCCForCallHomeClusterRole() *rbacv1.ClusterRole { + return &rbacv1.ClusterRole{ + ObjectMeta: metav1.ObjectMeta{ + Name: config.GetNameForResource(config.CallHomeSCCClusterRole, c.Name), + }, + Rules: []rbacv1.PolicyRule{ + { + APIGroups: []string{""}, + Resources: []string{namespaceResource}, + Verbs: []string{verbGet}, + }, + }, + } +} + func (c *IBMBlockCSI) GenerateSCCForNodeClusterRoleBinding() *rbacv1.ClusterRoleBinding { return &rbacv1.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ @@ -489,3 +515,23 @@ func (c *IBMBlockCSI) GenerateSCCForNodeClusterRoleBinding() *rbacv1.ClusterRole }, } } + +func (c *IBMBlockCSI) GenerateSCCForCallHomeClusterRoleBinding() *rbacv1.ClusterRoleBinding { + return &rbacv1.ClusterRoleBinding{ + ObjectMeta: metav1.ObjectMeta{ + Name: config.GetNameForResource(config.CallHomeSCCClusterRoleBinding, c.Name), + }, + Subjects: []rbacv1.Subject{ + { + Kind: "ServiceAccount", + Name: config.GetNameForResource(config.CallHomeServiceAccount, c.Name), + Namespace: c.Namespace, + }, + }, + RoleRef: rbacv1.RoleRef{ + Kind: "ClusterRole", + Name: config.GetNameForResource(config.CallHomeSCCClusterRole, c.Name), + APIGroup: rbacAuthorizationApiGroup, + }, + } +} diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index 4a3cf9303..584df907c 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -32,12 +32,11 @@ import ( ) const ( - callHomeContainerName = "ibm-block-csi-call-home" - secretVolumeName = "secret-dir" - secretUsernameKey = "username" - secretPasswordKey = "password" - secretManagementAddressKey = "management_address" - defaultCronSchedule = "0 0 * *" + callHomeContainerName = "ibm-block-csi-call-home" + secretVolumeName = "secret-dir" + secretUsernameKey = "username" + secretPasswordKey = "password" + defaultCronSchedule = "0 0 * *" ) type callHomeSyncer struct { @@ -106,9 +105,10 @@ func (s *callHomeSyncer) ensurePodSpec() corev1.PodSpec { FSGroup: &fsGroup, RunAsUser: &fsGroup, }, - Affinity: s.driver.Spec.CallHome.Affinity, - Tolerations: s.driver.Spec.CallHome.Tolerations, - RestartPolicy: "OnFailure", + ServiceAccountName: config.GetNameForResource(config.CallHomeServiceAccount, s.driver.Name), + Affinity: s.driver.Spec.CallHome.Affinity, + Tolerations: s.driver.Spec.CallHome.Tolerations, + RestartPolicy: "OnFailure", } } @@ -189,12 +189,6 @@ func (s *callHomeSyncer) getEnvFor(name string) []corev1.EnvVar { secretPasswordKey, false, ), - s.envVarFromSecret( - s.driver.Spec.CallHome.SecretName, - config.EnvCALLHomeSecretManagementAddress, - secretManagementAddressKey, - false, - ), } } diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index afe0af81e..1fac0fae3 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -1725,7 +1725,6 @@ rules: - watch - apiGroups: - apps - - batch resourceNames: - ibm-block-csi-operator resources: @@ -1734,6 +1733,7 @@ rules: - update - apiGroups: - csi.ibm.com + - batch resources: - '*' verbs: diff --git a/pkg/config/resources.go b/pkg/config/resources.go index cb6fc842e..e5f30c79c 100644 --- a/pkg/config/resources.go +++ b/pkg/config/resources.go @@ -32,6 +32,7 @@ const ( NodeAgent ResourceName = "ibm-node-agent" CSIControllerServiceAccount ResourceName = "csi-controller-sa" CSINodeServiceAccount ResourceName = "csi-node-sa" + CallHomeServiceAccount ResourceName = "call-home-sa" ExternalProvisionerClusterRole ResourceName = "external-provisioner-clusterrole" ExternalProvisionerClusterRoleBinding ResourceName = "external-provisioner-clusterrolebinding" ExternalAttacherClusterRole ResourceName = "external-attacher-clusterrole" @@ -45,7 +46,9 @@ const ( CSIControllerSCCClusterRole ResourceName = "csi-controller-scc-clusterrole" CSIControllerSCCClusterRoleBinding ResourceName = "csi-controller-scc-clusterrolebinding" CSINodeSCCClusterRole ResourceName = "csi-node-scc-clusterrole" + CallHomeSCCClusterRole ResourceName = "call-home-scc-clusterrole" CSINodeSCCClusterRoleBinding ResourceName = "csi-node-scc-clusterrolebinding" + CallHomeSCCClusterRoleBinding ResourceName = "call-home-scc-clusterrolebinding" ) // GetNameForResource returns the name of a resource for a CSI driver From 4facf7527638cdaf309d80498206cc5f4b877f53 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 20 Feb 2022 10:28:51 +0200 Subject: [PATCH 19/69] adding namespaces role --- config/rbac/role.yaml | 6 ++++++ .../internal/ibmblockcsi/static_resource_generator.go | 4 ++-- deploy/installer/generated/ibm-block-csi-operator.yaml | 6 ++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index a1dd5875c..ef553e9cd 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -34,6 +34,12 @@ rules: - get - list - watch +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get - apiGroups: - "" resources: diff --git a/controllers/internal/ibmblockcsi/static_resource_generator.go b/controllers/internal/ibmblockcsi/static_resource_generator.go index efc48eb1b..2fce84f6f 100644 --- a/controllers/internal/ibmblockcsi/static_resource_generator.go +++ b/controllers/internal/ibmblockcsi/static_resource_generator.go @@ -48,7 +48,7 @@ const ( volumeReplicationsStatusResource string = "volumereplications/status" eventsResource string = "events" nodesResource string = "nodes" - namespaceResource string = "namespace" + namespacesResource string = "namespaces" csiNodesResource string = "csinodes" secretsResource string = "secrets" securityContextConstraintsResource string = "securitycontextconstraints" @@ -489,7 +489,7 @@ func (c *IBMBlockCSI) GenerateSCCForCallHomeClusterRole() *rbacv1.ClusterRole { Rules: []rbacv1.PolicyRule{ { APIGroups: []string{""}, - Resources: []string{namespaceResource}, + Resources: []string{namespacesResource}, Verbs: []string{verbGet}, }, }, diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index 1fac0fae3..130d3c002 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -1647,6 +1647,12 @@ rules: - get - list - watch +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get - apiGroups: - "" resources: From 404bf7798c49e4c7ebe142c3e423a1dde949a6d8 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 20 Feb 2022 10:39:25 +0200 Subject: [PATCH 20/69] create ServiceAccount --- controllers/ibmblockcsi_controller.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 971bc1f4e..2cfd843b1 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -455,6 +455,7 @@ func (r *IBMBlockCSIReconciler) reconcileServiceAccount(instance *ibmblockcsi.IB controller := instance.GenerateControllerServiceAccount() node := instance.GenerateNodeServiceAccount() + callHome := instance.GenerateCallHomeServiceAccount() controllerServiceAccountName := oconfig.GetNameForResource(oconfig.CSIControllerServiceAccount, instance.Name) nodeServiceAccountName := oconfig.GetNameForResource(oconfig.CSINodeServiceAccount, instance.Name) @@ -462,6 +463,7 @@ func (r *IBMBlockCSIReconciler) reconcileServiceAccount(instance *ibmblockcsi.IB for _, sa := range []*corev1.ServiceAccount{ controller, node, + callHome, } { if err := controllerutil.SetControllerReference(instance.Unwrap(), sa, r.Scheme); err != nil { return err From f079767021452eb91696cf6228948384527ca8c5 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 20 Feb 2022 11:15:49 +0200 Subject: [PATCH 21/69] create ClusterRoleBinding --- controllers/ibmblockcsi_controller.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 2cfd843b1..4235c86db 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -724,6 +724,7 @@ func (r *IBMBlockCSIReconciler) getClusterRoleBindings(instance *ibmblockcsi.IBM csiAddonsReplicator := instance.GenerateCSIAddonsReplicatorClusterRoleBinding() controllerSCC := instance.GenerateSCCForControllerClusterRoleBinding() nodeSCC := instance.GenerateSCCForNodeClusterRoleBinding() + callHomeSCC := instance.GenerateSCCForCallHomeClusterRoleBinding() return []*rbacv1.ClusterRoleBinding{ externalProvisioner, @@ -733,6 +734,7 @@ func (r *IBMBlockCSIReconciler) getClusterRoleBindings(instance *ibmblockcsi.IBM csiAddonsReplicator, controllerSCC, nodeSCC, + callHomeSCC, } } From 58bf2d884f88a618e4f91f87b4bec7f39a6b1808 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 20 Feb 2022 11:24:12 +0200 Subject: [PATCH 22/69] add pod to clusterrole --- .../internal/ibmblockcsi/static_resource_generator.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/controllers/internal/ibmblockcsi/static_resource_generator.go b/controllers/internal/ibmblockcsi/static_resource_generator.go index 2fce84f6f..ed5725874 100644 --- a/controllers/internal/ibmblockcsi/static_resource_generator.go +++ b/controllers/internal/ibmblockcsi/static_resource_generator.go @@ -492,6 +492,11 @@ func (c *IBMBlockCSI) GenerateSCCForCallHomeClusterRole() *rbacv1.ClusterRole { Resources: []string{namespacesResource}, Verbs: []string{verbGet}, }, + { + APIGroups: []string{""}, + Resources: []string{podsResource}, + Verbs: []string{verbList}, + }, }, } } From 3d0a5335cb53576fa4d28af815a7f14914b34ceb Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 20 Feb 2022 11:43:45 +0200 Subject: [PATCH 23/69] add cronjobs to role.yaml --- config/rbac/role.yaml | 12 +++++++++++- .../installer/generated/ibm-block-csi-operator.yaml | 12 +++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index ef553e9cd..859153857 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -40,6 +40,17 @@ rules: - namespaces verbs: - get +- apiGroups: + - batch + resources: + - cronjobs + verbs: + - create + - delete + - get + - list + - update + - watch - apiGroups: - "" resources: @@ -126,7 +137,6 @@ rules: - update - apiGroups: - csi.ibm.com - - batch resources: - '*' verbs: diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index 130d3c002..a6323c474 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -1653,6 +1653,17 @@ rules: - namespaces verbs: - get +- apiGroups: + - batch + resources: + - cronjobs + verbs: + - create + - delete + - get + - list + - update + - watch - apiGroups: - "" resources: @@ -1739,7 +1750,6 @@ rules: - update - apiGroups: - csi.ibm.com - - batch resources: - '*' verbs: From d4410ca8eace2cf5e31437e7ade6b3fb89c1530c Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 20 Feb 2022 11:49:45 +0200 Subject: [PATCH 24/69] clean --- config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml | 4 ++-- pkg/config/constants.go | 13 ++++++------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml index 9cc55f793..a23cc592f 100644 --- a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml +++ b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml @@ -47,8 +47,8 @@ spec: # callHome is a statefulSet with ibm-block-csi-call-home container # callHome: -# repository: registry.access.redhat.com/ubi8/python-38 -# tag: "1-77" +# repository: stg-artifactory.xiv.ibm.com:5030/ibm-block-csi-call-home-amd64 +# tag: "1.9.0" # imagePullPolicy: IfNotPresent # secretName: demo-secret # affinity: diff --git a/pkg/config/constants.go b/pkg/config/constants.go index 95589f5cf..35f848647 100644 --- a/pkg/config/constants.go +++ b/pkg/config/constants.go @@ -27,13 +27,12 @@ const ( NodeAgentRepository = "ibmcom/ibm-node-agent" - ENVIscsiAgentPort = "ISCSI_AGENT_PORT" - ENVEndpoint = "ENDPOINT" - ENVNodeName = "NODE_NAME" - ENVKubeVersion = "KUBE_VERSION" - EnvCallHomeSecretUsername = "CALL_HOME_SECRET_USERNAME" - EnvCALLHomeSecretPassword = "CALL_HOME_SECRET_PASSWORD" - EnvCALLHomeSecretManagementAddress = "CALL_HOME_SECRET_MANAGEMENT_ADDRESS" + ENVIscsiAgentPort = "ISCSI_AGENT_PORT" + ENVEndpoint = "ENDPOINT" + ENVNodeName = "NODE_NAME" + ENVKubeVersion = "KUBE_VERSION" + EnvCallHomeSecretUsername = "CALL_HOME_SECRET_USERNAME" + EnvCALLHomeSecretPassword = "CALL_HOME_SECRET_PASSWORD" CSINodeDriverRegistrar = "csi-node-driver-registrar" CSIProvisioner = "csi-provisioner" From 54c26b640e8b00353bcfcd24e86c4450ca1d01d4 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 20 Feb 2022 12:53:58 +0200 Subject: [PATCH 25/69] changed secret dir --- controllers/syncer/csi_call_home.go | 2 +- pkg/config/constants.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index 584df907c..c93fa9a3f 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -199,7 +199,7 @@ func (s *callHomeSyncer) getVolumeMountsFor(name string) []corev1.VolumeMount { return []corev1.VolumeMount{ { Name: secretVolumeName, - MountPath: config.ControllerSocketVolumeMountPath, + MountPath: config.CallHomeSocketVolumeMountPath, }, } } diff --git a/pkg/config/constants.go b/pkg/config/constants.go index 35f848647..bbe3d3bd2 100644 --- a/pkg/config/constants.go +++ b/pkg/config/constants.go @@ -44,6 +44,7 @@ const ( ControllerSocketVolumeMountPath = "/var/lib/csi/sockets/pluginproxy/" NodeSocketVolumeMountPath = "/csi" + CallHomeSecretVolumeMountPath = "/etc/secret-dir" ControllerLivenessProbeContainerSocketVolumeMountPath = "/csi" ControllerSocketPath = "/var/lib/csi/sockets/pluginproxy/csi.sock" NodeSocketPath = "/csi/csi.sock" From 1eea28bcd20c89893c6a3a41fc253f33fbae1641 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 20 Feb 2022 12:59:36 +0200 Subject: [PATCH 26/69] fix name --- controllers/syncer/csi_call_home.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index c93fa9a3f..c2e6346ad 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -199,7 +199,7 @@ func (s *callHomeSyncer) getVolumeMountsFor(name string) []corev1.VolumeMount { return []corev1.VolumeMount{ { Name: secretVolumeName, - MountPath: config.CallHomeSocketVolumeMountPath, + MountPath: config.CallHomeSecretVolumeMountPath, }, } } From 2cbab21df0b07dae3d2985c1d363f086413c38e4 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 20 Feb 2022 13:30:33 +0200 Subject: [PATCH 27/69] remove env var --- controllers/syncer/csi_call_home.go | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index c2e6346ad..3bdd75350 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -150,22 +150,6 @@ func (s *callHomeSyncer) ensureContainer(name, image string, args []string) core } } -func (s *callHomeSyncer) envVarFromSecret(sctName, name, key string, opt bool) corev1.EnvVar { - env := corev1.EnvVar{ - Name: name, - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{ - Name: sctName, - }, - Key: key, - Optional: &opt, - }, - }, - } - return env -} - func (s *callHomeSyncer) getEnvFor(name string) []corev1.EnvVar { return []corev1.EnvVar{ @@ -177,18 +161,6 @@ func (s *callHomeSyncer) getEnvFor(name string) []corev1.EnvVar { Name: "CSI_LOGLEVEL", Value: config.DefaultLogLevel, }, - s.envVarFromSecret( - s.driver.Spec.CallHome.SecretName, - config.EnvCallHomeSecretUsername, - secretUsernameKey, - false, - ), - s.envVarFromSecret( - s.driver.Spec.CallHome.SecretName, - config.EnvCALLHomeSecretPassword, - secretPasswordKey, - false, - ), } } From 992b4213399c6a4117fe0f0f06b55ca0b69a9d7d Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 20 Feb 2022 15:33:52 +0200 Subject: [PATCH 28/69] PR --- controllers/ibmblockcsi_controller.go | 6 ++-- .../internal/ibmblockcsi/ibmblockcsi.go | 22 +++----------- .../ibmblockcsi/static_resource_generator.go | 1 - controllers/syncer/csi_call_home.go | 30 +++++++------------ controllers/syncer/csi_controller.go | 2 +- controllers/syncer/csi_node.go | 2 +- pkg/config/constants.go | 9 ++---- 7 files changed, 22 insertions(+), 50 deletions(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 4235c86db..94864e0ed 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -548,13 +548,13 @@ func (r *IBMBlockCSIReconciler) getNodeDaemonSet(instance *ibmblockcsi.IBMBlockC } func (r *IBMBlockCSIReconciler) getCallHomeCronJob(instance *ibmblockcsi.IBMBlockCSI) (*batchv1.CronJob, error) { - CallHome := &batchv1.CronJob{} + callHome := &batchv1.CronJob{} err := r.Get(context.TODO(), types.NamespacedName{ Name: oconfig.GetNameForResource(oconfig.CallHome, instance.Name), Namespace: instance.Namespace, - }, CallHome) + }, callHome) - return CallHome, err + return callHome, err } func (r *IBMBlockCSIReconciler) isControllerReady(controller *appsv1.StatefulSet) bool { diff --git a/controllers/internal/ibmblockcsi/ibmblockcsi.go b/controllers/internal/ibmblockcsi/ibmblockcsi.go index 8ebbf91ca..229abfd37 100644 --- a/controllers/internal/ibmblockcsi/ibmblockcsi.go +++ b/controllers/internal/ibmblockcsi/ibmblockcsi.go @@ -121,25 +121,11 @@ func (c *IBMBlockCSI) GetCallHomePodLabels() labels.Set { return labels.Merge(c.GetLabels(), c.GetCallHomeSelectorLabels()) } -func (c *IBMBlockCSI) GetCSIControllerImage() string { - if c.Spec.Controller.Tag == "" { - return c.Spec.Controller.Repository +func (c *IBMBlockCSI) GetComponentImage(repository string, tag string) string { + if tag == "" { + return repository } - return c.Spec.Controller.Repository + ":" + c.Spec.Controller.Tag -} - -func (c *IBMBlockCSI) GetCSINodeImage() string { - if c.Spec.Node.Tag == "" { - return c.Spec.Node.Repository - } - return c.Spec.Node.Repository + ":" + c.Spec.Node.Tag -} - -func (c *IBMBlockCSI) GetCallHomeImage() string { - if c.Spec.CallHome.Tag == "" { - return c.Spec.CallHome.Repository - } - return c.Spec.CallHome.Repository + ":" + c.Spec.CallHome.Tag + return repository + ":" + tag } func (c *IBMBlockCSI) GetDefaultSidecarImageByName(name string) string { diff --git a/controllers/internal/ibmblockcsi/static_resource_generator.go b/controllers/internal/ibmblockcsi/static_resource_generator.go index ed5725874..56dd5676b 100644 --- a/controllers/internal/ibmblockcsi/static_resource_generator.go +++ b/controllers/internal/ibmblockcsi/static_resource_generator.go @@ -109,7 +109,6 @@ func (c *IBMBlockCSI) GenerateNodeServiceAccount() *corev1.ServiceAccount { } } func (c *IBMBlockCSI) GenerateCallHomeServiceAccount() *corev1.ServiceAccount { - return &corev1.ServiceAccount{ ObjectMeta: metav1.ObjectMeta{ Name: config.GetNameForResource(config.CallHomeServiceAccount, c.Name), diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/csi_call_home.go index 3bdd75350..6afa8a10e 100644 --- a/controllers/syncer/csi_call_home.go +++ b/controllers/syncer/csi_call_home.go @@ -34,8 +34,6 @@ import ( const ( callHomeContainerName = "ibm-block-csi-call-home" secretVolumeName = "secret-dir" - secretUsernameKey = "username" - secretPasswordKey = "password" defaultCronSchedule = "0 0 * *" ) @@ -68,9 +66,6 @@ func NewCallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmblock func (s *callHomeSyncer) SyncFn() error { out := s.obj.(*batchv1.CronJob) - //out.Spec.JobTemplate.Spec.Selector = metav1.SetAsLabelSelector(s.driver.GetCallHomeSelectorLabels()) - //out.Spec.ServiceName = config.GetNameForResource(config.CallHome, s.driver.Name) - //Run once a day at midnight out.Spec.Schedule = s.getCallHomeSchedule() @@ -114,7 +109,7 @@ func (s *callHomeSyncer) ensurePodSpec() corev1.PodSpec { func (s *callHomeSyncer) ensureContainersSpec() []corev1.Container { callHomePlugin := s.ensureContainer(callHomeContainerName, - s.driver.GetCallHomeImage(), + s.driver.GetComponentImage(s.driver.Spec.CallHome.Repository, s.driver.Spec.CallHome.Tag), []string{"--csi-endpoint=$(CSI_ENDPOINT)"}, ) @@ -143,14 +138,14 @@ func (s *callHomeSyncer) ensureContainer(name, image string, args []string) core Name: name, Image: image, Args: args, - Env: s.getEnvFor(name), - VolumeMounts: s.getVolumeMountsFor(name), + Env: s.getEnv(), + VolumeMounts: s.getVolumeMounts(), SecurityContext: sc, Resources: ensureDefaultResources(), } } -func (s *callHomeSyncer) getEnvFor(name string) []corev1.EnvVar { +func (s *callHomeSyncer) getEnv() []corev1.EnvVar { return []corev1.EnvVar{ { @@ -165,17 +160,14 @@ func (s *callHomeSyncer) getEnvFor(name string) []corev1.EnvVar { } -func (s *callHomeSyncer) getVolumeMountsFor(name string) []corev1.VolumeMount { - switch name { - case callHomeContainerName: - return []corev1.VolumeMount{ - { - Name: secretVolumeName, - MountPath: config.CallHomeSecretVolumeMountPath, - }, - } +func (s *callHomeSyncer) getVolumeMounts() []corev1.VolumeMount { + return []corev1.VolumeMount{ + { + Name: secretVolumeName, + MountPath: config.CallHomeSecretVolumeMountPath, + }, } - return nil + } func (s *callHomeSyncer) ensureVolumes() []corev1.Volume { diff --git a/controllers/syncer/csi_controller.go b/controllers/syncer/csi_controller.go index 0f85f0cac..b5b57e7f7 100644 --- a/controllers/syncer/csi_controller.go +++ b/controllers/syncer/csi_controller.go @@ -113,7 +113,7 @@ func (s *csiControllerSyncer) ensurePodSpec() corev1.PodSpec { func (s *csiControllerSyncer) ensureContainersSpec() []corev1.Container { controllerPlugin := s.ensureContainer(controllerContainerName, - s.driver.GetCSIControllerImage(), + s.driver.GetComponentImage(s.driver.Spec.Controller.Repository, s.driver.Spec.Controller.Tag), []string{"--csi-endpoint=$(CSI_ENDPOINT)"}, ) diff --git a/controllers/syncer/csi_node.go b/controllers/syncer/csi_node.go index 040afb007..0286da5a6 100644 --- a/controllers/syncer/csi_node.go +++ b/controllers/syncer/csi_node.go @@ -106,7 +106,7 @@ func (s *csiNodeSyncer) ensurePodSpec() corev1.PodSpec { func (s *csiNodeSyncer) ensureContainersSpec() []corev1.Container { // node plugin container nodePlugin := s.ensureContainer(nodeContainerName, - s.driver.GetCSINodeImage(), + s.driver.GetComponentImage(s.driver.Spec.Node.Repository, s.driver.Spec.Node.Tag), []string{ "--csi-endpoint=$(CSI_ENDPOINT)", "--hostname=$(KUBE_NODE_NAME)", diff --git a/pkg/config/constants.go b/pkg/config/constants.go index bbe3d3bd2..e42dbe460 100644 --- a/pkg/config/constants.go +++ b/pkg/config/constants.go @@ -27,12 +27,7 @@ const ( NodeAgentRepository = "ibmcom/ibm-node-agent" - ENVIscsiAgentPort = "ISCSI_AGENT_PORT" - ENVEndpoint = "ENDPOINT" - ENVNodeName = "NODE_NAME" - ENVKubeVersion = "KUBE_VERSION" - EnvCallHomeSecretUsername = "CALL_HOME_SECRET_USERNAME" - EnvCALLHomeSecretPassword = "CALL_HOME_SECRET_PASSWORD" + ENVKubeVersion = "KUBE_VERSION" CSINodeDriverRegistrar = "csi-node-driver-registrar" CSIProvisioner = "csi-provisioner" @@ -44,7 +39,7 @@ const ( ControllerSocketVolumeMountPath = "/var/lib/csi/sockets/pluginproxy/" NodeSocketVolumeMountPath = "/csi" - CallHomeSecretVolumeMountPath = "/etc/secret-dir" + CallHomeSecretVolumeMountPath = "/etc/call-home-secret-dir" ControllerLivenessProbeContainerSocketVolumeMountPath = "/csi" ControllerSocketPath = "/var/lib/csi/sockets/pluginproxy/csi.sock" NodeSocketPath = "/csi/csi.sock" From 8dfd762f0c4068e0ae5ed2d04b0fc07b19764dda Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 20 Feb 2022 15:35:32 +0200 Subject: [PATCH 29/69] PR --- config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml index a23cc592f..366d38df2 100644 --- a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml +++ b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml @@ -47,7 +47,7 @@ spec: # callHome is a statefulSet with ibm-block-csi-call-home container # callHome: -# repository: stg-artifactory.xiv.ibm.com:5030/ibm-block-csi-call-home-amd64 +# repository: ibmcom/ibm-block-csi-call-home # tag: "1.9.0" # imagePullPolicy: IfNotPresent # secretName: demo-secret From 558e3af83d3c6cc8f47dd78b950586bfa57edb82 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 20 Feb 2022 16:06:56 +0200 Subject: [PATCH 30/69] PR --- config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml index 366d38df2..2a279fda8 100644 --- a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml +++ b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml @@ -50,7 +50,7 @@ spec: # repository: ibmcom/ibm-block-csi-call-home # tag: "1.9.0" # imagePullPolicy: IfNotPresent -# secretName: demo-secret +# secretName: demo-call-home-secret # affinity: # nodeAffinity: # requiredDuringSchedulingIgnoredDuringExecution: From 8b19abd64fd6765540c3ba6d5e5490ffedc2ee08 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 21 Feb 2022 10:55:24 +0200 Subject: [PATCH 31/69] PR --- controllers/syncer/{csi_call_home.go => call_home.go} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename controllers/syncer/{csi_call_home.go => call_home.go} (100%) diff --git a/controllers/syncer/csi_call_home.go b/controllers/syncer/call_home.go similarity index 100% rename from controllers/syncer/csi_call_home.go rename to controllers/syncer/call_home.go From eaae53b2431ab521974dc355621a155c33cbf699 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 21 Feb 2022 11:02:02 +0200 Subject: [PATCH 32/69] PR --- controllers/internal/ibmblockcsi/ibmblockcsi.go | 12 ++++++++++++ controllers/syncer/call_home.go | 2 +- controllers/syncer/csi_controller.go | 2 +- controllers/syncer/csi_node.go | 2 +- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/controllers/internal/ibmblockcsi/ibmblockcsi.go b/controllers/internal/ibmblockcsi/ibmblockcsi.go index 229abfd37..9462d02e0 100644 --- a/controllers/internal/ibmblockcsi/ibmblockcsi.go +++ b/controllers/internal/ibmblockcsi/ibmblockcsi.go @@ -128,6 +128,18 @@ func (c *IBMBlockCSI) GetComponentImage(repository string, tag string) string { return repository + ":" + tag } +func (c *IBMBlockCSI) GetCSIControllerImage() string { + return c.GetComponentImage(c.Spec.Controller.Repository, c.Spec.Controller.Tag) +} + +func (c *IBMBlockCSI) GetCSINodeImage() string { + return c.GetComponentImage(c.Spec.Node.Repository, c.Spec.Node.Tag) +} + +func (c *IBMBlockCSI) GetCallHomeImage() string { + return c.GetComponentImage(c.Spec.CallHome.Repository, c.Spec.CallHome.Tag) +} + func (c *IBMBlockCSI) GetDefaultSidecarImageByName(name string) string { if sidecar, found := config.DefaultSidecarsByName[name]; found { return fmt.Sprintf("%s:%s", sidecar.Repository, sidecar.Tag) diff --git a/controllers/syncer/call_home.go b/controllers/syncer/call_home.go index 6afa8a10e..73529686a 100644 --- a/controllers/syncer/call_home.go +++ b/controllers/syncer/call_home.go @@ -109,7 +109,7 @@ func (s *callHomeSyncer) ensurePodSpec() corev1.PodSpec { func (s *callHomeSyncer) ensureContainersSpec() []corev1.Container { callHomePlugin := s.ensureContainer(callHomeContainerName, - s.driver.GetComponentImage(s.driver.Spec.CallHome.Repository, s.driver.Spec.CallHome.Tag), + s.driver.GetCallHomeImage(), []string{"--csi-endpoint=$(CSI_ENDPOINT)"}, ) diff --git a/controllers/syncer/csi_controller.go b/controllers/syncer/csi_controller.go index b5b57e7f7..0f85f0cac 100644 --- a/controllers/syncer/csi_controller.go +++ b/controllers/syncer/csi_controller.go @@ -113,7 +113,7 @@ func (s *csiControllerSyncer) ensurePodSpec() corev1.PodSpec { func (s *csiControllerSyncer) ensureContainersSpec() []corev1.Container { controllerPlugin := s.ensureContainer(controllerContainerName, - s.driver.GetComponentImage(s.driver.Spec.Controller.Repository, s.driver.Spec.Controller.Tag), + s.driver.GetCSIControllerImage(), []string{"--csi-endpoint=$(CSI_ENDPOINT)"}, ) diff --git a/controllers/syncer/csi_node.go b/controllers/syncer/csi_node.go index 0286da5a6..040afb007 100644 --- a/controllers/syncer/csi_node.go +++ b/controllers/syncer/csi_node.go @@ -106,7 +106,7 @@ func (s *csiNodeSyncer) ensurePodSpec() corev1.PodSpec { func (s *csiNodeSyncer) ensureContainersSpec() []corev1.Container { // node plugin container nodePlugin := s.ensureContainer(nodeContainerName, - s.driver.GetComponentImage(s.driver.Spec.Node.Repository, s.driver.Spec.Node.Tag), + s.driver.GetCSINodeImage(), []string{ "--csi-endpoint=$(CSI_ENDPOINT)", "--hostname=$(KUBE_NODE_NAME)", From 61c3f1e5e9bcff15c92b3b490ba47451f2e7fce0 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 21 Feb 2022 13:35:01 +0200 Subject: [PATCH 33/69] PR --- controllers/syncer/call_home.go | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/controllers/syncer/call_home.go b/controllers/syncer/call_home.go index 73529686a..57ca0379b 100644 --- a/controllers/syncer/call_home.go +++ b/controllers/syncer/call_home.go @@ -33,8 +33,8 @@ import ( const ( callHomeContainerName = "ibm-block-csi-call-home" - secretVolumeName = "secret-dir" - defaultCronSchedule = "0 0 * *" + secretVolumeName = "call-home-secret-dir" + cronSchedule = "0 0 * *" ) type callHomeSyncer struct { @@ -67,7 +67,7 @@ func (s *callHomeSyncer) SyncFn() error { out := s.obj.(*batchv1.CronJob) //Run once a day at midnight - out.Spec.Schedule = s.getCallHomeSchedule() + out.Spec.Schedule = cronSchedule // ensure template out.Spec.JobTemplate.ObjectMeta.Labels = s.driver.GetCallHomePodLabels() @@ -84,13 +84,6 @@ func (s *callHomeSyncer) SyncFn() error { return nil } -func (s *callHomeSyncer) getCallHomeSchedule() string { - if s.driver.Spec.CallHome.Schedule == "" { - return defaultCronSchedule - } - return s.driver.Spec.CallHome.Schedule -} - func (s *callHomeSyncer) ensurePodSpec() corev1.PodSpec { fsGroup := config.ControllerUserID return corev1.PodSpec{ From 5a0b70eab228009eb58fe6149fdbdf4a8e643343 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 21 Feb 2022 17:35:25 +0200 Subject: [PATCH 34/69] manage cronjob PR --- controllers/ibmblockcsi_controller.go | 3 ++- controllers/syncer/call_home.go | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 94864e0ed..e1825301e 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -240,6 +240,7 @@ func (r *IBMBlockCSIReconciler) SetupWithManager(mgr ctrl.Manager) error { Owns(&appsv1.StatefulSet{}). Owns(&appsv1.DaemonSet{}). Owns(&corev1.ServiceAccount{}). + Owns(&batchv1.CronJob{}). Complete(r) } @@ -566,7 +567,7 @@ func (r *IBMBlockCSIReconciler) isNodeReady(node *appsv1.DaemonSet) bool { } func (r *IBMBlockCSIReconciler) isCallHomeReady(callHome *batchv1.CronJob) bool { - return len(callHome.Status.Active) == len(callHome.Status.Active) + return callHome.Spec.Schedule == clustersyncer.CronSchedule } func (r *IBMBlockCSIReconciler) reconcileClusterRole(instance *ibmblockcsi.IBMBlockCSI) error { diff --git a/controllers/syncer/call_home.go b/controllers/syncer/call_home.go index 57ca0379b..31b3dac5c 100644 --- a/controllers/syncer/call_home.go +++ b/controllers/syncer/call_home.go @@ -34,7 +34,7 @@ import ( const ( callHomeContainerName = "ibm-block-csi-call-home" secretVolumeName = "call-home-secret-dir" - cronSchedule = "0 0 * *" + CronSchedule = "0 0 * *" ) type callHomeSyncer struct { @@ -67,7 +67,7 @@ func (s *callHomeSyncer) SyncFn() error { out := s.obj.(*batchv1.CronJob) //Run once a day at midnight - out.Spec.Schedule = cronSchedule + out.Spec.Schedule = CronSchedule // ensure template out.Spec.JobTemplate.ObjectMeta.Labels = s.driver.GetCallHomePodLabels() From 2b0048f2bb1aecef3e9bb588fdbf578fecc76947 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 21 Feb 2022 17:52:14 +0200 Subject: [PATCH 35/69] fix cron --- controllers/syncer/call_home.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/syncer/call_home.go b/controllers/syncer/call_home.go index 31b3dac5c..bf7be2fff 100644 --- a/controllers/syncer/call_home.go +++ b/controllers/syncer/call_home.go @@ -34,7 +34,7 @@ import ( const ( callHomeContainerName = "ibm-block-csi-call-home" secretVolumeName = "call-home-secret-dir" - CronSchedule = "0 0 * *" + CronSchedule = "0 0 * * *" ) type callHomeSyncer struct { From 2b8a8c3b2b944db3212fb497517b3586276cced8 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 21 Feb 2022 17:57:10 +0200 Subject: [PATCH 36/69] fix callHome type --- api/v1/ibmblockcsi_types.go | 4 ---- config/crd/bases/csi.ibm.com_ibmblockcsis.yaml | 3 --- deploy/installer/generated/ibm-block-csi-operator.yaml | 3 --- 3 files changed, 10 deletions(-) diff --git a/api/v1/ibmblockcsi_types.go b/api/v1/ibmblockcsi_types.go index 607c2c0d0..7f80c2c72 100644 --- a/api/v1/ibmblockcsi_types.go +++ b/api/v1/ibmblockcsi_types.go @@ -125,10 +125,6 @@ type IBMBlockCSICallHomeSpec struct { // +kubebuilder:validation:Optional ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy"` - // The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. - // +kubebuilder:validation:Optional - Schedule string `json:"schedule" protobuf:"bytes,1,opt,name=schedule"` - // +kubebuilder:validation:Optional Affinity *corev1.Affinity `json:"affinity,omitempty"` diff --git a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml index 8375ecaf5..8a0e83fc1 100644 --- a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml +++ b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml @@ -507,9 +507,6 @@ spec: type: string repository: type: string - schedule: - description: The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. - type: string secretName: type: string tag: diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index a6323c474..618185f79 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -507,9 +507,6 @@ spec: type: string repository: type: string - schedule: - description: The schedule in Cron format, see https://en.wikipedia.org/wiki/Cron. - type: string secretName: type: string tag: From 29534fb773b77d5be0c4f94cca6f9df5b4ecc197 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 23 Feb 2022 10:26:17 +0200 Subject: [PATCH 37/69] PR --- api/v1/ibmblockcsi_types.go | 1 - .../crd/bases/csi.ibm.com_ibmblockcsis.yaml | 3 -- config/rbac/role.yaml | 6 ---- controllers/ibmblockcsi_controller.go | 30 ++++--------------- controllers/syncer/call_home.go | 7 +++-- .../generated/ibm-block-csi-operator.yaml | 9 ------ 6 files changed, 10 insertions(+), 46 deletions(-) diff --git a/api/v1/ibmblockcsi_types.go b/api/v1/ibmblockcsi_types.go index 7f80c2c72..645343c5b 100644 --- a/api/v1/ibmblockcsi_types.go +++ b/api/v1/ibmblockcsi_types.go @@ -138,7 +138,6 @@ type IBMBlockCSIStatus struct { Phase DriverPhase `json:"phase"` ControllerReady bool `json:"controllerReady"` NodeReady bool `json:"nodeReady"` - CallHomeReady bool `json:"callHomeReady"` // Version is the current driver version Version string `json:"version"` diff --git a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml index 8a0e83fc1..7888d18ac 100644 --- a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml +++ b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml @@ -1566,8 +1566,6 @@ spec: status: description: IBMBlockCSIStatus defines the observed state of IBMBlockCSI properties: - callHomeReady: - type: boolean controllerReady: type: boolean nodeReady: @@ -1579,7 +1577,6 @@ spec: description: Version is the current driver version type: string required: - - callHomeReady - controllerReady - nodeReady - phase diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 859153857..2443b2d56 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -34,12 +34,6 @@ rules: - get - list - watch -- apiGroups: - - "" - resources: - - namespaces - verbs: - - get - apiGroups: - batch resources: diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index e1825301e..a8a61ce10 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -194,9 +194,11 @@ func (r *IBMBlockCSIReconciler) Reconcile(ctx context.Context, req ctrl.Request) return reconcile.Result{}, err } - callHomeSyncer := clustersyncer.NewCallHomeSyncer(r.Client, r.Scheme, instance) - if err := syncer.Sync(context.TODO(), callHomeSyncer, r.Recorder); err != nil { - return reconcile.Result{}, err + if instance.Spec.CallHome.SecretName != "" { + callHomeSyncer := clustersyncer.NewCallHomeSyncer(r.Client, r.Scheme, instance) + if err := syncer.Sync(context.TODO(), callHomeSyncer, r.Recorder); err != nil { + return reconcile.Result{}, err + } } if err := r.updateStatus(instance, originalStatus); err != nil { @@ -315,16 +317,10 @@ func (r *IBMBlockCSIReconciler) updateStatus(instance *ibmblockcsi.IBMBlockCSI, return err } - callHomeCronJob, err := r.getCallHomeCronJob(instance) - if err != nil { - return err - } - instance.Status.ControllerReady = r.isControllerReady(controllerStatefulset) instance.Status.NodeReady = r.isNodeReady(nodeDaemonSet) - instance.Status.CallHomeReady = r.isCallHomeReady(callHomeCronJob) phase := csiv1.DriverPhaseNone - if instance.Status.ControllerReady && instance.Status.NodeReady && instance.Status.CallHomeReady { + if instance.Status.ControllerReady && instance.Status.NodeReady { phase = csiv1.DriverPhaseRunning } else { if !instance.Status.ControllerReady { @@ -548,16 +544,6 @@ func (r *IBMBlockCSIReconciler) getNodeDaemonSet(instance *ibmblockcsi.IBMBlockC return node, err } -func (r *IBMBlockCSIReconciler) getCallHomeCronJob(instance *ibmblockcsi.IBMBlockCSI) (*batchv1.CronJob, error) { - callHome := &batchv1.CronJob{} - err := r.Get(context.TODO(), types.NamespacedName{ - Name: oconfig.GetNameForResource(oconfig.CallHome, instance.Name), - Namespace: instance.Namespace, - }, callHome) - - return callHome, err -} - func (r *IBMBlockCSIReconciler) isControllerReady(controller *appsv1.StatefulSet) bool { return controller.Status.ReadyReplicas == controller.Status.Replicas } @@ -566,10 +552,6 @@ func (r *IBMBlockCSIReconciler) isNodeReady(node *appsv1.DaemonSet) bool { return node.Status.DesiredNumberScheduled == node.Status.NumberAvailable } -func (r *IBMBlockCSIReconciler) isCallHomeReady(callHome *batchv1.CronJob) bool { - return callHome.Spec.Schedule == clustersyncer.CronSchedule -} - func (r *IBMBlockCSIReconciler) reconcileClusterRole(instance *ibmblockcsi.IBMBlockCSI) error { logger := log.WithValues("Resource Type", "ClusterRole") diff --git a/controllers/syncer/call_home.go b/controllers/syncer/call_home.go index bf7be2fff..0ca1a2afd 100644 --- a/controllers/syncer/call_home.go +++ b/controllers/syncer/call_home.go @@ -35,6 +35,7 @@ const ( callHomeContainerName = "ibm-block-csi-call-home" secretVolumeName = "call-home-secret-dir" CronSchedule = "0 0 * * *" + jobsHistoryLimit = int32(1) ) type callHomeSyncer struct { @@ -66,15 +67,15 @@ func NewCallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmblock func (s *callHomeSyncer) SyncFn() error { out := s.obj.(*batchv1.CronJob) - //Run once a day at midnight + // "0 0 * * *" - Run once a day at midnight out.Spec.Schedule = CronSchedule // ensure template out.Spec.JobTemplate.ObjectMeta.Labels = s.driver.GetCallHomePodLabels() out.Spec.JobTemplate.ObjectMeta.Annotations = s.driver.GetAnnotations("", "") out.Spec.JobTemplate.Spec.Template.ObjectMeta.Labels = s.driver.GetCallHomePodLabels() - defaultSuccessfulJobsHistoryLimit := int32(1) - out.Spec.SuccessfulJobsHistoryLimit = &defaultSuccessfulJobsHistoryLimit + successfulJobsHistoryLimit := jobsHistoryLimit + out.Spec.SuccessfulJobsHistoryLimit = &successfulJobsHistoryLimit err := mergo.Merge(&out.Spec.JobTemplate.Spec.Template.Spec, s.ensurePodSpec(), mergo.WithTransformers(transformers.PodSpec)) if err != nil { diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index 618185f79..bcc70c9d3 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -1566,8 +1566,6 @@ spec: status: description: IBMBlockCSIStatus defines the observed state of IBMBlockCSI properties: - callHomeReady: - type: boolean controllerReady: type: boolean nodeReady: @@ -1579,7 +1577,6 @@ spec: description: Version is the current driver version type: string required: - - callHomeReady - controllerReady - nodeReady - phase @@ -1644,12 +1641,6 @@ rules: - get - list - watch -- apiGroups: - - "" - resources: - - namespaces - verbs: - - get - apiGroups: - batch resources: From be7116e458f26a2c73f252b047f129352fd9483e Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 23 Feb 2022 10:52:10 +0200 Subject: [PATCH 38/69] fix role --- config/rbac/role.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 2443b2d56..859153857 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -34,6 +34,12 @@ rules: - get - list - watch +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get - apiGroups: - batch resources: From 0b4fa9c4639b5e264f0581688bf669576ce2c75e Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 23 Feb 2022 10:56:59 +0200 Subject: [PATCH 39/69] fix role --- deploy/installer/generated/ibm-block-csi-operator.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index bcc70c9d3..b3b8766eb 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -1641,6 +1641,12 @@ rules: - get - list - watch +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get - apiGroups: - batch resources: From fa9d848ae0c157bdaa45185a94be56d352adc30b Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 23 Feb 2022 12:52:24 +0200 Subject: [PATCH 40/69] test readiness --- controllers/ibmblockcsi_controller.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index a8a61ce10..a6edb64a2 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -317,8 +317,14 @@ func (r *IBMBlockCSIReconciler) updateStatus(instance *ibmblockcsi.IBMBlockCSI, return err } + callHomeCronJob, err := r.getCallHomeCronJob(instance) + if err != nil { + return err + } + instance.Status.ControllerReady = r.isControllerReady(controllerStatefulset) instance.Status.NodeReady = r.isNodeReady(nodeDaemonSet) + r.isCallHomeReady(callHomeCronJob, logger) phase := csiv1.DriverPhaseNone if instance.Status.ControllerReady && instance.Status.NodeReady { phase = csiv1.DriverPhaseRunning @@ -544,6 +550,16 @@ func (r *IBMBlockCSIReconciler) getNodeDaemonSet(instance *ibmblockcsi.IBMBlockC return node, err } +func (r *IBMBlockCSIReconciler) getCallHomeCronJob(instance *ibmblockcsi.IBMBlockCSI) (*batchv1.CronJob, error) { + callHome := &batchv1.CronJob{} + err := r.Get(context.TODO(), types.NamespacedName{ + Name: oconfig.GetNameForResource(oconfig.CallHome, instance.Name), + Namespace: instance.Namespace, + }, callHome) + + return callHome, err +} + func (r *IBMBlockCSIReconciler) isControllerReady(controller *appsv1.StatefulSet) bool { return controller.Status.ReadyReplicas == controller.Status.Replicas } @@ -552,6 +568,11 @@ func (r *IBMBlockCSIReconciler) isNodeReady(node *appsv1.DaemonSet) bool { return node.Status.DesiredNumberScheduled == node.Status.NumberAvailable } +func (r *IBMBlockCSIReconciler) isCallHomeReady(callHome *batchv1.CronJob, logger logr.Logger) bool { + logger.Info("callHome instance: %v", callHome) + return callHome.Spec.Schedule == clustersyncer.CronSchedule +} + func (r *IBMBlockCSIReconciler) reconcileClusterRole(instance *ibmblockcsi.IBMBlockCSI) error { logger := log.WithValues("Resource Type", "ClusterRole") From 67b057f275669fb2d06825d12ce5c8527827b03a Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 23 Feb 2022 13:08:01 +0200 Subject: [PATCH 41/69] test readiness --- controllers/ibmblockcsi_controller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index a6edb64a2..22c209fd4 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -569,7 +569,7 @@ func (r *IBMBlockCSIReconciler) isNodeReady(node *appsv1.DaemonSet) bool { } func (r *IBMBlockCSIReconciler) isCallHomeReady(callHome *batchv1.CronJob, logger logr.Logger) bool { - logger.Info("callHome instance: %v", callHome) + logger.Info(fmt.Sprintf("callHome instance: %v", callHome)) return callHome.Spec.Schedule == clustersyncer.CronSchedule } From 356cd9ec5f0085cf22ee4c70803af060bccce55f Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 23 Feb 2022 13:30:50 +0200 Subject: [PATCH 42/69] test readiness --- controllers/ibmblockcsi_controller.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 22c209fd4..17d621cc7 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -324,7 +324,7 @@ func (r *IBMBlockCSIReconciler) updateStatus(instance *ibmblockcsi.IBMBlockCSI, instance.Status.ControllerReady = r.isControllerReady(controllerStatefulset) instance.Status.NodeReady = r.isNodeReady(nodeDaemonSet) - r.isCallHomeReady(callHomeCronJob, logger) + r.isCallHomeReady(callHomeCronJob, instance, logger) phase := csiv1.DriverPhaseNone if instance.Status.ControllerReady && instance.Status.NodeReady { phase = csiv1.DriverPhaseRunning @@ -568,8 +568,9 @@ func (r *IBMBlockCSIReconciler) isNodeReady(node *appsv1.DaemonSet) bool { return node.Status.DesiredNumberScheduled == node.Status.NumberAvailable } -func (r *IBMBlockCSIReconciler) isCallHomeReady(callHome *batchv1.CronJob, logger logr.Logger) bool { - logger.Info(fmt.Sprintf("callHome instance: %v", callHome)) +func (r *IBMBlockCSIReconciler) isCallHomeReady(callHome *batchv1.CronJob, instance *ibmblockcsi.IBMBlockCSI, logger logr.Logger) bool { + logger.Info(fmt.Sprintf("callHome object: %v", callHome)) + logger.Info(fmt.Sprintf("callHome instance: %v", instance.Spec.CallHome)) return callHome.Spec.Schedule == clustersyncer.CronSchedule } From 27941e8949ee0eb60fcc407c8fae6007e8c00710 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 23 Feb 2022 14:13:13 +0200 Subject: [PATCH 43/69] test readiness --- controllers/ibmblockcsi_controller.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 17d621cc7..b7cab6d9a 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -319,12 +319,16 @@ func (r *IBMBlockCSIReconciler) updateStatus(instance *ibmblockcsi.IBMBlockCSI, callHomeCronJob, err := r.getCallHomeCronJob(instance) if err != nil { - return err + logger.Info("failed to get call Home CronJob") + } else { + err = r.updateCallHomeStatus(instance, callHomeCronJob, logger) + if err != nil { + logger.Error(err, "failed to delete call home CronJob") + } } instance.Status.ControllerReady = r.isControllerReady(controllerStatefulset) instance.Status.NodeReady = r.isNodeReady(nodeDaemonSet) - r.isCallHomeReady(callHomeCronJob, instance, logger) phase := csiv1.DriverPhaseNone if instance.Status.ControllerReady && instance.Status.NodeReady { phase = csiv1.DriverPhaseRunning @@ -556,7 +560,6 @@ func (r *IBMBlockCSIReconciler) getCallHomeCronJob(instance *ibmblockcsi.IBMBloc Name: oconfig.GetNameForResource(oconfig.CallHome, instance.Name), Namespace: instance.Namespace, }, callHome) - return callHome, err } @@ -568,10 +571,12 @@ func (r *IBMBlockCSIReconciler) isNodeReady(node *appsv1.DaemonSet) bool { return node.Status.DesiredNumberScheduled == node.Status.NumberAvailable } -func (r *IBMBlockCSIReconciler) isCallHomeReady(callHome *batchv1.CronJob, instance *ibmblockcsi.IBMBlockCSI, logger logr.Logger) bool { - logger.Info(fmt.Sprintf("callHome object: %v", callHome)) - logger.Info(fmt.Sprintf("callHome instance: %v", instance.Spec.CallHome)) - return callHome.Spec.Schedule == clustersyncer.CronSchedule +func (r *IBMBlockCSIReconciler) updateCallHomeStatus(instance *ibmblockcsi.IBMBlockCSI, callHome *batchv1.CronJob, logger logr.Logger) error { + if instance.Spec.CallHome.SecretName == "" { + logger.Info("Deleting call home object") + return r.Delete(context.TODO(), callHome) + } + return nil } func (r *IBMBlockCSIReconciler) reconcileClusterRole(instance *ibmblockcsi.IBMBlockCSI) error { From c37fc4b98e1ccebf9a8dc3b7fac46f8ddb76b4a5 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 23 Feb 2022 14:29:23 +0200 Subject: [PATCH 44/69] PR --- controllers/ibmblockcsi_controller.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index b7cab6d9a..9e8a5d308 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -318,9 +318,7 @@ func (r *IBMBlockCSIReconciler) updateStatus(instance *ibmblockcsi.IBMBlockCSI, } callHomeCronJob, err := r.getCallHomeCronJob(instance) - if err != nil { - logger.Info("failed to get call Home CronJob") - } else { + if err == nil { err = r.updateCallHomeStatus(instance, callHomeCronJob, logger) if err != nil { logger.Error(err, "failed to delete call home CronJob") @@ -573,7 +571,7 @@ func (r *IBMBlockCSIReconciler) isNodeReady(node *appsv1.DaemonSet) bool { func (r *IBMBlockCSIReconciler) updateCallHomeStatus(instance *ibmblockcsi.IBMBlockCSI, callHome *batchv1.CronJob, logger logr.Logger) error { if instance.Spec.CallHome.SecretName == "" { - logger.Info("Deleting call home object") + logger.Info("deleting call home CronJob") return r.Delete(context.TODO(), callHome) } return nil From a3e605d4d3ed20cd113a58bd970389f28b34d81b Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 23 Feb 2022 14:35:52 +0200 Subject: [PATCH 45/69] test fsGroup --- controllers/syncer/call_home.go | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/controllers/syncer/call_home.go b/controllers/syncer/call_home.go index 0ca1a2afd..6e54733b4 100644 --- a/controllers/syncer/call_home.go +++ b/controllers/syncer/call_home.go @@ -34,7 +34,7 @@ import ( const ( callHomeContainerName = "ibm-block-csi-call-home" secretVolumeName = "call-home-secret-dir" - CronSchedule = "0 0 * * *" + CronSchedule = "1 * * * *" jobsHistoryLimit = int32(1) ) @@ -86,14 +86,9 @@ func (s *callHomeSyncer) SyncFn() error { } func (s *callHomeSyncer) ensurePodSpec() corev1.PodSpec { - fsGroup := config.ControllerUserID return corev1.PodSpec{ - Containers: s.ensureContainersSpec(), - Volumes: s.ensureVolumes(), - SecurityContext: &corev1.PodSecurityContext{ - FSGroup: &fsGroup, - RunAsUser: &fsGroup, - }, + Containers: s.ensureContainersSpec(), + Volumes: s.ensureVolumes(), ServiceAccountName: config.GetNameForResource(config.CallHomeServiceAccount, s.driver.Name), Affinity: s.driver.Spec.CallHome.Affinity, Tolerations: s.driver.Spec.CallHome.Tolerations, From b2fc678cda27b8629e5849982808b09a40dc6ef0 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 23 Feb 2022 14:49:20 +0200 Subject: [PATCH 46/69] test fsGroup --- controllers/syncer/call_home.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/syncer/call_home.go b/controllers/syncer/call_home.go index 6e54733b4..11290ef92 100644 --- a/controllers/syncer/call_home.go +++ b/controllers/syncer/call_home.go @@ -34,7 +34,7 @@ import ( const ( callHomeContainerName = "ibm-block-csi-call-home" secretVolumeName = "call-home-secret-dir" - CronSchedule = "1 * * * *" + CronSchedule = "*/2 * * * *" jobsHistoryLimit = int32(1) ) From 4bbcda44daff786be5f44092968d57c32cce19fe Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 23 Feb 2022 15:01:09 +0200 Subject: [PATCH 47/69] PR --- controllers/syncer/call_home.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/syncer/call_home.go b/controllers/syncer/call_home.go index 11290ef92..b92951fa0 100644 --- a/controllers/syncer/call_home.go +++ b/controllers/syncer/call_home.go @@ -34,7 +34,7 @@ import ( const ( callHomeContainerName = "ibm-block-csi-call-home" secretVolumeName = "call-home-secret-dir" - CronSchedule = "*/2 * * * *" + CronSchedule = "0 0 * * *" jobsHistoryLimit = int32(1) ) From 4848247c221dd40503624d3a49196f2739cca6ba Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 23 Feb 2022 15:07:11 +0200 Subject: [PATCH 48/69] PR --- controllers/syncer/call_home.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/controllers/syncer/call_home.go b/controllers/syncer/call_home.go index b92951fa0..0e0929ca9 100644 --- a/controllers/syncer/call_home.go +++ b/controllers/syncer/call_home.go @@ -34,8 +34,9 @@ import ( const ( callHomeContainerName = "ibm-block-csi-call-home" secretVolumeName = "call-home-secret-dir" - CronSchedule = "0 0 * * *" - jobsHistoryLimit = int32(1) + // CronSchedule - run once a day at midnight + CronSchedule = "0 0 * * *" + jobsHistoryLimit = int32(1) ) type callHomeSyncer struct { @@ -67,7 +68,6 @@ func NewCallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmblock func (s *callHomeSyncer) SyncFn() error { out := s.obj.(*batchv1.CronJob) - // "0 0 * * *" - Run once a day at midnight out.Spec.Schedule = CronSchedule // ensure template From 43dc5502d43cfbef3e93667a62c37e6f9245e2f8 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 23 Feb 2022 15:08:12 +0200 Subject: [PATCH 49/69] PR --- controllers/syncer/call_home.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/syncer/call_home.go b/controllers/syncer/call_home.go index 0e0929ca9..a809882fb 100644 --- a/controllers/syncer/call_home.go +++ b/controllers/syncer/call_home.go @@ -34,7 +34,7 @@ import ( const ( callHomeContainerName = "ibm-block-csi-call-home" secretVolumeName = "call-home-secret-dir" - // CronSchedule - run once a day at midnight + // CronSchedule runs once a day at midnight CronSchedule = "0 0 * * *" jobsHistoryLimit = int32(1) ) From f228e83276576e0681502f8aa4346d9072aeaaf5 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Wed, 23 Feb 2022 16:23:40 +0200 Subject: [PATCH 50/69] PR --- controllers/syncer/call_home.go | 29 +++++++---------------------- 1 file changed, 7 insertions(+), 22 deletions(-) diff --git a/controllers/syncer/call_home.go b/controllers/syncer/call_home.go index a809882fb..2e90d0fd5 100644 --- a/controllers/syncer/call_home.go +++ b/controllers/syncer/call_home.go @@ -34,9 +34,8 @@ import ( const ( callHomeContainerName = "ibm-block-csi-call-home" secretVolumeName = "call-home-secret-dir" - // CronSchedule runs once a day at midnight - CronSchedule = "0 0 * * *" - jobsHistoryLimit = int32(1) + CronSchedule = "0 0 * * *" // runs once a day at midnight + jobsHistoryLimit = int32(1) ) type callHomeSyncer struct { @@ -97,26 +96,17 @@ func (s *callHomeSyncer) ensurePodSpec() corev1.PodSpec { } func (s *callHomeSyncer) ensureContainersSpec() []corev1.Container { - callHomePlugin := s.ensureContainer(callHomeContainerName, + callHomeContainer := s.ensureContainer(callHomeContainerName, s.driver.GetCallHomeImage(), - []string{"--csi-endpoint=$(CSI_ENDPOINT)"}, + []string{""}, ) - callHomePlugin.Resources = ensureResources("40m", "800m", "40Mi", "400Mi") + callHomeContainer.Resources = ensureResources("40m", "800m", "40Mi", "400Mi") - healthPort := s.driver.Spec.HealthPort - if healthPort == 0 { - healthPort = controllerContainerDefaultHealthPortNumber - } - - callHomePlugin.Ports = ensurePorts(corev1.ContainerPort{ - Name: controllerContainerHealthPortName, - ContainerPort: int32(healthPort), - }) - callHomePlugin.ImagePullPolicy = s.driver.Spec.CallHome.ImagePullPolicy + callHomeContainer.ImagePullPolicy = s.driver.Spec.CallHome.ImagePullPolicy return []corev1.Container{ - callHomePlugin, + callHomeContainer, } } @@ -135,12 +125,7 @@ func (s *callHomeSyncer) ensureContainer(name, image string, args []string) core } func (s *callHomeSyncer) getEnv() []corev1.EnvVar { - return []corev1.EnvVar{ - { - Name: "CSI_ENDPOINT", - Value: config.CSIEndpoint, - }, { Name: "CSI_LOGLEVEL", Value: config.DefaultLogLevel, From c3a472d58462b2893945fbafdd869abbb4641435 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Thu, 24 Feb 2022 15:40:13 +0200 Subject: [PATCH 51/69] remove secret volume --- controllers/syncer/call_home.go | 22 +++------------------- pkg/config/constants.go | 1 - 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/controllers/syncer/call_home.go b/controllers/syncer/call_home.go index 2e90d0fd5..f3258c17a 100644 --- a/controllers/syncer/call_home.go +++ b/controllers/syncer/call_home.go @@ -17,6 +17,7 @@ package syncer import ( + csiversion "github.com/IBM/ibm-block-csi-operator/version" "github.com/imdario/mergo" batchv1 "k8s.io/api/batch/v1" corev1 "k8s.io/api/core/v1" @@ -33,7 +34,6 @@ import ( const ( callHomeContainerName = "ibm-block-csi-call-home" - secretVolumeName = "call-home-secret-dir" CronSchedule = "0 0 * * *" // runs once a day at midnight jobsHistoryLimit = int32(1) ) @@ -87,7 +87,6 @@ func (s *callHomeSyncer) SyncFn() error { func (s *callHomeSyncer) ensurePodSpec() corev1.PodSpec { return corev1.PodSpec{ Containers: s.ensureContainersSpec(), - Volumes: s.ensureVolumes(), ServiceAccountName: config.GetNameForResource(config.CallHomeServiceAccount, s.driver.Name), Affinity: s.driver.Spec.CallHome.Affinity, Tolerations: s.driver.Spec.CallHome.Tolerations, @@ -118,7 +117,6 @@ func (s *callHomeSyncer) ensureContainer(name, image string, args []string) core Image: image, Args: args, Env: s.getEnv(), - VolumeMounts: s.getVolumeMounts(), SecurityContext: sc, Resources: ensureDefaultResources(), } @@ -130,24 +128,10 @@ func (s *callHomeSyncer) getEnv() []corev1.EnvVar { Name: "CSI_LOGLEVEL", Value: config.DefaultLogLevel, }, - } - -} - -func (s *callHomeSyncer) getVolumeMounts() []corev1.VolumeMount { - return []corev1.VolumeMount{ { - Name: secretVolumeName, - MountPath: config.CallHomeSecretVolumeMountPath, + Name: "CSI_VERSION", + Value: csiversion.Version, }, } } - -func (s *callHomeSyncer) ensureVolumes() []corev1.Volume { - return []corev1.Volume{ - ensureVolume(secretVolumeName, corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{SecretName: s.driver.Spec.CallHome.SecretName}, - }), - } -} diff --git a/pkg/config/constants.go b/pkg/config/constants.go index e42dbe460..cc24a2ccb 100644 --- a/pkg/config/constants.go +++ b/pkg/config/constants.go @@ -39,7 +39,6 @@ const ( ControllerSocketVolumeMountPath = "/var/lib/csi/sockets/pluginproxy/" NodeSocketVolumeMountPath = "/csi" - CallHomeSecretVolumeMountPath = "/etc/call-home-secret-dir" ControllerLivenessProbeContainerSocketVolumeMountPath = "/csi" ControllerSocketPath = "/var/lib/csi/sockets/pluginproxy/csi.sock" NodeSocketPath = "/csi/csi.sock" From 8f538381d56b0c1008c722f90ed37e202f345c91 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Thu, 24 Feb 2022 16:51:37 +0200 Subject: [PATCH 52/69] remove secret volume --- api/v1/ibmblockcsi_types.go | 2 -- config/crd/bases/csi.ibm.com_ibmblockcsis.yaml | 3 --- config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml | 1 - deploy/installer/generated/ibm-block-csi-operator.yaml | 3 --- 4 files changed, 9 deletions(-) diff --git a/api/v1/ibmblockcsi_types.go b/api/v1/ibmblockcsi_types.go index 645343c5b..eb7a8b6d9 100644 --- a/api/v1/ibmblockcsi_types.go +++ b/api/v1/ibmblockcsi_types.go @@ -120,8 +120,6 @@ type IBMBlockCSICallHomeSpec struct { Repository string `json:"repository"` Tag string `json:"tag"` - SecretName string `json:"secretName"` - // +kubebuilder:validation:Optional ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy"` diff --git a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml index 7888d18ac..2b4dcfdd4 100644 --- a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml +++ b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml @@ -507,8 +507,6 @@ spec: type: string repository: type: string - secretName: - type: string tag: type: string tolerations: @@ -535,7 +533,6 @@ spec: type: array required: - repository - - secretName - tag type: object controller: diff --git a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml index 2a279fda8..3371fbc00 100644 --- a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml +++ b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml @@ -50,7 +50,6 @@ spec: # repository: ibmcom/ibm-block-csi-call-home # tag: "1.9.0" # imagePullPolicy: IfNotPresent -# secretName: demo-call-home-secret # affinity: # nodeAffinity: # requiredDuringSchedulingIgnoredDuringExecution: diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index b3b8766eb..03487239d 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -507,8 +507,6 @@ spec: type: string repository: type: string - secretName: - type: string tag: type: string tolerations: @@ -535,7 +533,6 @@ spec: type: array required: - repository - - secretName - tag type: object controller: From 5c6bcf111a061274efdd455ad129f216fe40afbe Mon Sep 17 00:00:00 2001 From: arbelnat Date: Thu, 24 Feb 2022 17:17:33 +0200 Subject: [PATCH 53/69] remove secret volume --- controllers/ibmblockcsi_controller.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 9e8a5d308..7286b2ae2 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -194,7 +194,7 @@ func (r *IBMBlockCSIReconciler) Reconcile(ctx context.Context, req ctrl.Request) return reconcile.Result{}, err } - if instance.Spec.CallHome.SecretName != "" { + if instance.Spec.CallHome.Repository == "" { callHomeSyncer := clustersyncer.NewCallHomeSyncer(r.Client, r.Scheme, instance) if err := syncer.Sync(context.TODO(), callHomeSyncer, r.Recorder); err != nil { return reconcile.Result{}, err @@ -570,7 +570,7 @@ func (r *IBMBlockCSIReconciler) isNodeReady(node *appsv1.DaemonSet) bool { } func (r *IBMBlockCSIReconciler) updateCallHomeStatus(instance *ibmblockcsi.IBMBlockCSI, callHome *batchv1.CronJob, logger logr.Logger) error { - if instance.Spec.CallHome.SecretName == "" { + if instance.Spec.CallHome.Repository == "" { logger.Info("deleting call home CronJob") return r.Delete(context.TODO(), callHome) } From e0272c8b5d411615dfb7796523943b81aafd20a0 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 27 Feb 2022 14:31:00 +0200 Subject: [PATCH 54/69] remove secret volume --- controllers/ibmblockcsi_controller.go | 13 +++++-------- controllers/syncer/call_home.go | 5 ++--- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 7286b2ae2..afc1a6f44 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -318,8 +318,8 @@ func (r *IBMBlockCSIReconciler) updateStatus(instance *ibmblockcsi.IBMBlockCSI, } callHomeCronJob, err := r.getCallHomeCronJob(instance) - if err == nil { - err = r.updateCallHomeStatus(instance, callHomeCronJob, logger) + if instance.Spec.CallHome.Repository == "" { + err = r.deleteCallHomeCronJob(callHomeCronJob, logger) if err != nil { logger.Error(err, "failed to delete call home CronJob") } @@ -569,12 +569,9 @@ func (r *IBMBlockCSIReconciler) isNodeReady(node *appsv1.DaemonSet) bool { return node.Status.DesiredNumberScheduled == node.Status.NumberAvailable } -func (r *IBMBlockCSIReconciler) updateCallHomeStatus(instance *ibmblockcsi.IBMBlockCSI, callHome *batchv1.CronJob, logger logr.Logger) error { - if instance.Spec.CallHome.Repository == "" { - logger.Info("deleting call home CronJob") - return r.Delete(context.TODO(), callHome) - } - return nil +func (r *IBMBlockCSIReconciler) deleteCallHomeCronJob(callHome *batchv1.CronJob, logger logr.Logger) error { + logger.Info("deleting call home CronJob") + return r.Delete(context.TODO(), callHome) } func (r *IBMBlockCSIReconciler) reconcileClusterRole(instance *ibmblockcsi.IBMBlockCSI) error { diff --git a/controllers/syncer/call_home.go b/controllers/syncer/call_home.go index f3258c17a..463822937 100644 --- a/controllers/syncer/call_home.go +++ b/controllers/syncer/call_home.go @@ -34,7 +34,7 @@ import ( const ( callHomeContainerName = "ibm-block-csi-call-home" - CronSchedule = "0 0 * * *" // runs once a day at midnight + cronSchedule = "0 0 * * *" // runs once a day at midnight jobsHistoryLimit = int32(1) ) @@ -67,7 +67,7 @@ func NewCallHomeSyncer(c client.Client, scheme *runtime.Scheme, driver *ibmblock func (s *callHomeSyncer) SyncFn() error { out := s.obj.(*batchv1.CronJob) - out.Spec.Schedule = CronSchedule + out.Spec.Schedule = cronSchedule // ensure template out.Spec.JobTemplate.ObjectMeta.Labels = s.driver.GetCallHomePodLabels() @@ -133,5 +133,4 @@ func (s *callHomeSyncer) getEnv() []corev1.EnvVar { Value: csiversion.Version, }, } - } From 8378d5f884fab207117b5f55215883696df54144 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 27 Feb 2022 15:45:10 +0200 Subject: [PATCH 55/69] test without call-home default Repository and tag --- controllers/internal/ibmblockcsi/default_setter.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/controllers/internal/ibmblockcsi/default_setter.go b/controllers/internal/ibmblockcsi/default_setter.go index 5dc5e0f14..3dd27726c 100644 --- a/controllers/internal/ibmblockcsi/default_setter.go +++ b/controllers/internal/ibmblockcsi/default_setter.go @@ -82,14 +82,6 @@ func (c *IBMBlockCSI) setDefaults() bool { changed = true } - if c.Spec.CallHome.Repository != config.DefaultCr.Spec.CallHome.Repository || - c.Spec.CallHome.Tag != config.DefaultCr.Spec.CallHome.Tag { - c.Spec.CallHome.Repository = config.DefaultCr.Spec.CallHome.Repository - c.Spec.CallHome.Tag = config.DefaultCr.Spec.CallHome.Tag - - changed = true - } - changed = c.setDefaultSidecars() || changed return changed From 5029c3906e81630b846b73f57fa3780768ed2c7c Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 27 Feb 2022 15:57:01 +0200 Subject: [PATCH 56/69] fix --- controllers/ibmblockcsi_controller.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index afc1a6f44..733e1d7e4 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -194,7 +194,7 @@ func (r *IBMBlockCSIReconciler) Reconcile(ctx context.Context, req ctrl.Request) return reconcile.Result{}, err } - if instance.Spec.CallHome.Repository == "" { + if instance.Spec.CallHome.Repository != "" { callHomeSyncer := clustersyncer.NewCallHomeSyncer(r.Client, r.Scheme, instance) if err := syncer.Sync(context.TODO(), callHomeSyncer, r.Recorder); err != nil { return reconcile.Result{}, err From 9ac11b543c45371ed20106c1b662c5d5fed3c8c7 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Sun, 27 Feb 2022 16:34:15 +0200 Subject: [PATCH 57/69] PR --- controllers/ibmblockcsi_controller.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 733e1d7e4..17fdbbf68 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -318,7 +318,9 @@ func (r *IBMBlockCSIReconciler) updateStatus(instance *ibmblockcsi.IBMBlockCSI, } callHomeCronJob, err := r.getCallHomeCronJob(instance) - if instance.Spec.CallHome.Repository == "" { + if err != nil { + logger.Error(err, "failed to get call home CronJob") + } else if instance.Spec.CallHome.Repository == "" { err = r.deleteCallHomeCronJob(callHomeCronJob, logger) if err != nil { logger.Error(err, "failed to delete call home CronJob") From c2dc77eb58f569c8073f77fe4f21a0850738795b Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 28 Feb 2022 14:56:00 +0200 Subject: [PATCH 58/69] PR --- controllers/ibmblockcsi_controller.go | 154 +++++++++++++++++--------- 1 file changed, 104 insertions(+), 50 deletions(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 17fdbbf68..c95ca3a22 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -194,7 +194,7 @@ func (r *IBMBlockCSIReconciler) Reconcile(ctx context.Context, req ctrl.Request) return reconcile.Result{}, err } - if instance.Spec.CallHome.Repository != "" { + if r.isCallHomeDefined(instance) { callHomeSyncer := clustersyncer.NewCallHomeSyncer(r.Client, r.Scheme, instance) if err := syncer.Sync(context.TODO(), callHomeSyncer, r.Recorder); err != nil { return reconcile.Result{}, err @@ -318,12 +318,13 @@ func (r *IBMBlockCSIReconciler) updateStatus(instance *ibmblockcsi.IBMBlockCSI, } callHomeCronJob, err := r.getCallHomeCronJob(instance) - if err != nil { - logger.Error(err, "failed to get call home CronJob") - } else if instance.Spec.CallHome.Repository == "" { - err = r.deleteCallHomeCronJob(callHomeCronJob, logger) + if err != nil && errors.IsNotFound(err) { + } else if err != nil { + return err + } else if !r.isCallHomeDefined(instance) { + err = r.deleteCallHome(instance, callHomeCronJob, logger) if err != nil { - logger.Error(err, "failed to delete call home CronJob") + return err } } @@ -467,11 +468,16 @@ func (r *IBMBlockCSIReconciler) reconcileServiceAccount(instance *ibmblockcsi.IB controllerServiceAccountName := oconfig.GetNameForResource(oconfig.CSIControllerServiceAccount, instance.Name) nodeServiceAccountName := oconfig.GetNameForResource(oconfig.CSINodeServiceAccount, instance.Name) - for _, sa := range []*corev1.ServiceAccount{ + ServiceAccounts := []*corev1.ServiceAccount{ controller, node, - callHome, - } { + } + + if r.isCallHomeDefined(instance) { + ServiceAccounts = append(ServiceAccounts, callHome) + } + + for _, sa := range ServiceAccounts { if err := controllerutil.SetControllerReference(instance.Unwrap(), sa, r.Scheme); err != nil { return err } @@ -571,9 +577,34 @@ func (r *IBMBlockCSIReconciler) isNodeReady(node *appsv1.DaemonSet) bool { return node.Status.DesiredNumberScheduled == node.Status.NumberAvailable } +func (r *IBMBlockCSIReconciler) isCallHomeDefined(instance *ibmblockcsi.IBMBlockCSI) bool { + return instance.Spec.CallHome.Repository != "" +} + +func (r *IBMBlockCSIReconciler) deleteCallHome(instance *ibmblockcsi.IBMBlockCSI, callHome *batchv1.CronJob, logger logr.Logger) error { + logger.Info("deleting call home clusterRoleBinding") + callHomeCRB := instance.GenerateSCCForCallHomeClusterRoleBinding() + if err := r.deleteClusterRoleBinding(callHomeCRB); err != nil { + return err + } + logger.Info("deleting call home clusterRole") + callHomeCR := instance.GenerateSCCForCallHomeClusterRole() + if err := r.deleteClusterRole(callHomeCR); err != nil { + return err + } + logger.Info("deleting call home CronJob") + if err := r.deleteCallHomeCronJob(callHome, logger); err != nil { + return err + } + return nil +} + func (r *IBMBlockCSIReconciler) deleteCallHomeCronJob(callHome *batchv1.CronJob, logger logr.Logger) error { logger.Info("deleting call home CronJob") - return r.Delete(context.TODO(), callHome) + if err := r.Delete(context.TODO(), callHome); err != nil { + return err + } + return nil } func (r *IBMBlockCSIReconciler) reconcileClusterRole(instance *ibmblockcsi.IBMBlockCSI) error { @@ -618,31 +649,37 @@ func (r *IBMBlockCSIReconciler) deleteClusterRolesAndBindings(instance *ibmblock } return nil } - func (r *IBMBlockCSIReconciler) deleteClusterRoles(instance *ibmblockcsi.IBMBlockCSI) error { - logger := log.WithName("deleteClusterRoles") - clusterRoles := r.getClusterRoles(instance) for _, cr := range clusterRoles { - found := &rbacv1.ClusterRole{} - err := r.Get(context.TODO(), types.NamespacedName{ - Name: cr.Name, - Namespace: cr.Namespace, - }, found) - if err != nil && errors.IsNotFound(err) { - continue - } else if err != nil { - logger.Error(err, "failed to get ClusterRole", "Name", cr.GetName()) + if err := r.deleteClusterRole(cr); err != nil { + return err + } + } + return nil +} +func (r *IBMBlockCSIReconciler) deleteClusterRole(clusterRole *rbacv1.ClusterRole) error { + logger := log.WithName("deleteClusterRoles") + + found := &rbacv1.ClusterRole{} + err := r.Get(context.TODO(), types.NamespacedName{ + Name: clusterRole.Name, + Namespace: clusterRole.Namespace, + }, found) + if err != nil && errors.IsNotFound(err) { + return nil + } else if err != nil { + logger.Error(err, "failed to get ClusterRole", "Name", clusterRole.GetName()) + return err + } else { + logger.Info("deleting ClusterRole", "Name", clusterRole.GetName()) + if err := r.Delete(context.TODO(), found); err != nil { + logger.Error(err, "failed to delete ClusterRole", "Name", clusterRole.GetName()) return err - } else { - logger.Info("deleting ClusterRole", "Name", cr.GetName()) - if err := r.Delete(context.TODO(), found); err != nil { - logger.Error(err, "failed to delete ClusterRole", "Name", cr.GetName()) - return err - } } } + return nil } @@ -656,7 +693,7 @@ func (r *IBMBlockCSIReconciler) getClusterRoles(instance *ibmblockcsi.IBMBlockCS nodeSCC := instance.GenerateSCCForNodeClusterRole() callHomeSCC := instance.GenerateSCCForCallHomeClusterRole() - return []*rbacv1.ClusterRole{ + clusterRoles := []*rbacv1.ClusterRole{ externalProvisioner, externalAttacher, externalSnapshotter, @@ -664,8 +701,13 @@ func (r *IBMBlockCSIReconciler) getClusterRoles(instance *ibmblockcsi.IBMBlockCS csiAddonsReplicator, controllerSCC, nodeSCC, - callHomeSCC, } + + if r.isCallHomeDefined(instance) { + clusterRoles = append(clusterRoles, callHomeSCC) + } + + return clusterRoles } func (r *IBMBlockCSIReconciler) reconcileClusterRoleBinding(instance *ibmblockcsi.IBMBlockCSI) error { @@ -697,29 +739,36 @@ func (r *IBMBlockCSIReconciler) reconcileClusterRoleBinding(instance *ibmblockcs } func (r *IBMBlockCSIReconciler) deleteClusterRoleBindings(instance *ibmblockcsi.IBMBlockCSI) error { - logger := log.WithName("deleteClusterRoleBindings") - clusterRoleBindings := r.getClusterRoleBindings(instance) - for _, crb := range clusterRoleBindings { - found := &rbacv1.ClusterRoleBinding{} - err := r.Get(context.TODO(), types.NamespacedName{ - Name: crb.Name, - Namespace: crb.Namespace, - }, found) - if err != nil && errors.IsNotFound(err) { - continue - } else if err != nil { - logger.Error(err, "failed to get ClusterRoleBinding", "Name", crb.GetName()) + if err := r.deleteClusterRoleBinding(crb); err != nil { + return err + } + } + return nil +} + +func (r *IBMBlockCSIReconciler) deleteClusterRoleBinding(clusterRoleBinding *rbacv1.ClusterRoleBinding) error { + logger := log.WithName("deleteClusterRoleBindings") + + found := &rbacv1.ClusterRoleBinding{} + err := r.Get(context.TODO(), types.NamespacedName{ + Name: clusterRoleBinding.Name, + Namespace: clusterRoleBinding.Namespace, + }, found) + if err != nil && errors.IsNotFound(err) { + return nil + } else if err != nil { + logger.Error(err, "failed to get ClusterRoleBinding", "Name", clusterRoleBinding.GetName()) + return err + } else { + logger.Info("deleting ClusterRoleBinding", "Name", clusterRoleBinding.GetName()) + if err := r.Delete(context.TODO(), found); err != nil { + logger.Error(err, "failed to delete ClusterRoleBinding", "Name", clusterRoleBinding.GetName()) return err - } else { - logger.Info("deleting ClusterRoleBinding", "Name", crb.GetName()) - if err := r.Delete(context.TODO(), found); err != nil { - logger.Error(err, "failed to delete ClusterRoleBinding", "Name", crb.GetName()) - return err - } } } + return nil } @@ -733,7 +782,7 @@ func (r *IBMBlockCSIReconciler) getClusterRoleBindings(instance *ibmblockcsi.IBM nodeSCC := instance.GenerateSCCForNodeClusterRoleBinding() callHomeSCC := instance.GenerateSCCForCallHomeClusterRoleBinding() - return []*rbacv1.ClusterRoleBinding{ + clusterRoleBindings := []*rbacv1.ClusterRoleBinding{ externalProvisioner, externalAttacher, externalSnapshotter, @@ -741,8 +790,13 @@ func (r *IBMBlockCSIReconciler) getClusterRoleBindings(instance *ibmblockcsi.IBM csiAddonsReplicator, controllerSCC, nodeSCC, - callHomeSCC, } + + if r.isCallHomeDefined(instance) { + clusterRoleBindings = append(clusterRoleBindings, callHomeSCC) + } + + return clusterRoleBindings } func (r *IBMBlockCSIReconciler) deleteCSIDriver(instance *ibmblockcsi.IBMBlockCSI) error { From a366e1b226852909ee6b1c708ec4544b1290d2fb Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 28 Feb 2022 16:24:37 +0200 Subject: [PATCH 59/69] PR --- .../csi.ibm.com_v1_ibmblockcsi_cr.yaml | 2 +- controllers/ibmblockcsi_controller.go | 32 +++++++++++++++++-- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml index 9039069e7..6c505a7cb 100644 --- a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml +++ b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml @@ -45,7 +45,7 @@ spec: - s390x - ppc64le - # callHome is a statefulSet with ibm-block-csi-call-home container + # callHome is cronJob # callHome: # repository: ibmcom/ibm-block-csi-call-home # tag: "1.9.0" diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index c95ca3a22..3297ab81b 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -592,6 +592,11 @@ func (r *IBMBlockCSIReconciler) deleteCallHome(instance *ibmblockcsi.IBMBlockCSI if err := r.deleteClusterRole(callHomeCR); err != nil { return err } + logger.Info("deleting call home serviceAccount") + callHomeSA := instance.GenerateCallHomeServiceAccount() + if err := r.deleteServiceAccount(callHomeSA); err != nil { + return err + } logger.Info("deleting call home CronJob") if err := r.deleteCallHomeCronJob(callHome, logger); err != nil { return err @@ -649,6 +654,7 @@ func (r *IBMBlockCSIReconciler) deleteClusterRolesAndBindings(instance *ibmblock } return nil } + func (r *IBMBlockCSIReconciler) deleteClusterRoles(instance *ibmblockcsi.IBMBlockCSI) error { clusterRoles := r.getClusterRoles(instance) @@ -659,8 +665,9 @@ func (r *IBMBlockCSIReconciler) deleteClusterRoles(instance *ibmblockcsi.IBMBloc } return nil } + func (r *IBMBlockCSIReconciler) deleteClusterRole(clusterRole *rbacv1.ClusterRole) error { - logger := log.WithName("deleteClusterRoles") + logger := log.WithName("deleteClusterRole") found := &rbacv1.ClusterRole{} err := r.Get(context.TODO(), types.NamespacedName{ @@ -679,7 +686,28 @@ func (r *IBMBlockCSIReconciler) deleteClusterRole(clusterRole *rbacv1.ClusterRol return err } } + return nil +} +func (r *IBMBlockCSIReconciler) deleteServiceAccount(serviceAccount *corev1.ServiceAccount) error { + logger := log.WithName("deleteServiceAccount") + found := &corev1.ServiceAccount{} + err := r.Get(context.TODO(), types.NamespacedName{ + Name: serviceAccount.Name, + Namespace: serviceAccount.Namespace, + }, found) + if err != nil && errors.IsNotFound(err) { + return nil + } else if err != nil { + logger.Error(err, "failed to get ServiceAccount", "Name", serviceAccount.GetName()) + return err + } else { + logger.Info("deleting ServiceAccount", "Name", serviceAccount.GetName()) + if err := r.Delete(context.TODO(), found); err != nil { + logger.Error(err, "failed to delete ServiceAccount", "Name", serviceAccount.GetName()) + return err + } + } return nil } @@ -749,7 +777,7 @@ func (r *IBMBlockCSIReconciler) deleteClusterRoleBindings(instance *ibmblockcsi. } func (r *IBMBlockCSIReconciler) deleteClusterRoleBinding(clusterRoleBinding *rbacv1.ClusterRoleBinding) error { - logger := log.WithName("deleteClusterRoleBindings") + logger := log.WithName("deleteClusterRoleBinding") found := &rbacv1.ClusterRoleBinding{} err := r.Get(context.TODO(), types.NamespacedName{ From e814128fa05996a35a2592a5a87cead137379b83 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 28 Feb 2022 16:36:16 +0200 Subject: [PATCH 60/69] PR --- controllers/syncer/call_home.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/controllers/syncer/call_home.go b/controllers/syncer/call_home.go index 463822937..9b14a2753 100644 --- a/controllers/syncer/call_home.go +++ b/controllers/syncer/call_home.go @@ -124,10 +124,6 @@ func (s *callHomeSyncer) ensureContainer(name, image string, args []string) core func (s *callHomeSyncer) getEnv() []corev1.EnvVar { return []corev1.EnvVar{ - { - Name: "CSI_LOGLEVEL", - Value: config.DefaultLogLevel, - }, { Name: "CSI_VERSION", Value: csiversion.Version, From 0b0785ac51b043fa1fa9ddabfa339dff9b0696dc Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 28 Feb 2022 16:54:36 +0200 Subject: [PATCH 61/69] PR --- controllers/ibmblockcsi_controller.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 3297ab81b..73842ea9e 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -468,16 +468,16 @@ func (r *IBMBlockCSIReconciler) reconcileServiceAccount(instance *ibmblockcsi.IB controllerServiceAccountName := oconfig.GetNameForResource(oconfig.CSIControllerServiceAccount, instance.Name) nodeServiceAccountName := oconfig.GetNameForResource(oconfig.CSINodeServiceAccount, instance.Name) - ServiceAccounts := []*corev1.ServiceAccount{ + serviceAccounts := []*corev1.ServiceAccount{ controller, node, } if r.isCallHomeDefined(instance) { - ServiceAccounts = append(ServiceAccounts, callHome) + serviceAccounts = append(serviceAccounts, callHome) } - for _, sa := range ServiceAccounts { + for _, sa := range serviceAccounts { if err := controllerutil.SetControllerReference(instance.Unwrap(), sa, r.Scheme); err != nil { return err } From 4b2abda8dc99cfddf4dfe572732c102e0c24ba30 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 28 Feb 2022 17:11:39 +0200 Subject: [PATCH 62/69] PR --- controllers/ibmblockcsi_controller.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 73842ea9e..c11dd7cdd 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -598,14 +598,13 @@ func (r *IBMBlockCSIReconciler) deleteCallHome(instance *ibmblockcsi.IBMBlockCSI return err } logger.Info("deleting call home CronJob") - if err := r.deleteCallHomeCronJob(callHome, logger); err != nil { + if err := r.deleteCallHomeCronJob(callHome); err != nil { return err } return nil } -func (r *IBMBlockCSIReconciler) deleteCallHomeCronJob(callHome *batchv1.CronJob, logger logr.Logger) error { - logger.Info("deleting call home CronJob") +func (r *IBMBlockCSIReconciler) deleteCallHomeCronJob(callHome *batchv1.CronJob) error { if err := r.Delete(context.TODO(), callHome); err != nil { return err } From 3108823996e78c46d146f191722eba9202e65274 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 28 Feb 2022 17:32:11 +0200 Subject: [PATCH 63/69] PR --- controllers/ibmblockcsi_controller.go | 30 +++++++++++++++++---------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index c11dd7cdd..0ed6d1e26 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -183,6 +183,10 @@ func (r *IBMBlockCSIReconciler) Reconcile(ctx context.Context, req ctrl.Request) } } + if err := r.reconcileCallHome(instance); err != nil { + return reconcile.Result{}, err + } + // sync the resources which change over time csiControllerSyncer := clustersyncer.NewCSIControllerSyncer(r.Client, r.Scheme, instance) if err := syncer.Sync(context.TODO(), csiControllerSyncer, r.Recorder); err != nil { @@ -304,6 +308,21 @@ func (r *IBMBlockCSIReconciler) getAccessorAndFinalizerName(instance *ibmblockcs return accessor, finalizerName, nil } +func (r *IBMBlockCSIReconciler) reconcileCallHome(instance *ibmblockcsi.IBMBlockCSI) error { + logger := log.WithName("reconcileCallHome") + callHomeCronJob, err := r.getCallHomeCronJob(instance) + if err != nil && errors.IsNotFound(err) { + } else if err != nil { + return err + } else if !r.isCallHomeDefined(instance) { + err = r.deleteCallHome(instance, callHomeCronJob, logger) + if err != nil { + return err + } + } + return nil +} + func (r *IBMBlockCSIReconciler) updateStatus(instance *ibmblockcsi.IBMBlockCSI, originalStatus csiv1.IBMBlockCSIStatus) error { logger := log.WithName("updateStatus") controllerPod := &corev1.Pod{} @@ -317,17 +336,6 @@ func (r *IBMBlockCSIReconciler) updateStatus(instance *ibmblockcsi.IBMBlockCSI, return err } - callHomeCronJob, err := r.getCallHomeCronJob(instance) - if err != nil && errors.IsNotFound(err) { - } else if err != nil { - return err - } else if !r.isCallHomeDefined(instance) { - err = r.deleteCallHome(instance, callHomeCronJob, logger) - if err != nil { - return err - } - } - instance.Status.ControllerReady = r.isControllerReady(controllerStatefulset) instance.Status.NodeReady = r.isNodeReady(nodeDaemonSet) phase := csiv1.DriverPhaseNone From 96ddcabc1ea59cd6bb25ba5b538e3863ac7aa30a Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 28 Feb 2022 17:44:56 +0200 Subject: [PATCH 64/69] rearrange --- controllers/ibmblockcsi_controller.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index 0ed6d1e26..d7420a88b 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -311,10 +311,13 @@ func (r *IBMBlockCSIReconciler) getAccessorAndFinalizerName(instance *ibmblockcs func (r *IBMBlockCSIReconciler) reconcileCallHome(instance *ibmblockcsi.IBMBlockCSI) error { logger := log.WithName("reconcileCallHome") callHomeCronJob, err := r.getCallHomeCronJob(instance) - if err != nil && errors.IsNotFound(err) { - } else if err != nil { + if err != nil { + if errors.IsNotFound(err) { + return nil + } return err - } else if !r.isCallHomeDefined(instance) { + } + if !r.isCallHomeDefined(instance) { err = r.deleteCallHome(instance, callHomeCronJob, logger) if err != nil { return err From 2be82948310ea7c0fb380b9e9419c4c6e6dc9300 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Mon, 28 Feb 2022 18:18:02 +0200 Subject: [PATCH 65/69] olm update --- .../manifests/csi.ibm.com_ibmblockcsis.yaml | 497 ++++++++++++++++++ ...operator.v1.9.0.clusterserviceversion.yaml | 17 + .../manifests/csi.ibm.com_ibmblockcsis.yaml | 497 ++++++++++++++++++ ...ck-csi-operator.clusterserviceversion.yaml | 17 + 4 files changed, 1028 insertions(+) diff --git a/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/csi.ibm.com_ibmblockcsis.yaml b/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/csi.ibm.com_ibmblockcsis.yaml index ef01c5cb9..b8e615cea 100644 --- a/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/csi.ibm.com_ibmblockcsis.yaml +++ b/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/csi.ibm.com_ibmblockcsis.yaml @@ -38,6 +38,503 @@ spec: spec: description: IBMBlockCSISpec defines the desired state of IBMBlockCSI properties: + callHome: + description: IBMBlockCSICallHomeSpec defines the desired state of IBMBlockCSICallHome + properties: + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + items: + description: A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull a container image + type: string + repository: + type: string + tag: + type: string + tolerations: + items: + description: The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + required: + - repository + - tag + type: object controller: description: IBMBlockCSIControllerSpec defines the desired state of IBMBlockCSIController properties: diff --git a/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/ibm-block-csi-operator.v1.9.0.clusterserviceversion.yaml b/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/ibm-block-csi-operator.v1.9.0.clusterserviceversion.yaml index 77d876936..e1cfcb3a1 100644 --- a/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/ibm-block-csi-operator.v1.9.0.clusterserviceversion.yaml +++ b/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/ibm-block-csi-operator.v1.9.0.clusterserviceversion.yaml @@ -257,6 +257,23 @@ spec: - get - list - watch + - apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - apiGroups: + - batch + resources: + - cronjobs + verbs: + - create + - delete + - get + - list + - update + - watch - apiGroups: - "" resources: diff --git a/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/csi.ibm.com_ibmblockcsis.yaml b/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/csi.ibm.com_ibmblockcsis.yaml index ef01c5cb9..b8e615cea 100644 --- a/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/csi.ibm.com_ibmblockcsis.yaml +++ b/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/csi.ibm.com_ibmblockcsis.yaml @@ -38,6 +38,503 @@ spec: spec: description: IBMBlockCSISpec defines the desired state of IBMBlockCSI properties: + callHome: + description: IBMBlockCSICallHomeSpec defines the desired state of IBMBlockCSICallHome + properties: + affinity: + description: Affinity is a group of affinity scheduling rules. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op). + properties: + preference: + description: A node selector term, associated with the corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + description: Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to an update), the system may or may not try to eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. The terms are ORed. + items: + description: A null or empty node selector term matches no objects. The requirements of them are ANDed. The TopologySelectorTerm type implements a subset of the NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements by node's labels. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements by node's fields. + items: + description: A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: The label key that the selector applies to. + type: string + operator: + description: Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt. + type: string + values: + description: An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. avoid putting this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to nodes that satisfy the anti-affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling anti-affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding "weight" to the sum if the node has pods which matches the corresponding podAffinityTerm; the node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by this field are not met at scheduling time, the pod will not be scheduled onto the node. If the anti-affinity requirements specified by this field cease to be met at some point during pod execution (e.g. due to a pod label update), the system may or may not try to eventually evict the pod from its node. When there are multiple elements, the lists of nodes corresponding to each podAffinityTerm are intersected, i.e. all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching the labelSelector relative to the given namespace(s)) that this pod should be co-located (affinity) or not co-located (anti-affinity) with, where co-located is defined as running on a node whose value of the label with key matches that of any node on which a pod of the set of pods is running + properties: + labelSelector: + description: A label query over a set of resources, in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaceSelector: + description: A label query over the set of namespaces that the term applies to. The term is applied to the union of the namespaces selected by this field and the ones listed in the namespaces field. null selector and null or empty namespaces list means "this pod's namespace". An empty selector ({}) matches all namespaces. This field is alpha-level and is only honored when PodAffinityNamespaceSelector feature is enabled. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector that contains values, a key, and an operator that relates the key and values. + properties: + key: + description: key is the label key that the selector applies to. + type: string + operator: + description: operator represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. This array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels map is equivalent to an element of matchExpressions, whose key field is "key", the operator is "In", and the values array contains only "value". The requirements are ANDed. + type: object + type: object + namespaces: + description: namespaces specifies a static list of namespace names that the term applies to. The term is applied to the union of the namespaces listed in this field and the ones selected by namespaceSelector. null or empty namespaces list and null namespaceSelector means "this pod's namespace" + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) or not co-located (anti-affinity) with the pods matching the labelSelector in the specified namespaces, where co-located is defined as running on a node whose value of the label with key topologyKey matches that of any node on which any of the selected pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + imagePullPolicy: + description: PullPolicy describes a policy for if/when to pull a container image + type: string + repository: + type: string + tag: + type: string + tolerations: + items: + description: The pod this Toleration is attached to tolerates any taint that matches the triple using the matching operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty means match all taint effects. When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies to. Empty means match all taint keys. If the key is empty, operator must be Exists; this combination means to match all values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the value. Valid operators are Exists and Equal. Defaults to Equal. Exists is equivalent to wildcard for value, so that a pod can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time the toleration (which must be of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default, it is not set, which means tolerate the taint forever (do not evict). Zero and negative values will be treated as 0 (evict immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches to. If the operator is Exists, the value should be empty, otherwise just a regular string. + type: string + type: object + type: array + required: + - repository + - tag + type: object controller: description: IBMBlockCSIControllerSpec defines the desired state of IBMBlockCSIController properties: diff --git a/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/ibm-block-csi-operator.clusterserviceversion.yaml b/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/ibm-block-csi-operator.clusterserviceversion.yaml index 6679026c6..fb66bed44 100644 --- a/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/ibm-block-csi-operator.clusterserviceversion.yaml +++ b/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/ibm-block-csi-operator.clusterserviceversion.yaml @@ -249,6 +249,23 @@ spec: - get - list - watch + - apiGroups: + - "" + resources: + - namespaces + verbs: + - get + - apiGroups: + - batch + resources: + - cronjobs + verbs: + - create + - delete + - get + - list + - update + - watch - apiGroups: - "" resources: From d2bdd731476c359f7f69de7af3143f5e318acd62 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Tue, 1 Mar 2022 10:13:46 +0200 Subject: [PATCH 66/69] PR --- config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml index 6c505a7cb..9f7659572 100644 --- a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml +++ b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml @@ -45,7 +45,7 @@ spec: - s390x - ppc64le - # callHome is cronJob + # callHome is a cronJob # callHome: # repository: ibmcom/ibm-block-csi-call-home # tag: "1.9.0" From ec9313da5200f31d1ca0926e052fbdba3e251fd0 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Tue, 1 Mar 2022 15:50:45 +0200 Subject: [PATCH 67/69] added enable field to CR and uncomment call home --- api/v1/ibmblockcsi_types.go | 3 ++ .../crd/bases/csi.ibm.com_ibmblockcsis.yaml | 2 ++ .../csi.ibm.com_v1_ibmblockcsi_cr.yaml | 31 ++++++++++--------- controllers/ibmblockcsi_controller.go | 2 +- .../generated/ibm-block-csi-operator.yaml | 2 ++ ...operator.v1.9.0.clusterserviceversion.yaml | 27 ++++++++++++++++ 6 files changed, 51 insertions(+), 16 deletions(-) diff --git a/api/v1/ibmblockcsi_types.go b/api/v1/ibmblockcsi_types.go index eb7a8b6d9..f0e4525aa 100644 --- a/api/v1/ibmblockcsi_types.go +++ b/api/v1/ibmblockcsi_types.go @@ -120,6 +120,9 @@ type IBMBlockCSICallHomeSpec struct { Repository string `json:"repository"` Tag string `json:"tag"` + // +kubebuilder:validation:Optional + Enable bool `json:"enable"` + // +kubebuilder:validation:Optional ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy"` diff --git a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml index 2b4dcfdd4..688c76d75 100644 --- a/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml +++ b/config/crd/bases/csi.ibm.com_ibmblockcsis.yaml @@ -502,6 +502,8 @@ spec: type: array type: object type: object + enable: + type: boolean imagePullPolicy: description: PullPolicy describes a policy for if/when to pull a container image type: string diff --git a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml index 9f7659572..1de421282 100644 --- a/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml +++ b/config/samples/csi.ibm.com_v1_ibmblockcsi_cr.yaml @@ -46,21 +46,22 @@ spec: - ppc64le # callHome is a cronJob -# callHome: -# repository: ibmcom/ibm-block-csi-call-home -# tag: "1.9.0" -# imagePullPolicy: IfNotPresent -# affinity: -# nodeAffinity: -# requiredDuringSchedulingIgnoredDuringExecution: -# nodeSelectorTerms: -# - matchExpressions: -# - key: kubernetes.io/arch -# operator: In -# values: -# - amd64 -# - s390x -# - ppc64le + callHome: + repository: ibmcom/ibm-block-csi-call-home + tag: "1.9.0" + enable: false + imagePullPolicy: IfNotPresent + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: kubernetes.io/arch + operator: In + values: + - amd64 + - s390x + - ppc64le # tolerations: # - effect: NoSchedule diff --git a/controllers/ibmblockcsi_controller.go b/controllers/ibmblockcsi_controller.go index d7420a88b..faf7da2ea 100644 --- a/controllers/ibmblockcsi_controller.go +++ b/controllers/ibmblockcsi_controller.go @@ -589,7 +589,7 @@ func (r *IBMBlockCSIReconciler) isNodeReady(node *appsv1.DaemonSet) bool { } func (r *IBMBlockCSIReconciler) isCallHomeDefined(instance *ibmblockcsi.IBMBlockCSI) bool { - return instance.Spec.CallHome.Repository != "" + return instance.Spec.CallHome.Enable == true } func (r *IBMBlockCSIReconciler) deleteCallHome(instance *ibmblockcsi.IBMBlockCSI, callHome *batchv1.CronJob, logger logr.Logger) error { diff --git a/deploy/installer/generated/ibm-block-csi-operator.yaml b/deploy/installer/generated/ibm-block-csi-operator.yaml index f3ee9dc60..db71f6e0f 100644 --- a/deploy/installer/generated/ibm-block-csi-operator.yaml +++ b/deploy/installer/generated/ibm-block-csi-operator.yaml @@ -502,6 +502,8 @@ spec: type: array type: object type: object + enable: + type: boolean imagePullPolicy: description: PullPolicy describes a policy for if/when to pull a container image type: string diff --git a/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/ibm-block-csi-operator.v1.9.0.clusterserviceversion.yaml b/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/ibm-block-csi-operator.v1.9.0.clusterserviceversion.yaml index e1cfcb3a1..e44e3e742 100644 --- a/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/ibm-block-csi-operator.v1.9.0.clusterserviceversion.yaml +++ b/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/ibm-block-csi-operator.v1.9.0.clusterserviceversion.yaml @@ -77,6 +77,33 @@ metadata: } } }, + "callHome": { + "repository": "ibmcom/ibm-block-csi-call-home", + "tag": "1.9.0", + "enable": false + "imagePullPolicy": "IfNotPresent", + "affinity": { + "nodeAffinity": { + "requiredDuringSchedulingIgnoredDuringExecution": { + "nodeSelectorTerms": [ + { + "matchExpressions": [ + { + "key": "kubernetes.io/arch", + "operator": "In", + "values": [ + "amd64", + "s390x", + "ppc64le" + ] + } + ] + } + ] + } + } + } + }, "sidecars": [ { "name": "csi-node-driver-registrar", From a16815e6c39f6af5ea438e8b212bc8d455419e49 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Tue, 1 Mar 2022 16:10:47 +0200 Subject: [PATCH 68/69] add call hom to CSV certified --- ...ck-csi-operator.clusterserviceversion.yaml | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/ibm-block-csi-operator.clusterserviceversion.yaml b/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/ibm-block-csi-operator.clusterserviceversion.yaml index fb66bed44..99b8d3b20 100644 --- a/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/ibm-block-csi-operator.clusterserviceversion.yaml +++ b/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/ibm-block-csi-operator.clusterserviceversion.yaml @@ -69,6 +69,31 @@ metadata: } } }, + "callHome": { + "repository": "ibmcom/ibm-block-csi-call-home", + "tag": "1.9.0", + "enable": false + "imagePullPolicy": "IfNotPresent", + "affinity": { + "nodeAffinity": { + "requiredDuringSchedulingIgnoredDuringExecution": { + "nodeSelectorTerms": [ + { + "matchExpressions": [ + { + "key": "kubernetes.io/arch", + "operator": "In", + "values": [ + "amd64" + ] + } + ] + } + ] + } + } + } + }, "sidecars": [ { "name": "csi-node-driver-registrar", From ba3dcf39fa4f5926b72fd852c83fc8174ee5c1b0 Mon Sep 17 00:00:00 2001 From: arbelnat Date: Tue, 1 Mar 2022 16:53:40 +0200 Subject: [PATCH 69/69] fix yamls --- .../ibm-block-csi-operator.v1.9.0.clusterserviceversion.yaml | 2 +- .../manifests/ibm-block-csi-operator.clusterserviceversion.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/ibm-block-csi-operator.v1.9.0.clusterserviceversion.yaml b/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/ibm-block-csi-operator.v1.9.0.clusterserviceversion.yaml index e44e3e742..04c9b42dc 100644 --- a/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/ibm-block-csi-operator.v1.9.0.clusterserviceversion.yaml +++ b/deploy/olm-catalog/ibm-block-csi-operator-community/1.9.0/manifests/ibm-block-csi-operator.v1.9.0.clusterserviceversion.yaml @@ -80,7 +80,7 @@ metadata: "callHome": { "repository": "ibmcom/ibm-block-csi-call-home", "tag": "1.9.0", - "enable": false + "enable": false, "imagePullPolicy": "IfNotPresent", "affinity": { "nodeAffinity": { diff --git a/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/ibm-block-csi-operator.clusterserviceversion.yaml b/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/ibm-block-csi-operator.clusterserviceversion.yaml index 99b8d3b20..6dc0172e5 100644 --- a/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/ibm-block-csi-operator.clusterserviceversion.yaml +++ b/deploy/olm-catalog/ibm-block-csi-operator/1.9.0/manifests/ibm-block-csi-operator.clusterserviceversion.yaml @@ -72,7 +72,7 @@ metadata: "callHome": { "repository": "ibmcom/ibm-block-csi-call-home", "tag": "1.9.0", - "enable": false + "enable": false, "imagePullPolicy": "IfNotPresent", "affinity": { "nodeAffinity": {