From ef5877167d1dee392bad5a30763fcfe277a11405 Mon Sep 17 00:00:00 2001 From: Amit Prinz Setter Date: Wed, 13 Nov 2024 21:59:05 -0800 Subject: [PATCH] Notifications - PR notes, take1 Signed-off-by: Amit Prinz Setter --- deploy/crds/noobaa.io_noobaas.yaml | 39 +- pkg/apis/noobaa/v1alpha1/noobaa_types.go | 21 +- .../noobaa/v1alpha1/zz_generated.deepcopy.go | 32 +- pkg/bundle/deploy.go | 2208 +++++++++++++++++ pkg/system/phase2_creating.go | 84 +- pkg/system/phase4_configuring.go | 6 +- pkg/system/reconciler.go | 4 + 7 files changed, 2362 insertions(+), 32 deletions(-) diff --git a/deploy/crds/noobaa.io_noobaas.yaml b/deploy/crds/noobaa.io_noobaas.yaml index 078903a262..b2e625c12c 100644 --- a/deploy/crds/noobaa.io_noobaas.yaml +++ b/deploy/crds/noobaa.io_noobaas.yaml @@ -1028,6 +1028,40 @@ spec: - guaranteed - much more reliable but need to provide a storage class that supports RWX PVs type: string type: object + bucketNotifications: + description: BucketNotifications (optional) controls bucket notification + options + properties: + connections: + description: |- + Connections - A list of secrets' names that are used by the notifications configrations + (in the TopicArn field). + items: + description: |- + SecretReference represents a Secret Reference. It has enough information to retrieve secret + in any namespace + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which the + secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + type: array + enabled: + description: Enabled - whether bucket notifications is enabled + type: boolean + pvc: + description: |- + PVC (optional) specifies the name of the Persistent Volume Claim (PVC) to be used + for holding pending notifications files. + For ODF - If not provided, the default CepthFS storage class will be used to create the PVC. + type: string + type: object cleanupPolicy: description: CleanupPolicy (optional) Indicates user's policy for deletion @@ -1706,11 +1740,6 @@ spec: update the admin account with new BackingStore/NamespaceStore in order to delete the DefaultBackingStore/DefaultNamespaceStore nullable: true type: boolean - notificationsPVC: - description: |- - NotificationsPVC (optional) specifies the name of the Persistent Volume Claim (PVC) to be used - for notifications persistent files. - type: string pvPoolDefaultStorageClass: description: |- PVPoolDefaultStorageClass (optional) overrides the default cluster StorageClass for the pv-pool volumes. diff --git a/pkg/apis/noobaa/v1alpha1/noobaa_types.go b/pkg/apis/noobaa/v1alpha1/noobaa_types.go index d2fab583d7..f8856cd8c9 100644 --- a/pkg/apis/noobaa/v1alpha1/noobaa_types.go +++ b/pkg/apis/noobaa/v1alpha1/noobaa_types.go @@ -228,10 +228,9 @@ type NooBaaSpec struct { // +optional BucketLogging BucketLoggingSpec `json:"bucketLogging,omitempty"` - // NotificationsPVC (optional) specifies the name of the Persistent Volume Claim (PVC) to be used - // for notifications persistent files. + // BucketNotifications (optional) controls bucket notification options // +optional - NotificationsPVC *string `json:"notificationsPVC,omitempty"` + BucketNotifications BucketNotificationsSpec `json:"bucketNotifications,omitempty"` } // AutoscalerSpec defines different actoscaling spec such as autoscaler type and prometheus namespace @@ -263,6 +262,22 @@ type BucketLoggingSpec struct { BucketLoggingPVC *string `json:"bucketLoggingPVC,omitempty"` } +//BucketNotificationsSpec controls bucket notification configuration +type BucketNotificationsSpec struct { + // Enabled - whether bucket notifications is enabled + Enabled bool `json:"enabled,omitempty"` + + //PVC (optional) specifies the name of the Persistent Volume Claim (PVC) to be used + //for holding pending notifications files. + //For ODF - If not provided, the default CepthFS storage class will be used to create the PVC. + // +optional + PVC *string `json:"pvc,omitempty"` + + //Connections - A list of secrets' names that are used by the notifications configrations + //(in the TopicArn field). + Connections []corev1.SecretReference `json:"connections,omitempty"` +} + // LoadBalancerSourceSubnetSpec defines the subnets that will be allowed to access the NooBaa services type LoadBalancerSourceSubnetSpec struct { // S3 is a list of subnets that will be allowed to access the Noobaa S3 service diff --git a/pkg/apis/noobaa/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/noobaa/v1alpha1/zz_generated.deepcopy.go index db8601e0be..894981134a 100644 --- a/pkg/apis/noobaa/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/noobaa/v1alpha1/zz_generated.deepcopy.go @@ -460,6 +460,32 @@ func (in *BucketLoggingSpec) DeepCopy() *BucketLoggingSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BucketNotificationsSpec) DeepCopyInto(out *BucketNotificationsSpec) { + *out = *in + if in.PVC != nil { + in, out := &in.PVC, &out.PVC + *out = new(string) + **out = **in + } + if in.Connections != nil { + in, out := &in.Connections, &out.Connections + *out = make([]corev1.SecretReference, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BucketNotificationsSpec. +func (in *BucketNotificationsSpec) DeepCopy() *BucketNotificationsSpec { + if in == nil { + return nil + } + out := new(BucketNotificationsSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CacheNamespacePolicy) DeepCopyInto(out *CacheNamespacePolicy) { *out = *in @@ -1227,11 +1253,7 @@ func (in *NooBaaSpec) DeepCopyInto(out *NooBaaSpec) { in.LoadBalancerSourceSubnets.DeepCopyInto(&out.LoadBalancerSourceSubnets) out.Autoscaler = in.Autoscaler in.BucketLogging.DeepCopyInto(&out.BucketLogging) - if in.NotificationsPVC != nil { - in, out := &in.NotificationsPVC, &out.NotificationsPVC - *out = new(string) - **out = **in - } + in.BucketNotifications.DeepCopyInto(&out.BucketNotifications) return } diff --git a/pkg/bundle/deploy.go b/pkg/bundle/deploy.go index b36914e04f..e52b89a21a 100644 --- a/pkg/bundle/deploy.go +++ b/pkg/bundle/deploy.go @@ -1415,6 +1415,2214 @@ spec: status: {} ` +const Sha256_deploy_crds_noobaa_io_noobaas_yam_ = "e7dfb9d8639a590b208c26f914df772a7566fa9ad0182f498a861f8e3a04c38c" + +const File_deploy_crds_noobaa_io_noobaas_yam_ = `--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.16.3 + name: noobaas.noobaa.io +spec: + group: noobaa.io + names: + kind: NooBaa + listKind: NooBaaList + plural: noobaas + shortNames: + - nb + singular: noobaa + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: S3 Endpoints + jsonPath: .status.services.serviceS3.nodePorts + name: S3-Endpoints + type: string + - description: STS Endpoints + jsonPath: .status.services.serviceSts.nodePorts + name: Sts-Endpoints + type: string + - description: Syslog Endpoints + jsonPath: .status.services.serviceSyslog.nodePorts + name: Syslog-Endpoints + type: string + - description: Actual Image + jsonPath: .status.actualImage + name: Image + type: string + - description: Phase + jsonPath: .status.phase + name: Phase + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: NooBaa is the Schema for the NooBaas API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Specification of the desired behavior of the noobaa system. + properties: + affinity: + description: Affinity (optional) passed through to noobaa's pods + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + 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 + x-kubernetes-list-type: atomic + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + type: object + x-kubernetes-map-type: atomic + type: array + x-kubernetes-list-type: atomic + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + 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. + If it's null, this PodAffinityTerm matches with no 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + 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 + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with ` + "`" + `labelSelector` + "`" + ` as ` + "`" + `key in (value)` + "`" + ` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with ` + "`" + `labelSelector` + "`" + ` as ` + "`" + `key notin (value)` + "`" + ` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + 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. + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + 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 + x-kubernetes-map-type: atomic + 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 + x-kubernetes-list-type: atomic + 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 + x-kubernetes-list-type: atomic + 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. + If it's null, this PodAffinityTerm matches with no 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + 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 + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with ` + "`" + `labelSelector` + "`" + ` as ` + "`" + `key in (value)` + "`" + ` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with ` + "`" + `labelSelector` + "`" + ` as ` + "`" + `key notin (value)` + "`" + ` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + 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. + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + 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 + x-kubernetes-map-type: atomic + 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 + x-kubernetes-list-type: atomic + 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 + x-kubernetes-list-type: atomic + 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. + If it's null, this PodAffinityTerm matches with no 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + 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 + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with ` + "`" + `labelSelector` + "`" + ` as ` + "`" + `key in (value)` + "`" + ` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with ` + "`" + `labelSelector` + "`" + ` as ` + "`" + `key notin (value)` + "`" + ` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + 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. + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + 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 + x-kubernetes-map-type: atomic + 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 + x-kubernetes-list-type: atomic + 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 + x-kubernetes-list-type: atomic + 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. + If it's null, this PodAffinityTerm matches with no 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + 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 + x-kubernetes-map-type: atomic + matchLabelKeys: + description: |- + MatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with ` + "`" + `labelSelector` + "`" + ` as ` + "`" + `key in (value)` + "`" + ` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both matchLabelKeys and labelSelector. + Also, matchLabelKeys cannot be set when labelSelector isn't set. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + mismatchLabelKeys: + description: |- + MismatchLabelKeys is a set of pod label keys to select which pods will + be taken into consideration. The keys are used to lookup values from the + incoming pod labels, those key-value labels are merged with ` + "`" + `labelSelector` + "`" + ` as ` + "`" + `key notin (value)` + "`" + ` + to select the group of existing pods which pods will be taken into consideration + for the incoming pod's pod (anti) affinity. Keys that don't exist in the incoming + pod labels will be ignored. The default value is empty. + The same key is forbidden to exist in both mismatchLabelKeys and labelSelector. + Also, mismatchLabelKeys cannot be set when labelSelector isn't set. + This is a beta field and requires enabling MatchLabelKeysInPodAffinity feature gate (enabled by default). + items: + type: string + type: array + x-kubernetes-list-type: atomic + 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. + 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 + x-kubernetes-list-type: atomic + required: + - key + - operator + type: object + type: array + x-kubernetes-list-type: atomic + 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 + x-kubernetes-map-type: atomic + 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 + x-kubernetes-list-type: atomic + 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 + x-kubernetes-list-type: atomic + type: object + type: object + annotations: + additionalProperties: + additionalProperties: + type: string + description: Annotations are annotation for a given daemon + type: object + description: The annotations-related configuration to add/set on each + Pod related object. + nullable: true + type: object + x-kubernetes-preserve-unknown-fields: true + autoscaler: + description: Configuration related to autoscaling + properties: + autoscalerType: + description: Type of autoscaling (optional) for noobaa-endpoint, + hpav2(default) and keda - Prometheus metrics based + enum: + - hpav2 + - keda + type: string + prometheusNamespace: + description: Prometheus namespace that scrap metrics from noobaa + type: string + type: object + bucketLogging: + description: BucketLogging sets the configuration for bucket logging + properties: + bucketLoggingPVC: + description: |- + BucketLoggingPVC (optional) specifies the name of the Persistent Volume Claim (PVC) to be used + for guaranteed logging when the logging type is set to 'guaranteed'. The PVC must support + ReadWriteMany (RWX) access mode to ensure reliable logging. + For ODF: If not provided, the default CephFS storage class will be used to create the PVC. + type: string + loggingType: + description: |- + LoggingType specifies the type of logging for the bucket + There are two types available: best-effort and guaranteed logging + - best-effort(default) - less immune to failures but with better performance + - guaranteed - much more reliable but need to provide a storage class that supports RWX PVs + type: string + type: object + bucketNotification: + description: BucketNotifications (optional) controls bucket notification + options + properties: + connection: + description: |- + Connections - A list of secrets' names that are used by the notifications configrations + (in the TopicArn field). + items: + description: |- + SecretReference represents a Secret Reference. It has enough information to retrieve secret + in any namespace + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which the + secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + type: array + enabled: + description: Enabled - whether bucket notifications is enabled + type: boolean + pvc: + description: |- + PVC (optional) specifies the name of the Persistent Volume Claim (PVC) to be used + for holding pending notifications files. + For ODF - If not provided, the default CepthFS storage class will be used to create the PVC. + type: string + required: + - connection + type: object + cleanupPolicy: + description: CleanupPolicy (optional) Indicates user's policy for + deletion + properties: + allowNoobaaDeletion: + type: boolean + confirmation: + description: CleanupConfirmationProperty is a string that specifies + cleanup confirmation + type: string + type: object + coreResources: + description: CoreResources (optional) overrides the default resource + requirements for the server container + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + dbConf: + description: DBConf (optional) overrides the default postgresql db + config + type: string + dbImage: + description: DBImage (optional) overrides the default image for the + db container + type: string + dbResources: + description: DBResources (optional) overrides the default resource + requirements for the db container + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + dbStorageClass: + description: |- + DBStorageClass (optional) overrides the default cluster StorageClass for the database volume. + For the time being this field is immutable and can only be set on system creation. + This affects where the system stores its database which contains system config, + buckets, objects meta-data and mapping file parts to storage locations. + type: string + dbType: + description: |- + DBType (optional) overrides the default type image for the db container. + The only possible value is postgres + enum: + - postgres + type: string + dbVolumeResources: + description: |- + DBVolumeResources (optional) overrides the default PVC resource requirements for the database volume. + For the time being this field is immutable and can only be set on system creation. + This is because volume size updates are only supported for increasing the size, + and only if the storage class specifies ` + "`" + `allowVolumeExpansion: true` + "`" + `, + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + debugLevel: + description: DebugLevel (optional) sets the debug level + enum: + - all + - nsfs + - warn + - default_level + type: integer + defaultBackingStoreSpec: + description: 'Deprecated: DefaultBackingStoreSpec is not supported + anymore, use ManualDefaultBackingStore instead.' + properties: + awsS3: + description: AWSS3Spec specifies a backing store of type aws-s3 + properties: + awsSTSRoleARN: + description: AWSSTSRoleARN allows to Assume Role and use AssumeRoleWithWebIdentity + type: string + region: + description: Region is the AWS region + type: string + secret: + description: |- + Secret refers to a secret that provides the credentials + The secret should define AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + sslDisabled: + description: SSLDisabled allows to disable SSL and use plain + http + type: boolean + targetBucket: + description: TargetBucket is the name of the target S3 bucket + type: string + required: + - targetBucket + type: object + azureBlob: + description: AzureBlob specifies a backing store of type azure-blob + properties: + secret: + description: |- + Secret refers to a secret that provides the credentials + The secret should define AccountName and AccountKey as provided by Azure Blob. + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + targetBlobContainer: + description: TargetBlobContainer is the name of the target + Azure Blob container + type: string + required: + - secret + - targetBlobContainer + type: object + googleCloudStorage: + description: GoogleCloudStorage specifies a backing store of type + google-cloud-storage + properties: + secret: + description: |- + Secret refers to a secret that provides the credentials + The secret should define GoogleServiceAccountPrivateKeyJson containing the entire json string as provided by Google. + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + targetBucket: + description: TargetBucket is the name of the target S3 bucket + type: string + required: + - secret + - targetBucket + type: object + ibmCos: + description: IBMCos specifies a backing store of type ibm-cos + properties: + endpoint: + description: 'Endpoint is the IBM COS compatible endpoint: + http(s)://host:port' + type: string + secret: + description: |- + Secret refers to a secret that provides the credentials + The secret should define IBM_COS_ACCESS_KEY_ID and IBM_COS_SECRET_ACCESS_KEY + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + signatureVersion: + description: SignatureVersion specifies the client signature + version to use when signing requests. + type: string + targetBucket: + description: TargetBucket is the name of the target IBM COS + bucket + type: string + required: + - endpoint + - secret + - targetBucket + type: object + pvPool: + description: PVPool specifies a backing store of type pv-pool + properties: + numVolumes: + description: NumVolumes is the number of volumes to allocate + type: integer + resources: + description: VolumeResources represents the minimum resources + each volume should have. + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + secret: + description: |- + Secret refers to a secret that provides the agent configuration + The secret should define AGENT_CONFIG containing agent_configuration from noobaa-core. + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + storageClass: + description: StorageClass is the name of the storage class + to use for the PV's + type: string + required: + - numVolumes + type: object + s3Compatible: + description: S3Compatible specifies a backing store of type s3-compatible + properties: + endpoint: + description: 'Endpoint is the S3 compatible endpoint: http(s)://host:port' + type: string + secret: + description: |- + Secret refers to a secret that provides the credentials + The secret should define AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + signatureVersion: + description: SignatureVersion specifies the client signature + version to use when signing requests. + type: string + targetBucket: + description: TargetBucket is the name of the target S3 bucket + type: string + required: + - endpoint + - secret + - targetBucket + type: object + type: + description: Type is an enum of supported types + type: string + required: + - type + type: object + denyHTTP: + description: DenyHTTP (optional) if given will deny access to the + NooBaa S3 service using HTTP (only HTTPS) + type: boolean + disableLoadBalancerService: + description: DisableLoadBalancerService (optional) sets the service + type to ClusterIP instead of LoadBalancer + nullable: true + type: boolean + endpoints: + description: |- + Endpoints (optional) sets configuration info for the noobaa endpoint + deployment. + properties: + additionalVirtualHosts: + description: |- + AdditionalVirtualHosts (optional) provide a list of additional hostnames + (on top of the builtin names defined by the cluster: service name, elb name, route name) + to be used as virtual hosts by the the endpoints in the endpoint deployment + items: + type: string + type: array + maxCount: + description: |- + MaxCount, the number of endpoint instances (pods) + to be used as the upper bound when autoscaling + format: int32 + type: integer + minCount: + description: |- + MinCount, the number of endpoint instances (pods) + to be used as the lower bound when autoscaling + format: int32 + type: integer + resources: + description: Resources (optional) overrides the default resource + requirements for every endpoint pod + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + type: object + externalPgSSLRequired: + description: ExternalPgSSLRequired (optional) holds an optional boolean + to force ssl connections to the external Postgres DB + type: boolean + externalPgSSLSecret: + description: ExternalPgSSLSecret (optional) holds an optional secret + with client key and cert used for connecting to external Postgres + DB + properties: + name: + description: name is unique within a namespace to reference a + secret resource. + type: string + namespace: + description: namespace defines the space within which the secret + name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + externalPgSSLUnauthorized: + description: ExternalPgSSLUnauthorized (optional) holds an optional + boolean to allow unauthorized connections to external Postgres DB + type: boolean + externalPgSecret: + description: ExternalPgSecret (optional) holds an optional secret + with a url to an extrenal Postgres DB to be used + properties: + name: + description: name is unique within a namespace to reference a + secret resource. + type: string + namespace: + description: namespace defines the space within which the secret + name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + image: + description: Image (optional) overrides the default image for the + server container + type: string + imagePullSecret: + description: ImagePullSecret (optional) sets a pull secret for the + system image + properties: + name: + default: "" + description: |- + Name of the referent. + This field is effectively required, but due to backwards compatibility is + allowed to be empty. Instances of this type with an empty value here are + almost certainly wrong. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + type: object + x-kubernetes-map-type: atomic + joinSecret: + description: |- + JoinSecret (optional) instructs the operator to join another cluster + and point to a secret that holds the join information + properties: + name: + description: name is unique within a namespace to reference a + secret resource. + type: string + namespace: + description: namespace defines the space within which the secret + name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + labels: + additionalProperties: + additionalProperties: + type: string + description: Labels are label for a given daemon + type: object + description: The labels-related configuration to add/set on each Pod + related object. + nullable: true + type: object + x-kubernetes-preserve-unknown-fields: true + loadBalancerSourceSubnets: + description: |- + LoadBalancerSourceSubnets (optional) if given will allow access to the NooBaa services + only from the listed subnets. This field will have no effect if DisableLoadBalancerService is set + to true + properties: + s3: + description: S3 is a list of subnets that will be allowed to access + the Noobaa S3 service + items: + type: string + type: array + sts: + description: STS is a list of subnets that will be allowed to + access the Noobaa STS service + items: + type: string + type: array + type: object + logResources: + description: LogResources (optional) overrides the default resource + requirements for the noobaa-log-processor container + properties: + claims: + description: |- + Claims lists the names of resources, defined in spec.resourceClaims, + that are used by this container. + + This is an alpha field and requires enabling the + DynamicResourceAllocation feature gate. + + This field is immutable. It can only be set for containers. + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: |- + Name must match the name of one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes that resource available + inside a container. + type: string + request: + description: |- + Request is the name chosen for a request in the referenced claim. + If empty, everything from the claim is made available, otherwise + only the result of this request. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Limits describes the maximum amount of compute resources allowed. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: |- + Requests describes the minimum amount of compute resources required. + If Requests is omitted for a container, it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + type: object + type: object + manualDefaultBackingStore: + description: |- + ManualDefaultBackingStore (optional - default value is false) if true the default backingstore/namespacestore + will not be reconciled by the operator and it should be manually handled by the user. It will allow the + user to delete DefaultBackingStore/DefaultNamespaceStore, user needs to delete associated buckets and + update the admin account with new BackingStore/NamespaceStore in order to delete the DefaultBackingStore/DefaultNamespaceStore + nullable: true + type: boolean + pvPoolDefaultStorageClass: + description: |- + PVPoolDefaultStorageClass (optional) overrides the default cluster StorageClass for the pv-pool volumes. + This affects where the system stores data chunks (encrypted). + Updates to this field will only affect new pv-pools, + but updates to existing pools are not supported by the operator. + type: string + region: + description: |- + Region (optional) provide a region for the location info + of the endpoints in the endpoint deployment + type: string + security: + description: Security represents security settings + properties: + kms: + description: KeyManagementServiceSpec represent various details + of the KMS server + properties: + connectionDetails: + additionalProperties: + type: string + type: object + enableKeyRotation: + type: boolean + schedule: + type: string + tokenSecretName: + type: string + type: object + type: object + tolerations: + description: Tolerations (optional) passed through to noobaa's pods + 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 + type: object + status: + description: Most recently observed status of the noobaa system. + properties: + accounts: + description: Accounts reports accounts info for the admin account + properties: + admin: + description: UserStatus is the status info of a user secret + properties: + secretRef: + description: |- + SecretReference represents a Secret Reference. It has enough information to retrieve secret + in any namespace + properties: + name: + description: name is unique within a namespace to reference + a secret resource. + type: string + namespace: + description: namespace defines the space within which + the secret name must be unique. + type: string + type: object + x-kubernetes-map-type: atomic + required: + - secretRef + type: object + required: + - admin + type: object + actualImage: + description: ActualImage is set to report which image the operator + is using + type: string + beforeUpgradeDbImage: + description: BeforeUpgradeDbImage is the db image used before last + db upgrade + type: string + conditions: + description: Conditions is a list of conditions related to operator + reconciliation + items: + description: |- + Condition represents the state of the operator's + reconciliation functionality. + properties: + lastHeartbeatTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + description: ConditionType is the state of the operator's reconciliation + functionality. + type: string + required: + - status + - type + type: object + type: array + endpoints: + description: |- + Endpoints reports the actual number of endpoints in the endpoint deployment + and the virtual hosts list used recognized by the endpoints + properties: + readyCount: + format: int32 + type: integer + virtualHosts: + items: + type: string + type: array + required: + - readyCount + - virtualHosts + type: object + lastKeyRotateTime: + description: LastKeyRotateTime is the time system ran an encryption + key rotate + format: date-time + type: string + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this noobaa system. + It corresponds to the CR generation, which is updated on mutation by the API Server. + format: int64 + type: integer + phase: + description: Phase is a simple, high-level summary of where the System + is in its lifecycle + type: string + postgresUpdatePhase: + description: Upgrade reports the status of the ongoing postgres upgrade + process + type: string + readme: + description: Readme is a user readable string with explanations on + the system + type: string + relatedObjects: + description: RelatedObjects is a list of objects related to this operator. + items: + description: ObjectReference contains enough information to let + you inspect or modify the referred object. + properties: + apiVersion: + description: API version of the referent. + type: string + fieldPath: + description: |- + If referring to a piece of an object instead of an entire object, this string + should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. + For example, if the object reference is to a container within a pod, this would take on a value like: + "spec.containers{name}" (where "name" refers to the name of the container that triggered + the event) or if no container name is specified "spec.containers[2]" (container with + index 2 in this pod). This syntax is chosen only to have some well-defined way of + referencing a part of an object. + type: string + kind: + description: |- + Kind of the referent. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + type: string + namespace: + description: |- + Namespace of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ + type: string + resourceVersion: + description: |- + Specific resourceVersion to which this reference is made, if any. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency + type: string + uid: + description: |- + UID of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids + type: string + type: object + x-kubernetes-map-type: atomic + type: array + services: + description: Services reports addresses for the services + properties: + serviceMgmt: + description: ServiceStatus is the status info and network addresses + of a service + properties: + externalDNS: + description: ExternalDNS are external public addresses for + the service + items: + type: string + type: array + externalIP: + description: |- + ExternalIP are external public addresses for the service + LoadBalancerPorts such as AWS ELB provide public address and load balancing for the service + IngressPorts are manually created public addresses for the service + https://kubernetes.io/docs/concepts/services-networking/service/#external-ips + https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer + https://kubernetes.io/docs/concepts/services-networking/ingress/ + items: + type: string + type: array + internalDNS: + description: InternalDNS are internal addresses of the service + inside the cluster + items: + type: string + type: array + internalIP: + description: |- + InternalIP are internal addresses of the service inside the cluster + https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + items: + type: string + type: array + nodePorts: + description: |- + NodePorts are the most basic network available. + NodePorts use the networks available on the hosts of kubernetes nodes. + This generally works from within a pod, and from the internal + network of the nodes, but may fail from public network. + https://kubernetes.io/docs/concepts/services-networking/service/#nodeport + items: + type: string + type: array + podPorts: + description: |- + PodPorts are the second most basic network address. + Every pod has an IP in the cluster and the pods network is a mesh + so the operator running inside a pod in the cluster can use this address. + Note: pod IPs are not guaranteed to persist over restarts, so should be rediscovered. + Note2: when running the operator outside of the cluster, pod IP is not accessible. + items: + type: string + type: array + type: object + serviceS3: + description: ServiceStatus is the status info and network addresses + of a service + properties: + externalDNS: + description: ExternalDNS are external public addresses for + the service + items: + type: string + type: array + externalIP: + description: |- + ExternalIP are external public addresses for the service + LoadBalancerPorts such as AWS ELB provide public address and load balancing for the service + IngressPorts are manually created public addresses for the service + https://kubernetes.io/docs/concepts/services-networking/service/#external-ips + https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer + https://kubernetes.io/docs/concepts/services-networking/ingress/ + items: + type: string + type: array + internalDNS: + description: InternalDNS are internal addresses of the service + inside the cluster + items: + type: string + type: array + internalIP: + description: |- + InternalIP are internal addresses of the service inside the cluster + https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + items: + type: string + type: array + nodePorts: + description: |- + NodePorts are the most basic network available. + NodePorts use the networks available on the hosts of kubernetes nodes. + This generally works from within a pod, and from the internal + network of the nodes, but may fail from public network. + https://kubernetes.io/docs/concepts/services-networking/service/#nodeport + items: + type: string + type: array + podPorts: + description: |- + PodPorts are the second most basic network address. + Every pod has an IP in the cluster and the pods network is a mesh + so the operator running inside a pod in the cluster can use this address. + Note: pod IPs are not guaranteed to persist over restarts, so should be rediscovered. + Note2: when running the operator outside of the cluster, pod IP is not accessible. + items: + type: string + type: array + type: object + serviceSts: + description: ServiceStatus is the status info and network addresses + of a service + properties: + externalDNS: + description: ExternalDNS are external public addresses for + the service + items: + type: string + type: array + externalIP: + description: |- + ExternalIP are external public addresses for the service + LoadBalancerPorts such as AWS ELB provide public address and load balancing for the service + IngressPorts are manually created public addresses for the service + https://kubernetes.io/docs/concepts/services-networking/service/#external-ips + https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer + https://kubernetes.io/docs/concepts/services-networking/ingress/ + items: + type: string + type: array + internalDNS: + description: InternalDNS are internal addresses of the service + inside the cluster + items: + type: string + type: array + internalIP: + description: |- + InternalIP are internal addresses of the service inside the cluster + https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + items: + type: string + type: array + nodePorts: + description: |- + NodePorts are the most basic network available. + NodePorts use the networks available on the hosts of kubernetes nodes. + This generally works from within a pod, and from the internal + network of the nodes, but may fail from public network. + https://kubernetes.io/docs/concepts/services-networking/service/#nodeport + items: + type: string + type: array + podPorts: + description: |- + PodPorts are the second most basic network address. + Every pod has an IP in the cluster and the pods network is a mesh + so the operator running inside a pod in the cluster can use this address. + Note: pod IPs are not guaranteed to persist over restarts, so should be rediscovered. + Note2: when running the operator outside of the cluster, pod IP is not accessible. + items: + type: string + type: array + type: object + serviceSyslog: + description: ServiceStatus is the status info and network addresses + of a service + properties: + externalDNS: + description: ExternalDNS are external public addresses for + the service + items: + type: string + type: array + externalIP: + description: |- + ExternalIP are external public addresses for the service + LoadBalancerPorts such as AWS ELB provide public address and load balancing for the service + IngressPorts are manually created public addresses for the service + https://kubernetes.io/docs/concepts/services-networking/service/#external-ips + https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer + https://kubernetes.io/docs/concepts/services-networking/ingress/ + items: + type: string + type: array + internalDNS: + description: InternalDNS are internal addresses of the service + inside the cluster + items: + type: string + type: array + internalIP: + description: |- + InternalIP are internal addresses of the service inside the cluster + https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + items: + type: string + type: array + nodePorts: + description: |- + NodePorts are the most basic network available. + NodePorts use the networks available on the hosts of kubernetes nodes. + This generally works from within a pod, and from the internal + network of the nodes, but may fail from public network. + https://kubernetes.io/docs/concepts/services-networking/service/#nodeport + items: + type: string + type: array + podPorts: + description: |- + PodPorts are the second most basic network address. + Every pod has an IP in the cluster and the pods network is a mesh + so the operator running inside a pod in the cluster can use this address. + Note: pod IPs are not guaranteed to persist over restarts, so should be rediscovered. + Note2: when running the operator outside of the cluster, pod IP is not accessible. + items: + type: string + type: array + type: object + required: + - serviceMgmt + - serviceS3 + type: object + upgradePhase: + description: Upgrade reports the status of the ongoing upgrade process + type: string + type: object + type: object + served: true + storage: true + subresources: + status: {} +` + const Sha256_deploy_crds_noobaa_io_noobaas_yaml = "0f61ab9eecb4ccd392e5e5e7932baa0fa12ba035b56c4d610a8eaaebb98c8188" const File_deploy_crds_noobaa_io_noobaas_yaml = `--- diff --git a/pkg/system/phase2_creating.go b/pkg/system/phase2_creating.go index 77f4110937..24fecf95b7 100644 --- a/pkg/system/phase2_creating.go +++ b/pkg/system/phase2_creating.go @@ -136,6 +136,14 @@ func (r *Reconciler) ReconcilePhaseCreatingForMainClusters() error { return err } } + + // create notification log pvc if bucket notifications is enabled and pvc was not set explicitly + if r.NooBaa.Spec.BucketNotifications.Enabled { + if err := r.ReconcileODFNotificationsPVC(); err != nil { + return err + } + } + util.KubeCreateOptional(util.KubeObject(bundle.File_deploy_scc_core_yaml).(*secv1.SecurityContextConstraints)) if err := r.ReconcileObject(r.ServiceMgmt, r.SetDesiredServiceMgmt); err != nil { return err @@ -451,12 +459,11 @@ func (r *Reconciler) setDesiredCoreEnv(c *corev1.Container) { } } - if r.NooBaa.Spec.NotificationsPVC != nil { + if r.NooBaa.Spec.BucketNotifications.Enabled {//TODO - has pvc envVar := corev1.EnvVar{ Name: "NOTIFICATION_LOG_DIR", Value: "/var/logs/notifications", } - util.MergeEnvArrays(&c.Env, &[]corev1.EnvVar{envVar}); } @@ -530,7 +537,7 @@ func (r *Reconciler) SetDesiredCoreApp() error { util.MergeVolumeMountList(&c.VolumeMounts, &bucketLogVolumeMounts) } - if r.NooBaa.Spec.NotificationsPVC != nil { + if r.NooBaa.Spec.BucketNotifications.Enabled { notificationVolumeMounts := []corev1.VolumeMount{{ Name: "notif-vol", MountPath: "/var/logs/notifications", @@ -541,32 +548,25 @@ func (r *Reconciler) SetDesiredCoreApp() error { Name: "notif-vol", VolumeSource: corev1.VolumeSource { PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource { - ClaimName: *r.NooBaa.Spec.NotificationsPVC, + ClaimName: r.BucketNotificationsPVC.Name, }, }, }} util.MergeVolumeList(&podSpec.Volumes, ¬ificationVolumes) - //find secrets that tell us how to connect to remote notifications servers, - //mount them so core can read them - notificatoinSecrets := &corev1.SecretList{} - noobaaNotifSelector, _ := labels.Parse("app=noobaa,noobaa=notifications") - util.KubeList(notificatoinSecrets, &client.ListOptions{Namespace: options.Namespace, LabelSelector: noobaaNotifSelector}) - - for _, notificationSecret := range notificatoinSecrets.Items { - + for _, notifSecret := range r.NooBaa.Spec.BucketNotifications.Connections { secretVolumeMounts := []corev1.VolumeMount{{ - Name: notificationSecret.Name, - MountPath: "/etc/notif_connect/" + notificationSecret.Name, + Name: notifSecret.Name, + MountPath: "/etc/notif_connect/" + notifSecret.Name, ReadOnly: true, }} util.MergeVolumeMountList(&c.VolumeMounts, &secretVolumeMounts) secretVolumes := []corev1.Volume{{ - Name: notificationSecret.Name, + Name: notifSecret.Name, VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ - SecretName: notificationSecret.Name, + SecretName: notifSecret.Name, }, }, }} @@ -1271,6 +1271,58 @@ func (r *Reconciler) prepareODFBucketLoggingPVC() error { return nil } +// ReconcileODFNotificationsPVC ensures the bucket notifications PVC is properly configured +func (r *Reconciler) ReconcileODFNotificationsPVC() error { + log := r.Logger.WithField("func", "ReconcileNotificationsPVC") + + // Return if notifications PVC already exist + if r.NooBaa.Spec.BucketNotifications.PVC != nil { + r.BucketNotificationsPVC.Name = *r.NooBaa.Spec.BucketNotifications.PVC + log.Infof("BucketNotifications.pvc %s already exists and supports RWX access mode. Skipping ReconcileODFBucketLoggingPVC.", r.BucketNotificationsPVC.Name) + return nil + } + + util.KubeCheck(r.BucketNotificationsPVC) + if r.BucketNotificationsPVC.UID != "" { + log.Infof("BucketNotifications.pvc %s already exists. Skipping creation.", r.BucketNotificationsPVC.Name) + return nil + } + + if err := r.prepareODFNotificationsPVC(); err != nil { + return err + } + r.Own(r.BucketNotificationsPVC) + + log.Infof("BucketNotifications.pvc %s does not exist. Creating...", r.BucketNotificationsPVC.Name) + err := r.Client.Create(r.Ctx, r.BucketNotificationsPVC) + if err != nil { + return err + } + + return nil +} + +// prepareODFNotificationsPVC configures the bucket notifications pvc +func (r *Reconciler) prepareODFNotificationsPVC() error { + r.BucketNotificationsPVC.Spec.AccessModes = []corev1.PersistentVolumeAccessMode{corev1.ReadWriteMany} + + sc := &storagev1.StorageClass{ + TypeMeta: metav1.TypeMeta{Kind: "StorageClass"}, + ObjectMeta: metav1.ObjectMeta{Name: "ocs-storagecluster-cephfs"}, + } + + // fallback to cephfs storageclass to create bucket logging pvc if running on ODF + if util.KubeCheck(sc) { + r.Logger.Infof("BucketNotifications.pvc not provided, defaulting to 'cephfs' storage class %s to create bucket notifications pvc", sc.Name) + r.BucketNotificationsPVC.Spec.StorageClassName = &sc.Name + } else { + return util.NewPersistentError("InvalidBucketNotificationsConfiguration", + "Bucket Notifications requires a Persistent Volume Claim (PVC) with ReadWriteMany (RWX) access mode. Please specify 'BucketNotifications.pvc'.") + } + + return nil +} + // SetDesiredPostgresDBConf fill desired postgres db config map func (r *Reconciler) SetDesiredPostgresDBConf() error { dbConfigYaml := util.KubeObject(bundle.File_deploy_internal_configmap_postgres_db_yaml).(*corev1.ConfigMap) diff --git a/pkg/system/phase4_configuring.go b/pkg/system/phase4_configuring.go index 14f81b4300..87062c6c9c 100644 --- a/pkg/system/phase4_configuring.go +++ b/pkg/system/phase4_configuring.go @@ -415,7 +415,7 @@ func (r *Reconciler) SetDesiredDeploymentEndpoint() error { } } - if r.NooBaa.Spec.NotificationsPVC != nil { + if r.NooBaa.Spec.BucketNotifications.Enabled { envVar := corev1.EnvVar{ Name: "NOTIFICATION_LOG_DIR", Value: "/var/logs/notifications", @@ -542,12 +542,12 @@ func (r *Reconciler) setDesiredEndpointMounts(podSpec *corev1.PodSpec, container util.MergeVolumeMountList(&container.VolumeMounts, &bucketLogVolumeMounts) } - if r.NooBaa.Spec.NotificationsPVC != nil { + if r.NooBaa.Spec.BucketNotifications.Enabled { notificationVolumes := []corev1.Volume{{ Name: "notif-vol", VolumeSource: corev1.VolumeSource{ PersistentVolumeClaim: &corev1.PersistentVolumeClaimVolumeSource{ - ClaimName: *r.NooBaa.Spec.NotificationsPVC, + ClaimName: r.BucketNotificationsPVC.Name, }, }, }} diff --git a/pkg/system/reconciler.go b/pkg/system/reconciler.go index 159421d804..9992e8520f 100644 --- a/pkg/system/reconciler.go +++ b/pkg/system/reconciler.go @@ -122,6 +122,7 @@ type Reconciler struct { AdapterHPA *autoscalingv2.HorizontalPodAutoscaler ExternalPgSecret *corev1.Secret ExternalPgSSLSecret *corev1.Secret + BucketNotificationsPVC *corev1.PersistentVolumeClaim } // NewReconciler initializes a reconciler to be used for loading or reconciling a noobaa system @@ -171,6 +172,7 @@ func NewReconciler( DefaultNsfsPvc: util.KubeObject(bundle.File_deploy_internal_nsfs_pvc_cr_yaml).(*corev1.PersistentVolumeClaim), OBCStorageClass: util.KubeObject(bundle.File_deploy_obc_storage_class_yaml).(*storagev1.StorageClass), BucketLoggingPVC: util.KubeObject(bundle.File_deploy_internal_pvc_agent_yaml).(*corev1.PersistentVolumeClaim), + BucketNotificationsPVC: util.KubeObject(bundle.File_deploy_internal_pvc_agent_yaml).(*corev1.PersistentVolumeClaim), PrometheusRule: util.KubeObject(bundle.File_deploy_internal_prometheus_rules_yaml).(*monitoringv1.PrometheusRule), ServiceMonitorMgmt: util.KubeObject(bundle.File_deploy_internal_servicemonitor_mgmt_yaml).(*monitoringv1.ServiceMonitor), ServiceMonitorS3: util.KubeObject(bundle.File_deploy_internal_servicemonitor_s3_yaml).(*monitoringv1.ServiceMonitor), @@ -230,6 +232,7 @@ func NewReconciler( r.KedaScaled.Namespace = r.Request.Namespace r.AdapterHPA.Namespace = r.Request.Namespace r.BucketLoggingPVC.Namespace = r.Request.Namespace + r.BucketNotificationsPVC.Namespace = r.Request.Namespace // Set Names r.NooBaa.Name = r.Request.Name @@ -274,6 +277,7 @@ func NewReconciler( r.KedaScaled.Name = r.Request.Name r.AdapterHPA.Name = r.Request.Name + "-hpav2" r.BucketLoggingPVC.Name = r.Request.Name + "-bucket-logging-pvc" + r.BucketNotificationsPVC.Name = r.Request.Name + "-bucket-notifications-pvc" // Set the target service for routes. r.RouteMgmt.Spec.To.Name = r.ServiceMgmt.Name