From 82333df6394296c535b1d757dbc42bb9013b66c1 Mon Sep 17 00:00:00 2001 From: Christian Schwede Date: Fri, 10 Nov 2023 16:31:17 +0100 Subject: [PATCH] Add NetworkAttachments From other similar patches: For network isolation outgoing traffic, service pods need to be attached additional networks. To achive this, the the `k8s.v1.cni.cncf.io/networks` annotation needs to be set on the pods. This adds a networkAttachments parameter to the CRD where it can be specified to which additional networks the service pods should be attached to. --- .../swift.openstack.org_swiftproxies.yaml | 17 +++++++ api/bases/swift.openstack.org_swifts.yaml | 22 +++++++++ .../swift.openstack.org_swiftstorages.yaml | 17 +++++++ api/v1beta1/swift_types.go | 5 +++ api/v1beta1/swiftproxy_types.go | 8 ++++ api/v1beta1/swiftstorage_types.go | 10 ++++- api/v1beta1/zz_generated.deepcopy.go | 45 +++++++++++++++++++ .../swift.openstack.org_swiftproxies.yaml | 17 +++++++ .../crd/bases/swift.openstack.org_swifts.yaml | 22 +++++++++ .../swift.openstack.org_swiftstorages.yaml | 17 +++++++ config/rbac/role.yaml | 8 ++++ controllers/swift_controller.go | 2 + controllers/swiftproxy_controller.go | 36 +++++++++++++++ controllers/swiftstorage_controller.go | 36 +++++++++++++++ 14 files changed, 261 insertions(+), 1 deletion(-) diff --git a/api/bases/swift.openstack.org_swiftproxies.yaml b/api/bases/swift.openstack.org_swiftproxies.yaml index b3f5a737..86c5cfd6 100644 --- a/api/bases/swift.openstack.org_swiftproxies.yaml +++ b/api/bases/swift.openstack.org_swiftproxies.yaml @@ -16,6 +16,10 @@ spec: scope: Namespaced versions: - additionalPrinterColumns: + - description: NetworkAttachments + jsonPath: .status.networkAttachments + name: NetworkAttachments + type: string - description: Status jsonPath: .status.conditions[0].status name: Status @@ -50,6 +54,12 @@ spec: containerImageProxy: description: Swift Proxy Container Image URL type: string + networkAttachments: + description: NetworkAttachments is a list of NetworkAttachment resource + names to expose the services to the given network + items: + type: string + type: array override: description: Override, provides the ability to override the generated manifest of several child resources. @@ -310,6 +320,13 @@ spec: - type type: object type: array + networkAttachments: + additionalProperties: + items: + type: string + type: array + description: NetworkAttachments status of the deployment pods + type: object readyCount: description: ReadyCount of SwiftProxy instances format: int32 diff --git a/api/bases/swift.openstack.org_swifts.yaml b/api/bases/swift.openstack.org_swifts.yaml index 556eb8e5..45235832 100644 --- a/api/bases/swift.openstack.org_swifts.yaml +++ b/api/bases/swift.openstack.org_swifts.yaml @@ -16,6 +16,10 @@ spec: scope: Namespaced versions: - additionalPrinterColumns: + - description: NetworkAttachments + jsonPath: .status.networkAttachments + name: NetworkAttachments + type: string - description: Status jsonPath: .status.conditions[0].status name: Status @@ -44,6 +48,12 @@ spec: spec: description: SwiftSpec defines the desired state of Swift properties: + networkAttachments: + description: NetworkAttachments is a list of NetworkAttachment resource + names to expose the services to the given network + items: + type: string + type: array storageClass: default: "" description: Storage class. This is passed to SwiftStorage unless @@ -63,6 +73,12 @@ spec: containerImageProxy: description: Swift Proxy Container Image URL type: string + networkAttachments: + description: NetworkAttachments is a list of NetworkAttachment + resource names to expose the services to the given network + items: + type: string + type: array override: description: Override, provides the ability to override the generated manifest of several child resources. @@ -326,6 +342,12 @@ spec: containerImageProxy: description: Image URL for Swift proxy service type: string + networkAttachments: + description: NetworkAttachments is a list of NetworkAttachment + resource names to expose the services to the given network + items: + type: string + type: array replicas: default: 1 format: int32 diff --git a/api/bases/swift.openstack.org_swiftstorages.yaml b/api/bases/swift.openstack.org_swiftstorages.yaml index a953d67e..58841f0e 100644 --- a/api/bases/swift.openstack.org_swiftstorages.yaml +++ b/api/bases/swift.openstack.org_swiftstorages.yaml @@ -16,6 +16,10 @@ spec: scope: Namespaced versions: - additionalPrinterColumns: + - description: NetworkAttachments + jsonPath: .status.networkAttachments + name: NetworkAttachments + type: string - description: Status jsonPath: .status.conditions[0].status name: Status @@ -59,6 +63,12 @@ spec: containerImageProxy: description: Image URL for Swift proxy service type: string + networkAttachments: + description: NetworkAttachments is a list of NetworkAttachment resource + names to expose the services to the given network + items: + type: string + type: array replicas: default: 1 format: int32 @@ -133,6 +143,13 @@ spec: - type type: object type: array + networkAttachments: + additionalProperties: + items: + type: string + type: array + description: NetworkAttachments status of the deployment pods + type: object readyCount: description: ReadyCount of SwiftStorage instances format: int32 diff --git a/api/v1beta1/swift_types.go b/api/v1beta1/swift_types.go index 46f0361c..2b574d01 100644 --- a/api/v1beta1/swift_types.go +++ b/api/v1beta1/swift_types.go @@ -55,6 +55,10 @@ type SwiftSpec struct { // +kubebuilder:validation:Required // +kubebuilder:default="" StorageClass string `json:"storageClass"` + + // +kubebuilder:validation:Optional + // NetworkAttachments is a list of NetworkAttachment resource names to expose the services to the given network + NetworkAttachments []string `json:"networkAttachments,omitempty"` } // SwiftStatus defines the observed state of Swift @@ -65,6 +69,7 @@ type SwiftStatus struct { //+kubebuilder:object:root=true //+kubebuilder:subresource:status +//+kubebuilder:printcolumn:name="NetworkAttachments",type="string",JSONPath=".status.networkAttachments",description="NetworkAttachments" //+kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[0].status",description="Status" //+kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[0].message",description="Message" diff --git a/api/v1beta1/swiftproxy_types.go b/api/v1beta1/swiftproxy_types.go index 36dbff17..5c1b20df 100644 --- a/api/v1beta1/swiftproxy_types.go +++ b/api/v1beta1/swiftproxy_types.go @@ -72,6 +72,10 @@ type SwiftProxySpec struct { // +kubebuilder:validation:Optional // Override, provides the ability to override the generated manifest of several child resources. Override ProxyOverrideSpec `json:"override,omitempty"` + + // +kubebuilder:validation:Optional + // NetworkAttachments is a list of NetworkAttachment resource names to expose the services to the given network + NetworkAttachments []string `json:"networkAttachments,omitempty"` } // ProxyOverrideSpec to override the generated manifest of several child resources. @@ -88,10 +92,14 @@ type SwiftProxyStatus struct { // Conditions Conditions condition.Conditions `json:"conditions,omitempty" optional:"true"` + + // NetworkAttachments status of the deployment pods + NetworkAttachments map[string][]string `json:"networkAttachments,omitempty"` } //+kubebuilder:object:root=true //+kubebuilder:subresource:status +//+kubebuilder:printcolumn:name="NetworkAttachments",type="string",JSONPath=".status.networkAttachments",description="NetworkAttachments" //+kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[0].status",description="Status" //+kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[0].message",description="Message" diff --git a/api/v1beta1/swiftstorage_types.go b/api/v1beta1/swiftstorage_types.go index 324d9302..5919c210 100644 --- a/api/v1beta1/swiftstorage_types.go +++ b/api/v1beta1/swiftstorage_types.go @@ -65,6 +65,10 @@ type SwiftStorageSpec struct { // +kubebuilder:default=swift-conf // Name of Secret containing swift.conf SwiftConfSecret string `json:"swiftConfSecret"` + + // +kubebuilder:validation:Optional + // NetworkAttachments is a list of NetworkAttachment resource names to expose the services to the given network + NetworkAttachments []string `json:"networkAttachments,omitempty"` } // SwiftStorageStatus defines the observed state of SwiftStorage @@ -72,12 +76,16 @@ type SwiftStorageStatus struct { // ReadyCount of SwiftStorage instances ReadyCount int32 `json:"readyCount,omitempty"` - // Conditions + // Conditions Conditions condition.Conditions `json:"conditions,omitempty" optional:"true"` + + // NetworkAttachments status of the deployment pods + NetworkAttachments map[string][]string `json:"networkAttachments,omitempty"` } //+kubebuilder:object:root=true //+kubebuilder:subresource:status +//+kubebuilder:printcolumn:name="NetworkAttachments",type="string",JSONPath=".status.networkAttachments",description="NetworkAttachments" //+kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[0].status",description="Status" //+kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[0].message",description="Message" diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 11cfdd85..081db798 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -207,6 +207,11 @@ func (in *SwiftProxySpec) DeepCopyInto(out *SwiftProxySpec) { } out.PasswordSelectors = in.PasswordSelectors in.Override.DeepCopyInto(&out.Override) + if in.NetworkAttachments != nil { + in, out := &in.NetworkAttachments, &out.NetworkAttachments + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SwiftProxySpec. @@ -229,6 +234,21 @@ func (in *SwiftProxyStatus) DeepCopyInto(out *SwiftProxyStatus) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.NetworkAttachments != nil { + in, out := &in.NetworkAttachments, &out.NetworkAttachments + *out = make(map[string][]string, len(*in)) + for key, val := range *in { + var outVal []string + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = make([]string, len(*in)) + copy(*out, *in) + } + (*out)[key] = outVal + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SwiftProxyStatus. @@ -355,6 +375,11 @@ func (in *SwiftSpec) DeepCopyInto(out *SwiftSpec) { in.SwiftRing.DeepCopyInto(&out.SwiftRing) in.SwiftStorage.DeepCopyInto(&out.SwiftStorage) in.SwiftProxy.DeepCopyInto(&out.SwiftProxy) + if in.NetworkAttachments != nil { + in, out := &in.NetworkAttachments, &out.NetworkAttachments + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SwiftSpec. @@ -456,6 +481,11 @@ func (in *SwiftStorageSpec) DeepCopyInto(out *SwiftStorageSpec) { *out = new(int32) **out = **in } + if in.NetworkAttachments != nil { + in, out := &in.NetworkAttachments, &out.NetworkAttachments + *out = make([]string, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SwiftStorageSpec. @@ -478,6 +508,21 @@ func (in *SwiftStorageStatus) DeepCopyInto(out *SwiftStorageStatus) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.NetworkAttachments != nil { + in, out := &in.NetworkAttachments, &out.NetworkAttachments + *out = make(map[string][]string, len(*in)) + for key, val := range *in { + var outVal []string + if val == nil { + (*out)[key] = nil + } else { + in, out := &val, &outVal + *out = make([]string, len(*in)) + copy(*out, *in) + } + (*out)[key] = outVal + } + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SwiftStorageStatus. diff --git a/config/crd/bases/swift.openstack.org_swiftproxies.yaml b/config/crd/bases/swift.openstack.org_swiftproxies.yaml index b3f5a737..86c5cfd6 100644 --- a/config/crd/bases/swift.openstack.org_swiftproxies.yaml +++ b/config/crd/bases/swift.openstack.org_swiftproxies.yaml @@ -16,6 +16,10 @@ spec: scope: Namespaced versions: - additionalPrinterColumns: + - description: NetworkAttachments + jsonPath: .status.networkAttachments + name: NetworkAttachments + type: string - description: Status jsonPath: .status.conditions[0].status name: Status @@ -50,6 +54,12 @@ spec: containerImageProxy: description: Swift Proxy Container Image URL type: string + networkAttachments: + description: NetworkAttachments is a list of NetworkAttachment resource + names to expose the services to the given network + items: + type: string + type: array override: description: Override, provides the ability to override the generated manifest of several child resources. @@ -310,6 +320,13 @@ spec: - type type: object type: array + networkAttachments: + additionalProperties: + items: + type: string + type: array + description: NetworkAttachments status of the deployment pods + type: object readyCount: description: ReadyCount of SwiftProxy instances format: int32 diff --git a/config/crd/bases/swift.openstack.org_swifts.yaml b/config/crd/bases/swift.openstack.org_swifts.yaml index 556eb8e5..45235832 100644 --- a/config/crd/bases/swift.openstack.org_swifts.yaml +++ b/config/crd/bases/swift.openstack.org_swifts.yaml @@ -16,6 +16,10 @@ spec: scope: Namespaced versions: - additionalPrinterColumns: + - description: NetworkAttachments + jsonPath: .status.networkAttachments + name: NetworkAttachments + type: string - description: Status jsonPath: .status.conditions[0].status name: Status @@ -44,6 +48,12 @@ spec: spec: description: SwiftSpec defines the desired state of Swift properties: + networkAttachments: + description: NetworkAttachments is a list of NetworkAttachment resource + names to expose the services to the given network + items: + type: string + type: array storageClass: default: "" description: Storage class. This is passed to SwiftStorage unless @@ -63,6 +73,12 @@ spec: containerImageProxy: description: Swift Proxy Container Image URL type: string + networkAttachments: + description: NetworkAttachments is a list of NetworkAttachment + resource names to expose the services to the given network + items: + type: string + type: array override: description: Override, provides the ability to override the generated manifest of several child resources. @@ -326,6 +342,12 @@ spec: containerImageProxy: description: Image URL for Swift proxy service type: string + networkAttachments: + description: NetworkAttachments is a list of NetworkAttachment + resource names to expose the services to the given network + items: + type: string + type: array replicas: default: 1 format: int32 diff --git a/config/crd/bases/swift.openstack.org_swiftstorages.yaml b/config/crd/bases/swift.openstack.org_swiftstorages.yaml index a953d67e..58841f0e 100644 --- a/config/crd/bases/swift.openstack.org_swiftstorages.yaml +++ b/config/crd/bases/swift.openstack.org_swiftstorages.yaml @@ -16,6 +16,10 @@ spec: scope: Namespaced versions: - additionalPrinterColumns: + - description: NetworkAttachments + jsonPath: .status.networkAttachments + name: NetworkAttachments + type: string - description: Status jsonPath: .status.conditions[0].status name: Status @@ -59,6 +63,12 @@ spec: containerImageProxy: description: Image URL for Swift proxy service type: string + networkAttachments: + description: NetworkAttachments is a list of NetworkAttachment resource + names to expose the services to the given network + items: + type: string + type: array replicas: default: 1 format: int32 @@ -133,6 +143,13 @@ spec: - type type: object type: array + networkAttachments: + additionalProperties: + items: + type: string + type: array + description: NetworkAttachments status of the deployment pods + type: object readyCount: description: ReadyCount of SwiftStorage instances format: int32 diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 848d8a05..782d6483 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -119,6 +119,14 @@ rules: - patch - update - watch +- apiGroups: + - k8s.cni.cncf.io + resources: + - network-attachment-definitions + verbs: + - get + - list + - watch - apiGroups: - keystone.openstack.org resources: diff --git a/controllers/swift_controller.go b/controllers/swift_controller.go index 8addb32a..9b889e47 100644 --- a/controllers/swift_controller.go +++ b/controllers/swift_controller.go @@ -352,6 +352,7 @@ func (r *SwiftReconciler) storageCreateOrUpdate(ctx context.Context, instance *s ContainerImageProxy: instance.Spec.SwiftStorage.ContainerImageProxy, ContainerImageMemcached: instance.Spec.SwiftStorage.ContainerImageMemcached, SwiftConfSecret: instance.Spec.SwiftConfSecret, + NetworkAttachments: instance.Spec.SwiftStorage.NetworkAttachments, } deployment := &swiftv1.SwiftStorage{ @@ -385,6 +386,7 @@ func (r *SwiftReconciler) proxyCreateOrUpdate(ctx context.Context, instance *swi PasswordSelectors: instance.Spec.SwiftProxy.PasswordSelectors, SwiftConfSecret: instance.Spec.SwiftConfSecret, Override: instance.Spec.SwiftProxy.Override, + NetworkAttachments: instance.Spec.SwiftStorage.NetworkAttachments, } deployment := &swiftv1.SwiftProxy{ diff --git a/controllers/swiftproxy_controller.go b/controllers/swiftproxy_controller.go index fd6b38b5..fc4bb943 100644 --- a/controllers/swiftproxy_controller.go +++ b/controllers/swiftproxy_controller.go @@ -38,6 +38,7 @@ import ( "github.com/openstack-k8s-operators/lib-common/modules/common/endpoint" "github.com/openstack-k8s-operators/lib-common/modules/common/env" "github.com/openstack-k8s-operators/lib-common/modules/common/helper" + "github.com/openstack-k8s-operators/lib-common/modules/common/networkattachment" "github.com/openstack-k8s-operators/lib-common/modules/common/secret" service "github.com/openstack-k8s-operators/lib-common/modules/common/service" "github.com/openstack-k8s-operators/lib-common/modules/common/util" @@ -64,6 +65,7 @@ type SwiftProxyReconciler struct { //+kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneendpoints,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=keystone.openstack.org,resources=keystoneservices,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch;create;update;patch;delete; +//+kubebuilder:rbac:groups=k8s.cni.cncf.io,resources=network-attachment-definitions,verbs=get;list;watch // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. @@ -95,6 +97,7 @@ func (r *SwiftProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request) instance.Status.Conditions = condition.Conditions{} cl := condition.CreateList( condition.UnknownCondition(condition.ReadyCondition, condition.InitReason, condition.ReadyInitMessage), + condition.UnknownCondition(condition.NetworkAttachmentsReadyCondition, condition.InitReason, condition.NetworkAttachmentsReadyInitMessage), condition.UnknownCondition(swiftv1beta1.SwiftProxyReadyCondition, condition.InitReason, swiftv1beta1.SwiftProxyReadyInitMessage), ) @@ -115,6 +118,10 @@ func (r *SwiftProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request) return ctrl.Result{}, err } + if instance.Status.NetworkAttachments == nil { + instance.Status.NetworkAttachments = map[string][]string{} + } + if !instance.DeletionTimestamp.IsZero() { return r.reconcileDelete(ctx, instance, helper) } @@ -293,6 +300,35 @@ func (r *SwiftProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request) return ctrl.Result{}, err } + // networks to attach to + for _, netAtt := range instance.Spec.NetworkAttachments { + _, err := networkattachment.GetNADWithName(ctx, helper, netAtt, instance.Namespace) + if err != nil { + if apierrors.IsNotFound(err) { + instance.Status.Conditions.Set(condition.FalseCondition( + condition.NetworkAttachmentsReadyCondition, + condition.RequestedReason, + condition.SeverityInfo, + condition.NetworkAttachmentsReadyWaitingMessage, + netAtt)) + return ctrl.Result{RequeueAfter: time.Second * 10}, fmt.Errorf("network-attachment-definition %s not found", netAtt) + } + instance.Status.Conditions.Set(condition.FalseCondition( + condition.NetworkAttachmentsReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + condition.NetworkAttachmentsReadyErrorMessage, + err.Error())) + return ctrl.Result{}, err + } + } + + _, err = networkattachment.CreateNetworksAnnotation(instance.Namespace, instance.Spec.NetworkAttachments) + if err != nil { + return ctrl.Result{}, fmt.Errorf("failed create network annotation from %s: %w", + instance.Spec.NetworkAttachments, err) + } + // Create Deployment depl := deployment.NewDeployment(swiftproxy.Deployment(instance, serviceLabels), 5*time.Second) ctrlResult, err = depl.CreateOrPatch(ctx, helper) diff --git a/controllers/swiftstorage_controller.go b/controllers/swiftstorage_controller.go index 9bf5f377..1d6384ab 100644 --- a/controllers/swiftstorage_controller.go +++ b/controllers/swiftstorage_controller.go @@ -43,6 +43,7 @@ import ( "github.com/openstack-k8s-operators/lib-common/modules/common/condition" "github.com/openstack-k8s-operators/lib-common/modules/common/configmap" "github.com/openstack-k8s-operators/lib-common/modules/common/env" + "github.com/openstack-k8s-operators/lib-common/modules/common/networkattachment" ) // SwiftStorageReconciler reconciles a SwiftStorage object @@ -59,6 +60,7 @@ type SwiftStorageReconciler struct { //+kubebuilder:rbac:groups=apps,resources=statefulsets,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core,resources=services,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=core,resources=configmaps,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=k8s.cni.cncf.io,resources=network-attachment-definitions,verbs=get;list;watch // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. @@ -90,6 +92,7 @@ func (r *SwiftStorageReconciler) Reconcile(ctx context.Context, req ctrl.Request instance.Status.Conditions = condition.Conditions{} cl := condition.CreateList( condition.UnknownCondition(condition.ReadyCondition, condition.InitReason, condition.ReadyInitMessage), + condition.UnknownCondition(condition.NetworkAttachmentsReadyCondition, condition.InitReason, condition.NetworkAttachmentsReadyInitMessage), condition.UnknownCondition(swiftv1beta1.SwiftStorageReadyCondition, condition.InitReason, condition.ReadyInitMessage), ) @@ -100,6 +103,10 @@ func (r *SwiftStorageReconciler) Reconcile(ctx context.Context, req ctrl.Request } } + if instance.Status.NetworkAttachments == nil { + instance.Status.NetworkAttachments = map[string][]string{} + } + if !instance.DeletionTimestamp.IsZero() { return ctrl.Result{}, nil } @@ -162,6 +169,35 @@ func (r *SwiftStorageReconciler) Reconcile(ctx context.Context, req ctrl.Request return ctrlResult, nil } + // networks to attach to + for _, netAtt := range instance.Spec.NetworkAttachments { + _, err := networkattachment.GetNADWithName(ctx, helper, netAtt, instance.Namespace) + if err != nil { + if apierrors.IsNotFound(err) { + instance.Status.Conditions.Set(condition.FalseCondition( + condition.NetworkAttachmentsReadyCondition, + condition.RequestedReason, + condition.SeverityInfo, + condition.NetworkAttachmentsReadyWaitingMessage, + netAtt)) + return ctrl.Result{RequeueAfter: time.Second * 10}, fmt.Errorf("network-attachment-definition %s not found", netAtt) + } + instance.Status.Conditions.Set(condition.FalseCondition( + condition.NetworkAttachmentsReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + condition.NetworkAttachmentsReadyErrorMessage, + err.Error())) + return ctrl.Result{}, err + } + } + + _, err = networkattachment.CreateNetworksAnnotation(instance.Namespace, instance.Spec.NetworkAttachments) + if err != nil { + return ctrl.Result{}, fmt.Errorf("failed create network annotation from %s: %w", + instance.Spec.NetworkAttachments, err) + } + // Statefulset with all backend containers sset := statefulset.NewStatefulSet(swiftstorage.StatefulSet(instance, serviceLabels), 5*time.Second) ctrlResult, err = sset.CreateOrPatch(ctx, helper)