From 1538a96c0612814d41dfb4bea53166d08962f983 Mon Sep 17 00:00:00 2001 From: Christian Schwede Date: Fri, 9 Feb 2024 10:55:54 +0100 Subject: [PATCH 1/3] Refactor ring device setup Creates device list now within the SwiftRing instance instead of the SwiftStorage instance. This is preliminary work to add device setup for dataplane nodes in the SwiftRing instance as well. This cleans up the SwiftStorage instance quite a bit and moves ring management code into the SwiftRing instance. Also change the logic: the ring rebalance job is now only executed if the deviceList hash did change, changes to the Swift ring file ConfigMap no longer trigger a rebalance. --- controllers/swiftring_controller.go | 73 +++++++++++++------------- controllers/swiftstorage_controller.go | 27 +--------- pkg/swiftring/funcs.go | 64 ++++++++++++++++++++++ pkg/swiftring/templates.go | 13 ++++- pkg/swiftstorage/funcs.go | 38 -------------- pkg/swiftstorage/templates.go | 16 ------ 6 files changed, 114 insertions(+), 117 deletions(-) diff --git a/controllers/swiftring_controller.go b/controllers/swiftring_controller.go index a1bd616b..447c5b03 100644 --- a/controllers/swiftring_controller.go +++ b/controllers/swiftring_controller.go @@ -151,31 +151,40 @@ func (r *SwiftRingReconciler) reconcileNormal(ctx context.Context, instance *swi serviceLabels := swiftring.Labels() - // Create a ConfigMap populated with content from templates/ - envVars := make(map[string]env.Setter) - tpl := swiftring.ConfigMapTemplates(instance, serviceLabels) - err := configmap.EnsureConfigMaps(ctx, helper, instance, tpl, &envVars) - if err != nil { - return ctrl.Result{}, err - } - // Swift ring init job - start if instance.Status.Hash == nil { instance.Status.Hash = map[string]string{} } - ringCreateHash := instance.Status.Hash[swiftv1beta1.RingCreateHash] - // Check if the device list ConfigMap did change and if so, delete the - // rebalance Job. This will result in a new Job that rebalances with - // the updated device list - _, deviceListHash, err := configmap.GetConfigMapAndHashWithName(ctx, helper, swift.DeviceConfigMapName, instance.Namespace) + deviceList, deviceListHash, err := swiftring.DeviceList(ctx, helper, instance) if err != nil { return ctrl.Result{}, err } + if instance.Status.Hash[swiftv1beta1.DeviceListHash] != deviceListHash { - if err := job.DeleteJob(ctx, helper, instance.Name+"-rebalance", instance.Namespace); err != nil { + // Create or update the devicelist ConfigMap + envVars := make(map[string]env.Setter) + tpl := swiftring.ConfigMapTemplates(instance, serviceLabels, deviceList) + err = configmap.EnsureConfigMaps(ctx, helper, instance, tpl, &envVars) + if err != nil { return ctrl.Result{}, err } + + // Delete a possibly still existing job that finished to re-run the job + j, err := job.GetJobWithName(ctx, helper, instance.Name+"-rebalance", instance.Namespace) + if err != nil { + if !apierrors.IsNotFound(err) { + return ctrl.Result{}, err + } + } else { + if j.Status.Active == 0 { + err = job.DeleteJob(ctx, helper, instance.Name+"-rebalance", instance.Namespace) + if err != nil { + return ctrl.Result{}, err + } + } + } + instance.Status.Hash[swiftv1beta1.RingCreateHash] = "" instance.Status.Hash[swiftv1beta1.DeviceListHash] = deviceListHash if err := r.Status().Update(ctx, instance); err != nil { @@ -183,7 +192,7 @@ func (r *SwiftRingReconciler) reconcileNormal(ctx context.Context, instance *swi } } - ringCreateJob := job.NewJob(swiftring.GetRingJob(instance, serviceLabels), swiftv1beta1.RingCreateHash, false, 5*time.Second, ringCreateHash) + ringCreateJob := job.NewJob(swiftring.GetRingJob(instance, serviceLabels), "rebalance", false, 5*time.Second, instance.Status.Hash[swiftv1beta1.RingCreateHash]) ctrlResult, err := ringCreateJob.DoJob(ctx, helper) if (ctrlResult != ctrl.Result{}) { instance.Status.Conditions.Set(condition.FalseCondition( @@ -191,9 +200,6 @@ func (r *SwiftRingReconciler) reconcileNormal(ctx context.Context, instance *swi condition.RequestedReason, condition.SeverityInfo, condition.ReadyInitMessage)) - if err := r.Status().Update(ctx, instance); err != nil { - return ctrl.Result{}, err - } return ctrlResult, nil } if err != nil { @@ -210,7 +216,6 @@ func (r *SwiftRingReconciler) reconcileNormal(ctx context.Context, instance *swi if ringCreateJob.HasChanged() { instance.Status.Hash[swiftv1beta1.RingCreateHash] = ringCreateJob.GetHash() - instance.Status.Hash[swiftv1beta1.DeviceListHash] = deviceListHash if err := r.Status().Update(ctx, instance); err != nil { return ctrl.Result{}, err } @@ -255,24 +260,20 @@ func (r *SwiftRingReconciler) reconcileDelete(ctx context.Context, instance *swi // SetupWithManager sets up the controller with the Manager. func (r *SwiftRingReconciler) SetupWithManager(mgr ctrl.Manager) error { - deviceConfigMapFilter := func(ctx context.Context, o client.Object) []reconcile.Request { + swiftRingFilter := func(ctx context.Context, o client.Object) []reconcile.Request { result := []reconcile.Request{} - if o.GetName() == swift.DeviceConfigMapName { - // There should be only one SwiftRing instance within - // the Namespace - that needs to be reconciled - swiftRings := &swiftv1beta1.SwiftRingList{} - listOpts := []client.ListOption{client.InNamespace(o.GetNamespace())} - err := r.Client.List(context.Background(), swiftRings, listOpts...) - if err != nil { - return nil - } - for _, cr := range swiftRings.Items { - name := client.ObjectKey{ - Namespace: o.GetNamespace(), - Name: cr.Name, - } - result = append(result, reconcile.Request{NamespacedName: name}) + swiftRings := &swiftv1beta1.SwiftRingList{} + listOpts := []client.ListOption{client.InNamespace(o.GetNamespace())} + err := r.Client.List(context.Background(), swiftRings, listOpts...) + if err != nil { + return nil + } + for _, cr := range swiftRings.Items { + name := client.ObjectKey{ + Namespace: o.GetNamespace(), + Name: cr.Name, } + result = append(result, reconcile.Request{NamespacedName: name}) } return result } @@ -283,6 +284,6 @@ func (r *SwiftRingReconciler) SetupWithManager(mgr ctrl.Manager) error { Owns(&corev1.ConfigMap{}). Owns(&rbacv1.ClusterRole{}). Owns(&rbacv1.ClusterRoleBinding{}). - Watches(&corev1.ConfigMap{}, handler.EnqueueRequestsFromMapFunc(deviceConfigMapFilter)). + Watches(&swiftv1beta1.SwiftStorage{}, handler.EnqueueRequestsFromMapFunc(swiftRingFilter)). Complete(r) } diff --git a/controllers/swiftstorage_controller.go b/controllers/swiftstorage_controller.go index b4304052..c7ce04be 100644 --- a/controllers/swiftstorage_controller.go +++ b/controllers/swiftstorage_controller.go @@ -41,7 +41,6 @@ import ( "k8s.io/client-go/kubernetes" swiftv1beta1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1" - "github.com/openstack-k8s-operators/swift-operator/pkg/swift" "github.com/openstack-k8s-operators/swift-operator/pkg/swiftstorage" "github.com/openstack-k8s-operators/lib-common/modules/common/condition" @@ -141,22 +140,6 @@ func (r *SwiftStorageReconciler) Reconcile(ctx context.Context, req ctrl.Request serviceLabels := swiftstorage.Labels() envVars := make(map[string]env.Setter) - // Check if there is already an existing ConfigMap and device list. If - // not, create an initial device list to bootstrap the cluster with The - // weights are simply set to the requested size, this will be changed - // once all StatefulSets are running - _, ctrlResult, err := configmap.GetConfigMap(ctx, helper, instance, swift.DeviceConfigMapName, 5*time.Second) - if err != nil { - return ctrlResult, err - } else if (ctrlResult != ctrl.Result{}) { - devices := swiftstorage.DeviceList(ctx, helper, instance) - tpl := swiftstorage.DeviceConfigMapTemplates(instance, devices) - err = configmap.EnsureConfigMaps(ctx, helper, instance, tpl, &envVars) - if err != nil { - return ctrl.Result{}, err - } - } - // Create a ConfigMap populated with content from templates/ tpl := swiftstorage.ConfigMapTemplates(instance, serviceLabels, instance.Spec.MemcachedServers) err = configmap.EnsureConfigMaps(ctx, helper, instance, tpl, &envVars) @@ -169,7 +152,7 @@ func (r *SwiftStorageReconciler) Reconcile(ctx context.Context, req ctrl.Request if err != nil { return ctrl.Result{}, err } - ctrlResult, err = svc.CreateOrPatch(ctx, helper) + ctrlResult, err := svc.CreateOrPatch(ctx, helper) if err != nil { return ctrlResult, err } else if (ctrlResult != ctrl.Result{}) { @@ -236,14 +219,6 @@ func (r *SwiftStorageReconciler) Reconcile(ctx context.Context, req ctrl.Request instance.Status.ReadyCount = sset.GetStatefulSet().Status.ReadyReplicas if instance.Status.ReadyCount == *instance.Spec.Replicas { - envVars := make(map[string]env.Setter) - devices := swiftstorage.DeviceList(ctx, helper, instance) - tpl = swiftstorage.DeviceConfigMapTemplates(instance, devices) - err = configmap.EnsureConfigMaps(ctx, helper, instance, tpl, &envVars) - if err != nil { - return ctrl.Result{}, err - } - // When the cluster is attached to an external network, create DNS record for every // cluster member so it can be resolved from outside cluster (edpm nodes) podList, err := pod.GetPodListWithLabel(ctx, helper, instance.Namespace, serviceLabels) diff --git a/pkg/swiftring/funcs.go b/pkg/swiftring/funcs.go index c4ae575d..99c3b665 100644 --- a/pkg/swiftring/funcs.go +++ b/pkg/swiftring/funcs.go @@ -16,10 +16,74 @@ limitations under the License. package swiftring import ( + "context" + "fmt" + "sort" + "strings" + + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/openstack-k8s-operators/lib-common/modules/common" + "github.com/openstack-k8s-operators/lib-common/modules/common/helper" + "github.com/openstack-k8s-operators/lib-common/modules/common/util" + + swiftv1beta1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1" "github.com/openstack-k8s-operators/swift-operator/pkg/swift" ) +//+kubebuilder:rbac:groups=core,resources=persistentvolumeclaims,verbs=get;list;watch + +func DeviceList(ctx context.Context, h *helper.Helper, instance *swiftv1beta1.SwiftRing) (string, string, error) { + // Returns a list of devices as CSV + devices := []string{} + + listOpts := []client.ListOption{client.InNamespace(instance.GetNamespace())} + + // Get all SwiftStorage instances + storages := &swiftv1beta1.SwiftStorageList{} + err := h.GetClient().List(context.Background(), storages, listOpts...) + if err != nil && !errors.IsNotFound(err) { + return "", "", err + } + for _, storageInstance := range storages.Items { + for replica := 0; replica < int(*storageInstance.Spec.Replicas); replica++ { + cn := fmt.Sprintf("%s-%s-%d", swift.ClaimName, storageInstance.Name, replica) + foundClaim := &corev1.PersistentVolumeClaim{} + err = h.GetClient().Get(ctx, types.NamespacedName{Name: cn, Namespace: storageInstance.Namespace}, foundClaim) + capacity := resource.MustParse(storageInstance.Spec.StorageRequest) + weight, _ := capacity.AsInt64() + if err == nil { + capacity := foundClaim.Status.Capacity["storage"] + weight, _ = capacity.AsInt64() + } else { + h.GetLogger().Info(fmt.Sprintf("Did not find PVC %s, assuming %s as capacity", cn, storageInstance.Spec.StorageRequest)) + } + weight = weight / (1000 * 1000 * 1000) // 10GiB gets a weight of 10 etc. + // CSV: region,zone,hostname,devicename,weight + devices = append(devices, fmt.Sprintf("1,1,%s-%d.%s,%s,%d\n", storageInstance.Name, replica, storageInstance.Name, "d1", weight)) + } + } + + // Device list must be sorted to ensure hash does not change + sort.Strings(devices) + + var deviceList strings.Builder + for _, line := range devices { + deviceList.WriteString(line) + } + + deviceListHash, err := util.ObjectHash(deviceList.String()) + if err != nil { + return "", "", err + } + + return deviceList.String(), deviceListHash, nil +} + func Labels() map[string]string { return map[string]string{ common.AppSelector: swift.ServiceName, diff --git a/pkg/swiftring/templates.go b/pkg/swiftring/templates.go index eddeb638..1d0ff05c 100644 --- a/pkg/swiftring/templates.go +++ b/pkg/swiftring/templates.go @@ -20,10 +20,21 @@ import ( "fmt" "github.com/openstack-k8s-operators/lib-common/modules/common/util" swiftv1beta1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1" + "github.com/openstack-k8s-operators/swift-operator/pkg/swift" ) -func ConfigMapTemplates(instance *swiftv1beta1.SwiftRing, labels map[string]string) []util.Template { +func ConfigMapTemplates(instance *swiftv1beta1.SwiftRing, labels map[string]string, devices string) []util.Template { + data := make(map[string]string) + data["devices.csv"] = devices + return []util.Template{ + { + Name: swift.DeviceConfigMapName, + Namespace: instance.Namespace, + Type: util.TemplateTypeNone, + InstanceType: instance.Kind, + CustomData: data, + }, { Name: fmt.Sprintf("%s-scripts", instance.Name), Namespace: instance.Namespace, diff --git a/pkg/swiftstorage/funcs.go b/pkg/swiftstorage/funcs.go index 0c4e8192..ec3debc8 100644 --- a/pkg/swiftstorage/funcs.go +++ b/pkg/swiftstorage/funcs.go @@ -17,48 +17,10 @@ limitations under the License. package swiftstorage import ( - "context" - "fmt" - "strings" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/apimachinery/pkg/types" - "github.com/openstack-k8s-operators/lib-common/modules/common" - "github.com/openstack-k8s-operators/lib-common/modules/common/helper" - - swiftv1beta1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1" "github.com/openstack-k8s-operators/swift-operator/pkg/swift" ) -//+kubebuilder:rbac:groups=core,resources=persistentvolumeclaims,verbs=get;list;watch - -func DeviceList(ctx context.Context, h *helper.Helper, instance *swiftv1beta1.SwiftStorage) string { - // Creates a CSV list of devices. If PVCs do not exist yet (because not - // all StatefulSets are up yet), it will just use the request capacity - // as value. - var devices strings.Builder - - foundClaim := &corev1.PersistentVolumeClaim{} - for replica := 0; replica < int(*instance.Spec.Replicas); replica++ { - cn := fmt.Sprintf("%s-%s-%d", swift.ClaimName, instance.Name, replica) - err := h.GetClient().Get(ctx, types.NamespacedName{Name: cn, Namespace: instance.Namespace}, foundClaim) - capacity := resource.MustParse(instance.Spec.StorageRequest) - weight, _ := capacity.AsInt64() - if err == nil { - capacity := foundClaim.Status.Capacity["storage"] - weight, _ = capacity.AsInt64() - } else { - h.GetLogger().Info(fmt.Sprintf("Did not find PVC %s, assuming %s as capacity", cn, instance.Spec.StorageRequest)) - } - weight = weight / (1000 * 1000 * 1000) // 10GiB gets a weight of 10 etc. - // CSV: region,zone,hostname,devicename,weight - devices.WriteString(fmt.Sprintf("1,1,%s-%d.%s.%s.svc,%s,%d\n", instance.Name, replica, instance.Name, instance.Namespace, "d1", weight)) - } - return devices.String() -} - func Labels() map[string]string { return map[string]string{ common.AppSelector: swift.ServiceName, diff --git a/pkg/swiftstorage/templates.go b/pkg/swiftstorage/templates.go index c01e9bc2..e2e8dfa6 100644 --- a/pkg/swiftstorage/templates.go +++ b/pkg/swiftstorage/templates.go @@ -20,7 +20,6 @@ import ( "fmt" "github.com/openstack-k8s-operators/lib-common/modules/common/util" swiftv1beta1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1" - "github.com/openstack-k8s-operators/swift-operator/pkg/swift" ) func ConfigMapTemplates(instance *swiftv1beta1.SwiftStorage, labels map[string]string, memcachedServers string) []util.Template { @@ -52,18 +51,3 @@ func ConfigMapTemplates(instance *swiftv1beta1.SwiftStorage, labels map[string]s }, } } - -func DeviceConfigMapTemplates(instance *swiftv1beta1.SwiftStorage, devices string) []util.Template { - data := make(map[string]string) - data["devices.csv"] = devices - - return []util.Template{ - { - Name: swift.DeviceConfigMapName, - Namespace: instance.Namespace, - Type: util.TemplateTypeNone, - InstanceType: instance.Kind, - CustomData: data, - }, - } -} From e61fc48bac16abaf8e8cc37aa82809cc75e0b3e6 Mon Sep 17 00:00:00 2001 From: Christian Schwede Date: Wed, 21 Feb 2024 13:00:55 +0100 Subject: [PATCH 2/3] Add additional CRD to Kuttl tests This CRD is required to run kuttl tests if the dataplane-operator is not deployed and the swift-operator iterates over the NodesetList. --- ...nstack.org_openstackdataplanenodesets.yaml | 1984 +++++++++++++++++ tests/kuttl/tests/basic-deploy/00-deps.yaml | 7 + .../kuttl/tests/basic-deploy_tls/00-deps.yaml | 7 + 3 files changed, 1998 insertions(+) create mode 100644 tests/kuttl/deps/dataplane.openstack.org_openstackdataplanenodesets.yaml create mode 100644 tests/kuttl/tests/basic-deploy/00-deps.yaml create mode 100644 tests/kuttl/tests/basic-deploy_tls/00-deps.yaml diff --git a/tests/kuttl/deps/dataplane.openstack.org_openstackdataplanenodesets.yaml b/tests/kuttl/deps/dataplane.openstack.org_openstackdataplanenodesets.yaml new file mode 100644 index 00000000..80de2948 --- /dev/null +++ b/tests/kuttl/deps/dataplane.openstack.org_openstackdataplanenodesets.yaml @@ -0,0 +1,1984 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.11.1 + creationTimestamp: null + name: openstackdataplanenodesets.dataplane.openstack.org +spec: + group: dataplane.openstack.org + names: + kind: OpenStackDataPlaneNodeSet + listKind: OpenStackDataPlaneNodeSetList + plural: openstackdataplanenodesets + shortNames: + - osdpns + - osdpnodeset + - osdpnodesets + singular: openstackdataplanenodeset + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Status + jsonPath: .status.conditions[0].status + name: Status + type: string + - description: Message + jsonPath: .status.conditions[0].message + name: Message + type: string + name: v1beta1 + schema: + openAPIV3Schema: + properties: + apiVersion: + type: string + kind: + type: string + metadata: + type: object + spec: + properties: + baremetalSetTemplate: + properties: + agentImageUrl: + type: string + apacheImageUrl: + type: string + automatedCleaningMode: + default: metadata + enum: + - metadata + - disabled + type: string + baremetalHosts: + additionalProperties: + properties: + ctlPlaneIP: + type: string + networkData: + properties: + name: + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + userData: + properties: + name: + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + type: object + type: object + bmhLabelSelector: + additionalProperties: + type: string + type: object + bmhNamespace: + default: openshift-machine-api + type: string + bootstrapDns: + items: + type: string + type: array + cloudUserName: + default: cloud-admin + type: string + ctlplaneGateway: + type: string + ctlplaneInterface: + type: string + ctlplaneNetmask: + default: 255.255.255.0 + type: string + deploymentSSHSecret: + type: string + dnsSearchDomains: + items: + type: string + type: array + domainName: + type: string + hardwareReqs: + properties: + cpuReqs: + properties: + arch: + enum: + - x86_64 + - ppc64le + type: string + countReq: + properties: + count: + minimum: 1 + type: integer + exactMatch: + type: boolean + type: object + mhzReq: + properties: + exactMatch: + type: boolean + mhz: + minimum: 1 + type: integer + type: object + type: object + diskReqs: + properties: + gbReq: + properties: + exactMatch: + type: boolean + gb: + minimum: 1 + type: integer + type: object + ssdReq: + properties: + exactMatch: + type: boolean + ssd: + type: boolean + type: object + type: object + memReqs: + properties: + gbReq: + properties: + exactMatch: + type: boolean + gb: + minimum: 1 + type: integer + type: object + type: object + type: object + networkData: + properties: + name: + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + osContainerImageUrl: + type: string + osImage: + type: string + passwordSecret: + properties: + name: + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + provisionServerName: + type: string + provisioningInterface: + type: string + userData: + properties: + name: + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - cloudUserName + - ctlplaneInterface + - deploymentSSHSecret + type: object + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + properties: + containerName: + type: string + divisor: + 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 + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + networkAttachments: + items: + type: string + type: array + nodeTemplate: + properties: + ansible: + properties: + ansibleHost: + type: string + ansiblePort: + type: integer + ansibleUser: + type: string + ansibleVars: + x-kubernetes-preserve-unknown-fields: true + type: object + ansibleSSHPrivateKeySecret: + type: string + extraMounts: + items: + properties: + extraVolType: + type: string + mounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + propagation: + items: + type: string + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + 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 + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + 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 + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + 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 + 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 + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + 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 + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - mounts + - volumes + type: object + type: array + managementNetwork: + default: ctlplane + type: string + networkData: + properties: + name: + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + networks: + items: + properties: + defaultRoute: + type: boolean + fixedIP: + type: string + name: + pattern: ^[a-zA-Z0-9][a-zA-Z0-9\-_]*[a-zA-Z0-9]$ + type: string + subnetName: + pattern: ^[a-zA-Z0-9][a-zA-Z0-9\-_]*[a-zA-Z0-9]$ + type: string + required: + - name + - subnetName + type: object + type: array + userData: + properties: + name: + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - ansibleSSHPrivateKeySecret + type: object + nodes: + additionalProperties: + properties: + ansible: + properties: + ansibleHost: + type: string + ansiblePort: + type: integer + ansibleUser: + type: string + ansibleVars: + x-kubernetes-preserve-unknown-fields: true + type: object + extraMounts: + items: + properties: + extraVolType: + type: string + mounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + propagation: + items: + type: string + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + 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 + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + 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 + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + required: + - kind + - name + type: object + resources: + properties: + claims: + items: + properties: + name: + 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 + 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 + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + 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 + resource: + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - mounts + - volumes + type: object + type: array + hostName: + type: string + managementNetwork: + type: string + networkData: + properties: + name: + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + networks: + items: + properties: + defaultRoute: + type: boolean + fixedIP: + type: string + name: + pattern: ^[a-zA-Z0-9][a-zA-Z0-9\-_]*[a-zA-Z0-9]$ + type: string + subnetName: + pattern: ^[a-zA-Z0-9][a-zA-Z0-9\-_]*[a-zA-Z0-9]$ + type: string + required: + - name + - subnetName + type: object + type: array + userData: + properties: + name: + type: string + namespace: + type: string + type: object + x-kubernetes-map-type: atomic + type: object + type: object + preProvisioned: + type: boolean + services: + default: + - download-cache + - bootstrap + - configure-network + - validate-network + - install-os + - configure-os + - run-os + - reboot-os + - install-certs + - ovn + - neutron-metadata + - libvirt + - nova + - telemetry + items: + type: string + type: array + tags: + items: + type: string + type: array + tlsEnabled: + default: false + type: boolean + required: + - nodeTemplate + - nodes + type: object + status: + properties: + allHostnames: + additionalProperties: + additionalProperties: + type: string + type: object + type: object + allIPs: + additionalProperties: + additionalProperties: + type: string + type: object + type: object + conditions: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + severity: + type: string + status: + type: string + type: + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + configHash: + type: string + configMapHashes: + additionalProperties: + type: string + type: object + ctlplaneSearchDomain: + type: string + deployed: + type: boolean + deployedConfigHash: + type: string + deploymentStatuses: + additionalProperties: + items: + properties: + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + severity: + type: string + status: + type: string + type: + type: string + required: + - lastTransitionTime + - status + - type + type: object + type: array + type: object + dnsClusterAddresses: + items: + type: string + type: array + secretHashes: + additionalProperties: + type: string + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/tests/kuttl/tests/basic-deploy/00-deps.yaml b/tests/kuttl/tests/basic-deploy/00-deps.yaml new file mode 100644 index 00000000..1f725683 --- /dev/null +++ b/tests/kuttl/tests/basic-deploy/00-deps.yaml @@ -0,0 +1,7 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: | + if ! [[ `oc get crd openstackdataplanenodesets.dataplane.openstack.org` ]]; then + oc apply -f ../../deps/dataplane.openstack.org_openstackdataplanenodesets.yaml + fi diff --git a/tests/kuttl/tests/basic-deploy_tls/00-deps.yaml b/tests/kuttl/tests/basic-deploy_tls/00-deps.yaml new file mode 100644 index 00000000..1f725683 --- /dev/null +++ b/tests/kuttl/tests/basic-deploy_tls/00-deps.yaml @@ -0,0 +1,7 @@ +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - script: | + if ! [[ `oc get crd openstackdataplanenodesets.dataplane.openstack.org` ]]; then + oc apply -f ../../deps/dataplane.openstack.org_openstackdataplanenodesets.yaml + fi From e262ad00c035c8d6656770b888edcd219ff0825e Mon Sep 17 00:00:00 2001 From: Christian Schwede Date: Fri, 9 Feb 2024 11:01:52 +0100 Subject: [PATCH 3/3] Add Dataplane Swift disks to rings Retrieves a list of DataplaneNodesets and checks if these are deploying the "swift" service. If yes, use defined disks to include them in the list of devices for the Swift rings. --- api/go.mod | 2 +- api/go.sum | 9 ++--- api/v1beta1/swiftring_types.go | 9 +++++ api/v1beta1/zz_generated.deepcopy.go | 15 +++++++++ config/rbac/role.yaml | 8 +++++ controllers/swiftring_controller.go | 2 ++ go.mod | 7 +++- go.sum | 19 +++++++---- main.go | 2 ++ pkg/swiftring/const.go | 4 ++- pkg/swiftring/funcs.go | 49 ++++++++++++++++++++++++++++ 11 files changed, 109 insertions(+), 17 deletions(-) diff --git a/api/go.mod b/api/go.mod index 493f25ba..26fcf507 100644 --- a/api/go.mod +++ b/api/go.mod @@ -31,7 +31,7 @@ require ( github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect + github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3 // indirect github.com/google/uuid v1.6.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/josharian/intern v1.0.0 // indirect diff --git a/api/go.sum b/api/go.sum index 745550d5..94b3f6a8 100644 --- a/api/go.sum +++ b/api/go.sum @@ -2,9 +2,6 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -44,11 +41,10 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3 h1:2XF1Vzq06X+inNqgJ9tRnGuw+ZVCB3FazXODD6JE1R8= +github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -126,7 +122,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/api/v1beta1/swiftring_types.go b/api/v1beta1/swiftring_types.go index a33510a4..34760abd 100644 --- a/api/v1beta1/swiftring_types.go +++ b/api/v1beta1/swiftring_types.go @@ -94,6 +94,15 @@ type SwiftRingList struct { Items []SwiftRing `json:"items"` } + +type SwiftDisk struct { + Device string `json:"device"` + Path string `json:"path"` + Weight int32 `json:"weight"` + Region int32 `json:"region"` + Zone int32 `json:"zone"` +} + func init() { SchemeBuilder.Register(&SwiftRing{}, &SwiftRingList{}) } diff --git a/api/v1beta1/zz_generated.deepcopy.go b/api/v1beta1/zz_generated.deepcopy.go index 916e5ca8..aebae7db 100644 --- a/api/v1beta1/zz_generated.deepcopy.go +++ b/api/v1beta1/zz_generated.deepcopy.go @@ -106,6 +106,21 @@ func (in *SwiftDefaults) DeepCopy() *SwiftDefaults { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SwiftDisk) DeepCopyInto(out *SwiftDisk) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SwiftDisk. +func (in *SwiftDisk) DeepCopy() *SwiftDisk { + if in == nil { + return nil + } + out := new(SwiftDisk) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SwiftList) DeepCopyInto(out *SwiftList) { *out = *in diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index d19b8f23..eddab010 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -119,6 +119,14 @@ rules: - patch - update - watch +- apiGroups: + - dataplane.openstack.org + resources: + - openstackdataplanenodesets + verbs: + - get + - list + - watch - apiGroups: - k8s.cni.cncf.io resources: diff --git a/controllers/swiftring_controller.go b/controllers/swiftring_controller.go index 447c5b03..96caafba 100644 --- a/controllers/swiftring_controller.go +++ b/controllers/swiftring_controller.go @@ -35,6 +35,7 @@ import ( "github.com/openstack-k8s-operators/lib-common/modules/common/helper" "github.com/openstack-k8s-operators/lib-common/modules/common/job" + dataplanev1 "github.com/openstack-k8s-operators/dataplane-operator/api/v1beta1" swiftv1beta1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1" "github.com/openstack-k8s-operators/swift-operator/pkg/swift" "github.com/openstack-k8s-operators/swift-operator/pkg/swiftring" @@ -285,5 +286,6 @@ func (r *SwiftRingReconciler) SetupWithManager(mgr ctrl.Manager) error { Owns(&rbacv1.ClusterRole{}). Owns(&rbacv1.ClusterRoleBinding{}). Watches(&swiftv1beta1.SwiftStorage{}, handler.EnqueueRequestsFromMapFunc(swiftRingFilter)). + Watches(&dataplanev1.OpenStackDataPlaneNodeSet{}, handler.EnqueueRequestsFromMapFunc(swiftRingFilter)). Complete(r) } diff --git a/go.mod b/go.mod index 5af9d9dd..2b0adebc 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.4.0 github.com/onsi/ginkgo/v2 v2.15.0 github.com/onsi/gomega v1.31.1 + github.com/openstack-k8s-operators/dataplane-operator/api v0.3.1-0.20240219024506-c76c45e69237 github.com/openstack-k8s-operators/infra-operator/apis v0.3.1-0.20240218132212-ad757a2f5bab github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240216173228-eec429bcc776 github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240216173409-86913e6d5885 @@ -36,18 +37,22 @@ require ( github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect + github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gophercloud/gophercloud v1.9.0 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/metal3-io/baremetal-operator/apis v0.5.0 // indirect + github.com/metal3-io/baremetal-operator/pkg/hardwareutils v0.4.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/openshift/api v3.9.0+incompatible // indirect github.com/openstack-k8s-operators/lib-common/modules/openstack v0.3.1-0.20240216173409-86913e6d5885 // indirect + github.com/openstack-k8s-operators/lib-common/modules/storage v0.3.1-0.20240216173409-86913e6d5885 // indirect + github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.3.1-0.20240218185734-5d372a0fd380 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.18.0 // indirect github.com/prometheus/client_model v0.5.0 // indirect diff --git a/go.sum b/go.sum index 872bdb45..8958563f 100644 --- a/go.sum +++ b/go.sum @@ -2,9 +2,6 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -44,13 +41,12 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3 h1:2XF1Vzq06X+inNqgJ9tRnGuw+ZVCB3FazXODD6JE1R8= +github.com/google/pprof v0.0.0-20230510103437-eeec1cb781c3/go.mod h1:79YE0hCXdHag9sBkw2o+N/YnZtTkXi0UT9Nnixa5eYk= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gophercloud/gophercloud v1.9.0 h1:zKvmHOmHuaZlnx9d2DJpEgbMxrGt/+CJ/bKOKQh9Xzo= github.com/gophercloud/gophercloud v1.9.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -65,6 +61,10 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/metal3-io/baremetal-operator/apis v0.5.0 h1:IRaKMxRCkYfFAjvZdDyGC6bIaGQsV6MMNmGV8gqyYCc= +github.com/metal3-io/baremetal-operator/apis v0.5.0/go.mod h1:rjpH/E7MB7JWt/LPi6hDd5LpaBIiqaBnm3KtFjKxnUM= +github.com/metal3-io/baremetal-operator/pkg/hardwareutils v0.4.0 h1:AnA8XLLp3RKYjjlB4KI0fyPSDN/d5gb3ZtM2cVyxwOc= +github.com/metal3-io/baremetal-operator/pkg/hardwareutils v0.4.0/go.mod h1:399nvdaqoU9rTI25UdFw2EWcVjmJPpeZPIhfDAIx/XU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -78,6 +78,8 @@ github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo= github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0= github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7 h1:rncLxJBpFGqBztyxCMwNRnMjhhIDOWHJowi6q8G6koI= github.com/openshift/api v0.0.0-20230414143018-3367bc7e6ac7/go.mod h1:ctXNyWanKEjGj8sss1KjjHQ3ENKFm33FFnS5BKaIPh4= +github.com/openstack-k8s-operators/dataplane-operator/api v0.3.1-0.20240219024506-c76c45e69237 h1:CBcDpN4bSG+qmssnMKYFnXqLCdAFnmVHeLRHQlo/HeY= +github.com/openstack-k8s-operators/dataplane-operator/api v0.3.1-0.20240219024506-c76c45e69237/go.mod h1:1M1q8AhjgB9P/Jxr4WodQxwv+C5AsVh9O6ZZlWiSEe4= github.com/openstack-k8s-operators/infra-operator/apis v0.3.1-0.20240218132212-ad757a2f5bab h1:zdI202C0TtXz5UPB+uTdxZtIaFseEDV0HtQ/MmX6hQU= github.com/openstack-k8s-operators/infra-operator/apis v0.3.1-0.20240218132212-ad757a2f5bab/go.mod h1:FGKwlmAIgTsvvz2+uusWqNYFKHNAm4uzVyKao+emeu0= github.com/openstack-k8s-operators/keystone-operator/api v0.3.1-0.20240216173228-eec429bcc776 h1:piRji0b//DM3h2KNXxphlIYTGeRw03QhfQ/+0JS5eVY= @@ -86,6 +88,10 @@ github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.2024021617 github.com/openstack-k8s-operators/lib-common/modules/common v0.3.1-0.20240216173409-86913e6d5885/go.mod h1:bQwzyQtWCR9F0+IvWZ30J9d1lB6tcX3CNJ0Ten1smDw= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.3.1-0.20240216173409-86913e6d5885 h1:g3wUugrt+GsQMtWdxQDzFXjY13U/FKLx1dVMMMJhQqA= github.com/openstack-k8s-operators/lib-common/modules/openstack v0.3.1-0.20240216173409-86913e6d5885/go.mod h1:8QsCFttAm+X6A8I8EQThGjNjeMAYt2hK7ivbvnR3434= +github.com/openstack-k8s-operators/lib-common/modules/storage v0.3.1-0.20240216173409-86913e6d5885 h1:sMO+IYsZ91Nho0FV6y03J0NTGd8+ZWB4KmKJJU94gTU= +github.com/openstack-k8s-operators/lib-common/modules/storage v0.3.1-0.20240216173409-86913e6d5885/go.mod h1:sK82mkh2UzITsbNa/y6AKTZftHQnsYigqRx+rFbfZM4= +github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.3.1-0.20240218185734-5d372a0fd380 h1:P6VpvKvGMy++Pwe/+4T0etjINGkMcUClTiReF3Ph9NU= +github.com/openstack-k8s-operators/openstack-baremetal-operator/api v0.3.1-0.20240218185734-5d372a0fd380/go.mod h1:BrNj++cLEqEJIw2p7SGGrFiuNXjiCDo7FKH0oB+qcMA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -140,7 +146,6 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/main.go b/main.go index e01058d9..d897ba49 100644 --- a/main.go +++ b/main.go @@ -43,6 +43,7 @@ import ( "github.com/openstack-k8s-operators/lib-common/modules/common/util" networkv1 "github.com/k8snetworkplumbingwg/network-attachment-definition-client/pkg/apis/k8s.cni.cncf.io/v1" + dataplanev1 "github.com/openstack-k8s-operators/dataplane-operator/api/v1beta1" memcachedv1 "github.com/openstack-k8s-operators/infra-operator/apis/memcached/v1beta1" infranetworkv1 "github.com/openstack-k8s-operators/infra-operator/apis/network/v1beta1" swiftv1beta1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1" @@ -62,6 +63,7 @@ func init() { utilruntime.Must(memcachedv1.AddToScheme(scheme)) utilruntime.Must(networkv1.AddToScheme(scheme)) utilruntime.Must(infranetworkv1.AddToScheme(scheme)) + utilruntime.Must(dataplanev1.AddToScheme(scheme)) //+kubebuilder:scaffold:scheme } diff --git a/pkg/swiftring/const.go b/pkg/swiftring/const.go index bb975902..6755a540 100644 --- a/pkg/swiftring/const.go +++ b/pkg/swiftring/const.go @@ -17,5 +17,7 @@ package swiftring const ( // ComponentName - - ComponentName = "swift-ring" + ComponentName = "swift-ring" + DataplaneDisks = "edpm_swift_disks" + DataplaneDomain = "storage.example.com" ) diff --git a/pkg/swiftring/funcs.go b/pkg/swiftring/funcs.go index 99c3b665..b9b200f3 100644 --- a/pkg/swiftring/funcs.go +++ b/pkg/swiftring/funcs.go @@ -17,7 +17,9 @@ package swiftring import ( "context" + "encoding/json" "fmt" + "path/filepath" "sort" "strings" @@ -31,11 +33,13 @@ import ( "github.com/openstack-k8s-operators/lib-common/modules/common/helper" "github.com/openstack-k8s-operators/lib-common/modules/common/util" + dataplanev1 "github.com/openstack-k8s-operators/dataplane-operator/api/v1beta1" swiftv1beta1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1" "github.com/openstack-k8s-operators/swift-operator/pkg/swift" ) //+kubebuilder:rbac:groups=core,resources=persistentvolumeclaims,verbs=get;list;watch +//+kubebuilder:rbac:groups=dataplane.openstack.org,resources=openstackdataplanenodesets,verbs=get;list;watch func DeviceList(ctx context.Context, h *helper.Helper, instance *swiftv1beta1.SwiftRing) (string, string, error) { // Returns a list of devices as CSV @@ -68,6 +72,51 @@ func DeviceList(ctx context.Context, h *helper.Helper, instance *swiftv1beta1.Sw } } + // Get all OpenStackDataPlaneNodeSets that deploy the Swift service and + // their used Swift disks + nodeSets := &dataplanev1.OpenStackDataPlaneNodeSetList{} + err = h.GetClient().List(context.Background(), nodeSets, listOpts...) + if err != nil && !errors.IsNotFound(err) { + return "", "", err + } + for _, nodeSet := range nodeSets.Items { + for _, service := range nodeSet.Spec.Services { + if service == "swift" { + // Get the global disk vars first that are used for all + // nodes if not set otherwise per-node + globalDisks := make(map[string]swiftv1beta1.SwiftDisk) + if edpmSwiftDisks, found := nodeSet.Spec.NodeTemplate.Ansible.AnsibleVars[DataplaneDisks]; found { + var swiftDisks []swiftv1beta1.SwiftDisk + if err := json.Unmarshal(edpmSwiftDisks, &swiftDisks); err == nil { + for _, disk := range swiftDisks { + globalDisks[disk.Path] = disk + } + } + } + + for _, node := range nodeSet.Spec.Nodes { + hostName := fmt.Sprintf("%s.%s", node.HostName, DataplaneDomain) + hostDisks := make(map[string]swiftv1beta1.SwiftDisk) + for k, v := range globalDisks { + hostDisks[k] = v + } + // These overwrite the global vars if set + if edpmSwiftDisks, found := node.Ansible.AnsibleVars[DataplaneDisks]; found { + var swiftDisks []swiftv1beta1.SwiftDisk + if err := json.Unmarshal(edpmSwiftDisks, &swiftDisks); err == nil { + for _, disk := range swiftDisks { + hostDisks[disk.Path] = disk + } + } + } + for _, disk := range hostDisks { + devices = append(devices, fmt.Sprintf("%d,%d,%s,%s,%d\n", disk.Region, disk.Zone, hostName, filepath.Base(disk.Path), disk.Weight)) + } + } + } + } + } + // Device list must be sorted to ensure hash does not change sort.Strings(devices)