diff --git a/.github/workflows/build-openstack-operator.yaml b/.github/workflows/build-openstack-operator.yaml index c6fcf0f3c..4a3547af0 100644 --- a/.github/workflows/build-openstack-operator.yaml +++ b/.github/workflows/build-openstack-operator.yaml @@ -18,7 +18,6 @@ jobs: go_version: 1.21.x operator_sdk_version: 1.31.0 bundle_dockerfile: ./bundle.Dockerfile - catalog_extra_bundles_script: ./hack/pin-bundle-images.sh secrets: IMAGENAMESPACE: ${{ secrets.IMAGENAMESPACE }} QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 01b4ed01a..cc719c4dd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -25,6 +25,12 @@ repos: entry: make args: ['operator-lint'] pass_filenames: false + - id: make-bindata + name: make-bindata + language: system + entry: make + args: ['bindata'] + pass_filenames: false - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 @@ -41,6 +47,7 @@ repos: - id: destroyed-symlinks - id: check-yaml args: [-m] + exclude: '^bindata/operator|^config/operator' - id: check-json - id: detect-private-key - id: end-of-file-fixer diff --git a/Dockerfile b/Dockerfile index 15f279e9b..368c1615e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -26,8 +26,10 @@ RUN if [ ! -f $CACHITO_ENV_FILE ]; then go mod download ; fi # Build manager RUN if [ -f $CACHITO_ENV_FILE ] ; then source $CACHITO_ENV_FILE ; fi ; env ${GO_BUILD_EXTRA_ENV_ARGS} go build ${GO_BUILD_EXTRA_ARGS} -a -o ${DEST_ROOT}/manager main.go +RUN if [ -f $CACHITO_ENV_FILE ] ; then source $CACHITO_ENV_FILE ; fi ; env ${GO_BUILD_EXTRA_ENV_ARGS} go build ${GO_BUILD_EXTRA_ARGS} -a -o ${DEST_ROOT}/operator cmd/operator/main.go RUN cp -r config/services ${DEST_ROOT}/services +RUN cp -r bindata ${DEST_ROOT}/bindata # Use distroless as minimal base image to package the manager binary # Refer to https://github.com/GoogleContainerTools/distroless for more details @@ -65,9 +67,11 @@ WORKDIR / # Install operator binary to WORKDIR COPY --from=builder ${DEST_ROOT}/manager . +COPY --from=builder ${DEST_ROOT}/operator . # Install services COPY --from=builder ${DEST_ROOT}/services ${OPERATOR_SERVICES} +COPY --from=builder ${DEST_ROOT}/bindata /bindata USER $USER_ID diff --git a/Makefile b/Makefile index 213964fb7..ab30777a3 100644 --- a/Makefile +++ b/Makefile @@ -129,15 +129,30 @@ help: ## Display this help. ##@ Development +# (dprince) FIXME: controller-gen crd didn't seem to like multiple paths so I didn't split it. So we can continue using kubebuilder +# I did split out the rbac for both binaries so we can use separate roles .PHONY: manifests manifests: controller-gen ## Generate WebhookConfiguration, ClusterRole and CustomResourceDefinition objects. - $(CONTROLLER_GEN) rbac:roleName=manager-role crd$(CRDDESC_OVERRIDE) webhook paths="./..." output:crd:artifacts:config=config/crd/bases && \ + mkdir -p config/operator/rbac && \ + $(CONTROLLER_GEN) crd$(CRDDESC_OVERRIDE) output:crd:artifacts:config=config/crd/bases webhook paths="./..." && \ + $(CONTROLLER_GEN) rbac:roleName=manager-role paths="{./apis/client/...,./apis/core/...,./apis/dataplane/...,./controllers/client/...,./controllers/core/...,./controllers/dataplane/...,./pkg/...}" output:dir=config/rbac && \ + $(CONTROLLER_GEN) rbac:roleName=operator-role paths="./controllers/operator/..." paths="./apis/operator/..." output:dir=config/operator/rbac && \ rm -f apis/bases/* && cp -a config/crd/bases apis/ .PHONY: generate generate: controller-gen ## Generate code containing DeepCopy, DeepCopyInto, and DeepCopyObject method implementations. $(CONTROLLER_GEN) object:headerFile="hack/boilerplate.go.txt" paths="./..." +.PHONY: bindata +bindata: ## Build docker image with the manager. + mkdir -p bindata/crds bindata/rbac bindata/operator + $(KUSTOMIZE) build config/crd > bindata/crds/crds.yaml + $(KUSTOMIZE) build config/default > bindata/operator/operator.yaml + cp config/operator/managers.yaml bindata/operator/ + cp config/operator/rabbit.yaml bindata/operator/ + $(KUSTOMIZE) build config/rbac > bindata/rbac/rbac.yaml + /bin/bash hack/sync-bindata.sh + .PHONY: fmt fmt: ## Run go fmt against code. go fmt ./... @@ -205,8 +220,17 @@ run: manifests generate fmt vet ## Run a controller from your host. source hack/export_related_images.sh && \ go run ./main.go -metrics-bind-address ":$(METRICS_PORT)" -health-probe-bind-address ":$(HEALTH_PORT)" +.PHONY: run-operator +run-operator: export METRICS_PORT?=8080 +run-operator: export HEALTH_PORT?=8081 +run-operator: export ENABLE_WEBHOOKS?=false +run-operator: export BASE_BINDATA?=bindata +run-operator: manifests generate fmt vet ## Run a controller from your host. + source hack/export_operator_related_images.sh && \ + go run ./cmd/operator/main.go -metrics-bind-address ":$(METRICS_PORT)" -health-probe-bind-address ":$(HEALTH_PORT)" + .PHONY: docker-build -docker-build: ## Build docker image with the manager. +docker-build: ## Build docker image with the manager. podman build -t ${IMG} . ${DOCKER_BUILD_ARGS} .PHONY: docker-push @@ -271,7 +295,7 @@ GINKGO_TESTS ?= ./tests/... ./apis/client/... ./apis/core/... ./apis/dataplane/. KUTTL ?= $(LOCALBIN)/kubectl-kuttl ## Tool Versions -KUSTOMIZE_VERSION ?= v3.8.7 +KUSTOMIZE_VERSION ?= v5.5.0 #(dprince: bumped to aquire new features like --load-restrictor) CONTROLLER_TOOLS_VERSION ?= v0.11.1 CRD_MARKDOWN_VERSION ?= v0.0.3 KUTTL_VERSION ?= 0.17.0 @@ -339,9 +363,9 @@ endif .PHONY: bundle bundle: build manifests kustomize operator-sdk ## Generate bundle manifests and metadata, then validate generated files. $(OPERATOR_SDK) generate kustomize manifests -q - cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG) - $(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle $(BUNDLE_GEN_FLAGS) - cp dependencies.yaml ./bundle/metadata + cd config/operator/deployment/ && $(KUSTOMIZE) edit set image controller=$(IMG) + $(KUSTOMIZE) build config/operator --load-restrictor='LoadRestrictionsNone' | $(OPERATOR_SDK) generate bundle $(BUNDLE_GEN_FLAGS) + #cp dependencies.yaml ./bundle/metadata $(OPERATOR_SDK) bundle validate ./bundle .PHONY: bundle-build diff --git a/apis/bases/operator.openstack.org_openstacks.yaml b/apis/bases/operator.openstack.org_openstacks.yaml index 18cf475dc..cd4bc2838 100644 --- a/apis/bases/operator.openstack.org_openstacks.yaml +++ b/apis/bases/operator.openstack.org_openstacks.yaml @@ -15,7 +15,15 @@ spec: singular: openstack scope: Namespaced versions: - - name: v1beta1 + - additionalPrinterColumns: + - jsonPath: .status.deployedOperatorCount + name: Deployed Operator Count + type: integer + - description: Status + jsonPath: .status.conditions[0].status + name: Status + type: string + name: v1beta1 schema: openAPIV3Schema: properties: @@ -26,11 +34,36 @@ spec: metadata: type: object spec: - properties: - foo: - type: string type: object status: + properties: + 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 + deployedOperatorCount: + type: integer + observedGeneration: + format: int64 + type: integer type: object type: object served: true diff --git a/apis/operator/v1beta1/conditions.go b/apis/operator/v1beta1/conditions.go new file mode 100644 index 000000000..0019582da --- /dev/null +++ b/apis/operator/v1beta1/conditions.go @@ -0,0 +1,46 @@ +/* + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" +) + +// OpenStack Condition Types used by API objects. +const ( + // OpenStackOperatorReadyCondition Status=True condition which indicates if operators have been deployed + OpenStackOperatorReadyCondition condition.Type = "OpenStackOperatorReadyCondition" +) + +// Common Messages used by Openstack operator +const ( + // + // OpenStackOperator condition messages + // + + // OpenStackOperatorErrorMessage + OpenStackOperatorErrorMessage = "OpenStackOperator error occured %s" + + // OpenStackOperatorReadyInitMessage + OpenStackOperatorReadyInitMessage = "OpenStackOperator not started" + + // OpenStackOperatorReadyRunningMessage + OpenStackOperatorReadyRunningMessage = "OpenStackOperator in progress" + + // OpenStackOperatorReadyMessage + OpenStackOperatorReadyMessage = "OpenStackOperator completed" + +) diff --git a/apis/operator/v1beta1/openstack_types.go b/apis/operator/v1beta1/openstack_types.go index 7459ad7ae..9d9a0860a 100644 --- a/apis/operator/v1beta1/openstack_types.go +++ b/apis/operator/v1beta1/openstack_types.go @@ -17,30 +17,32 @@ limitations under the License. package v1beta1 import ( + condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! -// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. - // OpenStackSpec defines the desired state of OpenStack type OpenStackSpec struct { - // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster - // Important: Run "make" to regenerate code after modifying this file - - // Foo is an example field of OpenStack. Edit openstack_types.go to remove/update - Foo string `json:"foo,omitempty"` } // OpenStackStatus defines the observed state of OpenStack type OpenStackStatus struct { - // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster - // Important: Run "make" to regenerate code after modifying this file -} -//+kubebuilder:object:root=true -//+kubebuilder:subresource:status + // +operator-sdk:csv:customresourcedefinitions:type=status,xDescriptors={"urn:alm:descriptor:io.kubernetes.conditions"} + // Conditions + Conditions condition.Conditions `json:"conditions,omitempty" optional:"true"` + + // DeployedOperatorCount - the number of operators deployed + DeployedOperatorCount *int `json:"deployedOperatorCount,omitempty"` + + // ObservedGeneration - the most recent generation observed for this object. + ObservedGeneration int64 `json:"observedGeneration,omitempty"` // no spec yet so maybe we don't need this +} +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Deployed Operator Count",type=integer,JSONPath=`.status.deployedOperatorCount` +// +kubebuilder:printcolumn:name="Status",type="string",JSONPath=".status.conditions[0].status",description="Status" // OpenStack is the Schema for the openstacks API type OpenStack struct { metav1.TypeMeta `json:",inline"` diff --git a/apis/operator/v1beta1/zz_generated.deepcopy.go b/apis/operator/v1beta1/zz_generated.deepcopy.go index 6357b41e4..8ea973b19 100644 --- a/apis/operator/v1beta1/zz_generated.deepcopy.go +++ b/apis/operator/v1beta1/zz_generated.deepcopy.go @@ -22,6 +22,7 @@ limitations under the License. package v1beta1 import ( + "github.com/openstack-k8s-operators/lib-common/modules/common/condition" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -31,7 +32,7 @@ func (in *OpenStack) DeepCopyInto(out *OpenStack) { out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) out.Spec = in.Spec - out.Status = in.Status + in.Status.DeepCopyInto(&out.Status) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStack. @@ -102,6 +103,18 @@ func (in *OpenStackSpec) DeepCopy() *OpenStackSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OpenStackStatus) DeepCopyInto(out *OpenStackStatus) { *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(condition.Conditions, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.DeployedOperatorCount != nil { + in, out := &in.DeployedOperatorCount, &out.DeployedOperatorCount + *out = new(int) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OpenStackStatus. diff --git a/cmd/operator/main.go b/cmd/operator/main.go index 52c80d04a..e10af1893 100644 --- a/cmd/operator/main.go +++ b/cmd/operator/main.go @@ -44,7 +44,6 @@ import ( operatorv1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/operator/v1beta1" operatorcontrollers "github.com/openstack-k8s-operators/openstack-operator/controllers/operator" - // +kubebuilder:scaffold:imports ) var ( @@ -55,7 +54,6 @@ var ( func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) utilruntime.Must(operatorv1beta1.AddToScheme(scheme)) - // +kubebuilder:scaffold:scheme } func main() { @@ -96,7 +94,7 @@ func main() { }, HealthProbeBindAddress: probeAddr, LeaderElection: enableLeaderElection, - LeaderElectionID: "40ba705e.openstack.org", + LeaderElectionID: "20ca801f.openstack.org", WebhookServer: webhook.NewServer( webhook.Options{ Port: 9443, @@ -147,7 +145,8 @@ func main() { setupLog.Error(err, "unable to create controller", "controller", "OpenStack") os.Exit(1) } - // +kubebuilder:scaffold:builder + operatorcontrollers.SetupEnv() + if err := mgr.AddHealthzCheck("healthz", checker); err != nil { setupLog.Error(err, "unable to set up health check") os.Exit(1) diff --git a/config/crd/bases/operator.openstack.org_openstacks.yaml b/config/crd/bases/operator.openstack.org_openstacks.yaml index 18cf475dc..cd4bc2838 100644 --- a/config/crd/bases/operator.openstack.org_openstacks.yaml +++ b/config/crd/bases/operator.openstack.org_openstacks.yaml @@ -15,7 +15,15 @@ spec: singular: openstack scope: Namespaced versions: - - name: v1beta1 + - additionalPrinterColumns: + - jsonPath: .status.deployedOperatorCount + name: Deployed Operator Count + type: integer + - description: Status + jsonPath: .status.conditions[0].status + name: Status + type: string + name: v1beta1 schema: openAPIV3Schema: properties: @@ -26,11 +34,36 @@ spec: metadata: type: object spec: - properties: - foo: - type: string type: object status: + properties: + 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 + deployedOperatorCount: + type: integer + observedGeneration: + format: int64 + type: integer type: object type: object served: true diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index a6b9db9f0..a55279ade 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -8,7 +8,7 @@ resources: - bases/dataplane.openstack.org_openstackdataplanenodesets.yaml - bases/dataplane.openstack.org_openstackdataplaneservices.yaml - bases/dataplane.openstack.org_openstackdataplanedeployments.yaml -- bases/operator.openstack.org_openstacks.yaml +#- bases/operator.openstack.org_openstacks.yaml #+kubebuilder:scaffold:crdkustomizeresource patchesStrategicMerge: @@ -22,7 +22,7 @@ patchesStrategicMerge: # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. # patches here are for enabling the CA injection for each CRD -- patches/cainjection_in_core_openstackcontrolplanes.yaml +#- patches/cainjection_in_core_openstackcontrolplanes.yaml #- patches/cainjection_in_openstackclients.yaml #- patches/cainjection_in_openstackversions.yaml #- patches/cainjection_in_openstacks.yaml diff --git a/config/default/kustomization.yaml b/config/default/kustomization.yaml index ff3b2d7e4..1b9631f48 100644 --- a/config/default/kustomization.yaml +++ b/config/default/kustomization.yaml @@ -1,5 +1,5 @@ # Adds namespace to all resources. -namespace: openstack-operator-system +namespace: '{{ .OperatorNamespace }}' # Value of this field is prepended to the # names of all resources, e.g. a deployment named @@ -12,9 +12,9 @@ namePrefix: openstack-operator- #commonLabels: # someName: someValue -bases: -- ../crd -- ../rbac +resources: +#- ../crd +#- ../rbac - ../manager # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in # crd/kustomization.yaml @@ -49,29 +49,29 @@ patchesStrategicMerge: # the following config is for teaching kustomize how to do var substitution vars: # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER' prefix. -#- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR -# objref: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -# fieldref: -# fieldpath: metadata.namespace -#- name: CERTIFICATE_NAME -# objref: -# kind: Certificate -# group: cert-manager.io -# version: v1 -# name: serving-cert # this name should match the one in certificate.yaml -#- name: SERVICE_NAMESPACE # namespace of the service -# objref: -# kind: Service -# version: v1 -# name: webhook-service -# fieldref: -# fieldpath: metadata.namespace -#- name: SERVICE_NAME -# objref: -# kind: Service -# version: v1 -# name: webhook-service +- name: CERTIFICATE_NAMESPACE # namespace of the certificate CR + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: serving-cert # this name should match the one in certificate.yaml + fieldref: + fieldpath: metadata.namespace +- name: CERTIFICATE_NAME + objref: + kind: Certificate + group: cert-manager.io + version: v1 + name: serving-cert # this name should match the one in certificate.yaml +- name: SERVICE_NAMESPACE # namespace of the service + objref: + kind: Service + version: v1 + name: webhook-service + fieldref: + fieldpath: metadata.namespace +- name: SERVICE_NAME + objref: + kind: Service + version: v1 + name: webhook-service diff --git a/config/default/webhookcainjection_patch.yaml b/config/default/webhookcainjection_patch.yaml index 81e80999d..6596b12de 100644 --- a/config/default/webhookcainjection_patch.yaml +++ b/config/default/webhookcainjection_patch.yaml @@ -14,3 +14,17 @@ metadata: name: validating-webhook-configuration annotations: cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + labels: + app.kubernetes.io/name: mutatingingwebhookconfiguration + app.kubernetes.io/instance: mutating-webhook-configuration + app.kubernetes.io/component: webhook + app.kubernetes.io/created-by: openstack-operator + app.kubernetes.io/part-of: openstack-operator + app.kubernetes.io/managed-by: kustomize + name: mutating-webhook-configuration + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) diff --git a/config/manager/manager.yaml b/config/manager/manager.yaml index b5f05ac15..a16168a60 100644 --- a/config/manager/manager.yaml +++ b/config/manager/manager.yaml @@ -73,5 +73,5 @@ spec: requests: cpu: 10m memory: 128Mi - serviceAccountName: controller-manager + serviceAccountName: openstack-operator-controller-manager terminationGracePeriodSeconds: 10 diff --git a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml index f44cee10a..6597332e6 100644 --- a/config/manifests/bases/openstack-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/openstack-operator.clusterserviceversion.yaml @@ -606,6 +606,17 @@ spec: x-descriptors: - urn:alm:descriptor:io.kubernetes.conditions version: v1beta1 + - description: OpenStack is the Schema for the openstacks API + displayName: Open Stack + kind: OpenStack + name: openstacks.operator.openstack.org + statusDescriptors: + - description: Conditions + displayName: Conditions + path: conditions + x-descriptors: + - urn:alm:descriptor:io.kubernetes.conditions + version: v1beta1 - description: OpenStackVersion is the Schema for the openstackversionupdates API displayName: OpenStack Version diff --git a/config/operator/delete_crd.yaml b/config/operator/delete_crd.yaml new file mode 100644 index 000000000..a7299553b --- /dev/null +++ b/config/operator/delete_crd.yaml @@ -0,0 +1,35 @@ +$patch: delete +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: openstackcontrolplanes.core.openstack.org +--- +$patch: delete +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: openstackversions.core.openstack.org +--- +$patch: delete +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: openstackclients.client.openstack.org +--- +$patch: delete +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: openstackdataplanenodesets.dataplane.openstack.org +--- +$patch: delete +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: openstackdataplaneservices.dataplane.openstack.org +--- +$patch: delete +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: openstackdataplanedeployments.dataplane.openstack.org diff --git a/config/operator/deployment/controller_operator_config.yaml b/config/operator/deployment/controller_operator_config.yaml new file mode 100644 index 000000000..c4e68c29d --- /dev/null +++ b/config/operator/deployment/controller_operator_config.yaml @@ -0,0 +1,11 @@ +apiVersion: controller-runtime.sigs.k8s.io/v1alpha1 +kind: ControllerManagerConfig +health: + healthProbeBindAddress: :8081 +metrics: + bindAddress: 127.0.0.1:8080 +webhook: + port: 9443 +leaderElection: + leaderElect: true + resourceName: 20ca801f.openstack.org diff --git a/config/operator/deployment/deployment.yaml b/config/operator/deployment/deployment.yaml new file mode 100644 index 000000000..a7e04bb66 --- /dev/null +++ b/config/operator/deployment/deployment.yaml @@ -0,0 +1,79 @@ +apiVersion: v1 +kind: Namespace +metadata: + labels: + control-plane: controller-operator + openstack.org/operator-name: openstack + name: system +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-operator + namespace: system + labels: + control-plane: controller-operator + openstack.org/operator-name: openstack +spec: + selector: + matchLabels: + openstack.org/operator-name: openstack + replicas: 1 + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: operator + labels: + control-plane: controller-operator + openstack.org/operator-name: openstack + spec: + securityContext: + runAsNonRoot: true + # TODO(user): For common cases that do not require escalating privileges + # it is recommended to ensure that all your Pods/Containers are restrictive. + # More info: https://kubernetes.io/docs/concepts/security/pod-security-standards/#restricted + # Please uncomment the following code if your project does NOT have to work on old Kubernetes + # versions < 1.19 or on vendors versions which do NOT support this field by default (i.e. Openshift < 4.11 ). + # seccompProfile: + # type: RuntimeDefault + containers: + - command: + - /operator + args: + - --leader-elect + env: + - name: ENABLE_WEBHOOKS + value: false + - name: OPENSTACK_RELEASE_VERSION + value: 0.0.1 + image: controller:latest + name: operator + securityContext: + allowPrivilegeEscalation: false + # TODO(user): uncomment for common cases that do not require escalating privileges + # capabilities: + # drop: + # - "ALL" + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + # TODO(user): Configure the resources accordingly based on the project requirements. + # More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ + resources: + limits: + cpu: 500m + memory: 256Mi + requests: + cpu: 10m + memory: 128Mi + serviceAccountName: controller-operator + terminationGracePeriodSeconds: 10 diff --git a/config/operator/deployment/kustomization.yaml b/config/operator/deployment/kustomization.yaml new file mode 100644 index 000000000..6ca4c7dc7 --- /dev/null +++ b/config/operator/deployment/kustomization.yaml @@ -0,0 +1,16 @@ +resources: +- deployment.yaml + +generatorOptions: + disableNameSuffixHash: true + +configMapGenerator: +- files: + - controller_operator_config.yaml + name: operator-config +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +images: +- name: controller + newName: quay.io/openstack-k8s-operators/openstack-operator + newTag: latest diff --git a/config/operator/kustomization.yaml b/config/operator/kustomization.yaml new file mode 100644 index 000000000..437691031 --- /dev/null +++ b/config/operator/kustomization.yaml @@ -0,0 +1,16 @@ +resources: +- ../crd/bases/operator.openstack.org_openstacks.yaml + +bases: +#- ../crd/ +- manifests +- rbac +- deployment +- ../certmanager/ +- ../samples/ + +patchesStrategicMerge: +#- delete_crd.yaml + +# Injects our custom images (ENV variable settings) +- manager_operator_images.yaml diff --git a/config/operator/manager_operator_images.yaml b/config/operator/manager_operator_images.yaml new file mode 100644 index 000000000..ded483abb --- /dev/null +++ b/config/operator/manager_operator_images.yaml @@ -0,0 +1,57 @@ +# NOTE: this file is automatically generated by hack/sync-bindata.sh! +# +# This patch inject custom ENV settings to the manager container +# Used to set our operator locations +apiVersion: apps/v1 +kind: Deployment +metadata: + name: controller-operator + namespace: system +spec: + template: + spec: + containers: + - name: operator + env: + - name: RELATED_IMAGE_BARBICAN_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/barbican-operator@sha256:f6c85e80f70b7b7334d74fe6d9f86a9b2a5006566db9a6024d0f8966c80167cf + - name: RELATED_IMAGE_CINDER_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/cinder-operator@sha256:23972d5bc7d91b5ce22a12d7d7f8cba5c68c8eade0bf7c0d27c1cb5be7168468 + - name: RELATED_IMAGE_DESIGNATE_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/designate-operator@sha256:98b7d7960bdfceec9b682fb48401b332a360eb2047d3e745553c81a9c3c8e1fd + - name: RELATED_IMAGE_GLANCE_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/glance-operator@sha256:9838dad960de475da993d98b8d5d543ee8f0030efc9f47b4a534ab90cc098556 + - name: RELATED_IMAGE_HEAT_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/heat-operator@sha256:59fdb9653bd85003cadd7a05161a665bda2ecb77a464bf30fc73064fd13519a5 + - name: RELATED_IMAGE_HORIZON_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/horizon-operator@sha256:6eabb8c57ce9de3d1ba9f4748bd36c5bbd36c8acb223375211b95ac9904e4e2a + - name: RELATED_IMAGE_INFRA_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/infra-operator@sha256:a7f2d7883d811d2dea6bbb20f215def498afbb0c428508b54ca2792a86d68bdd + - name: RELATED_IMAGE_IRONIC_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/ironic-operator@sha256:c26aee3592941c2ea62834d0a03f471d95ef777ae339b26bc5115a384aa48b3a + - name: RELATED_IMAGE_KEYSTONE_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/keystone-operator@sha256:d8c3c098edcb972bcee5b944f8182113951d3435aabf5794c02ff39da1d36bba + - name: RELATED_IMAGE_MANILA_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/manila-operator@sha256:07fb8c80d9648b5c1f2f0c47855542861374c214b9df9df27906b736ccfa79fc + - name: RELATED_IMAGE_MARIADB_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/mariadb-operator@sha256:4e539d5414535f03c274051013b304339741e19f797632a39861ba2309b3518a + - name: RELATED_IMAGE_NEUTRON_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/neutron-operator@sha256:bf373ff7eb87a3b587b10ef6b2b276ff8d5c5166772f3c09233e735d6ac308f5 + - name: RELATED_IMAGE_NOVA_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/nova-operator@sha256:468f90dcdbc174cc789dde192493bb170fa18f688c8af5a97c2a81000e7bb6bd + - name: RELATED_IMAGE_OCTAVIA_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/octavia-operator@sha256:b376450aa86e083e2a9b93b4af6b6efd6978451187990d5d21ac967e5ef0ef8c + - name: RELATED_IMAGE_OPENSTACK_BAREMETAL_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/openstack-baremetal-operator@sha256:fd552ef3c74923dc69f7fc5ce44f1a5de91bb8e85839f0c4b48387f769e79820 + - name: RELATED_IMAGE_OVN_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/ovn-operator@sha256:b900bb87fef70e4c6eded20fc4be5a595cfe3d4b3ebacc88af7dff2af29991a5 + - name: RELATED_IMAGE_PLACEMENT_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/placement-operator@sha256:70f80e0f966c61504a6d64dd3d2937ef7d7b17a65e9c1c9501a13abfb535a5b7 + - name: RELATED_IMAGE_RABBITMQ_CLUSTER_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/rabbitmq-cluster-operator@sha256:225524223bf2a7f3a4ce95958fc9ca6fdab02745fb70374e8ff5bf1ddaceda4b + - name: RELATED_IMAGE_SWIFT_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/swift-operator@sha256:0c7b99f5d18487c3a3c834fd099fd32a9fbd595a8bfb0dc401390088dbe07662 + - name: RELATED_IMAGE_TELEMETRY_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/telemetry-operator@sha256:b18442d853a996d3cdde52944815c722861e7ea2ae87a75c6396b606ee571e1d + - name: RELATED_IMAGE_TEST_OPERATOR_MANAGER_IMAGE_URL + value: quay.io/openstack-k8s-operators/test-operator@sha256:1840e87b584328ad53cde0635d28550d2f75a27995b8bc2c9419bd2083614b04 diff --git a/config/operator/managers.yaml b/config/operator/managers.yaml new file mode 100644 index 000000000..d416bfd3f --- /dev/null +++ b/config/operator/managers.yaml @@ -0,0 +1,82 @@ +{{ $namespace := .OperatorNamespace }} +{{ range $operatorName, $operatorImage := .OperatorImages }} +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + control-plane: controller-manager + openstack.org/operator-name: {{ $operatorName }} + name: {{ $operatorName }}-operator-controller-manager + namespace: {{ $namespace }} +spec: + replicas: 1 + selector: + matchLabels: + openstack.org/operator-name: {{ $operatorName }} + template: + metadata: + annotations: + kubectl.kubernetes.io/default-container: manager + labels: + control-plane: controller-manager + openstack.org/operator-name: {{ $operatorName }} + spec: + containers: + - args: + - --health-probe-bind-address=:8081 + - --metrics-bind-address=127.0.0.1:8080 + - --leader-elect + command: + - /manager + env: + - name: ENABLE_WEBHOOKS + value: 'false' + image: {{ $operatorImage }} + livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 + name: manager + readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + limits: + cpu: 500m + memory: 256Mi + requests: + cpu: 10m + memory: 128Mi + securityContext: + allowPrivilegeEscalation: false + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=0 + image: gcr.io/kubebuilder/kube-rbac-proxy:v0.13.0 + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + protocol: TCP + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 5m + memory: 64Mi + securityContext: + allowPrivilegeEscalation: false + securityContext: + runAsNonRoot: true + serviceAccountName: {{ $operatorName }}-operator-controller-manager + terminationGracePeriodSeconds: 10 +--- +{{ end }} diff --git a/config/operator/manifests/bases/openstack-operator.clusterserviceversion.yaml b/config/operator/manifests/bases/openstack-operator.clusterserviceversion.yaml new file mode 100644 index 000000000..81e91c8df --- /dev/null +++ b/config/operator/manifests/bases/openstack-operator.clusterserviceversion.yaml @@ -0,0 +1,56 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + alm-examples: '[]' + capabilities: Seamless Upgrades + features.operators.openshift.io/disconnected: "true" + features.operators.openshift.io/fips-compliant: "true" + features.operators.openshift.io/proxy-aware: "false" + features.operators.openshift.io/tls-profiles: "false" + features.operators.openshift.io/token-auth-aws: "false" + features.operators.openshift.io/token-auth-azure: "false" + features.operators.openshift.io/token-auth-gcp: "false" + operatorframework.io/suggested-namespace: openstack-operators + operatorframework.io/initialization-resource: '{"apiVersion":"operator.openstack.org/v1beta1","kind":"OpenStack","metadata":{"name":"openstack","namespace":"openstack-operators"},"spec":{}}' + operators.operatorframework.io/builder: operator-sdk-v1.31.0 + operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 + name: openstack-operator.v0.0.0 + namespace: placeholder +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: + - description: OpenStack is the Schema for the openstacks API + displayName: Open Stack + kind: OpenStack + name: openstacks.operator.openstack.org + version: v1beta1 + description: Install and configure OpenStack + displayName: OpenStack + icon: + - base64data: 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 + mediatype: image/png + install: + spec: + deployments: null + strategy: "" + installModes: + - supported: false + type: OwnNamespace + - supported: false + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: true + type: AllNamespaces + keywords: + - OpenStack + links: + - name: Openstack Operator + url: https://github.com/openstack-k8s-operators/ + maturity: alpha + provider: + name: Red Hat Inc. + url: https://redhat.com/ + version: 0.1.0 diff --git a/config/operator/manifests/kustomization.yaml b/config/operator/manifests/kustomization.yaml new file mode 100644 index 000000000..3e6f72b56 --- /dev/null +++ b/config/operator/manifests/kustomization.yaml @@ -0,0 +1,24 @@ +# These resources constitute the fully configured set of manifests +# used to generate the 'manifests/' directory in a bundle. +resources: +- bases/openstack-operator.clusterserviceversion.yaml + +# [WEBHOOK] To enable webhooks, uncomment all the sections with [WEBHOOK] prefix. +# Do NOT uncomment sections with prefix [CERTMANAGER], as OLM does not support cert-manager. +# These patches remove the unnecessary "cert" volume and its manager container volumeMount. +#patchesJson6902: +#- target: +# group: apps +# version: v1 +# kind: Deployment +# name: controller-manager +# namespace: system +# patch: |- +# # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs. +# # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment. +# - op: remove +# path: /spec/template/spec/containers/1/volumeMounts/0 +# # Remove the "cert" volume, since OLM will create and mount a set of certs. +# # Update the indices in this path if adding or removing volumes in the manager's Deployment. +# - op: remove +# path: /spec/template/spec/volumes/0 diff --git a/config/operator/rabbit.yaml b/config/operator/rabbit.yaml new file mode 100644 index 000000000..f79da0e6c --- /dev/null +++ b/config/operator/rabbit.yaml @@ -0,0 +1,44 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/name: rabbitmq-cluster-operator + app.kubernetes.io/part-of: rabbitmq + name: rabbitmq-cluster-operator-manager + namespace: {{ .OperatorNamespace }} +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: rabbitmq-cluster-operator + template: + metadata: + labels: + app.kubernetes.io/component: rabbitmq-operator + app.kubernetes.io/name: rabbitmq-cluster-operator + app.kubernetes.io/part-of: rabbitmq + spec: + containers: + - command: + - /manager + env: + - name: OPERATOR_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + image: {{ .RabbitmqImage }} + name: operator + ports: + - containerPort: 9782 + name: metrics + protocol: TCP + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 5m + memory: 64Mi + serviceAccountName: rabbitmq-cluster-operator-controller-manager + terminationGracePeriodSeconds: 10 diff --git a/config/operator/rbac/auth_proxy_client_clusterrole.yaml b/config/operator/rbac/auth_proxy_client_clusterrole.yaml new file mode 100644 index 000000000..4c35b21a7 --- /dev/null +++ b/config/operator/rbac/auth_proxy_client_clusterrole.yaml @@ -0,0 +1,9 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: metrics-reader-operator +rules: +- nonResourceURLs: + - "/metrics" + verbs: + - get diff --git a/config/operator/rbac/auth_proxy_role.yaml b/config/operator/rbac/auth_proxy_role.yaml new file mode 100644 index 000000000..cfbb8a4b5 --- /dev/null +++ b/config/operator/rbac/auth_proxy_role.yaml @@ -0,0 +1,17 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: proxy-role-operator +rules: +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create diff --git a/config/operator/rbac/auth_proxy_role_binding.yaml b/config/operator/rbac/auth_proxy_role_binding.yaml new file mode 100644 index 000000000..440225c75 --- /dev/null +++ b/config/operator/rbac/auth_proxy_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: proxy-rolebinding-operator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: proxy-role-operator +subjects: +- kind: ServiceAccount + name: controller-operator + namespace: system diff --git a/config/operator/rbac/auth_proxy_service.yaml b/config/operator/rbac/auth_proxy_service.yaml new file mode 100644 index 000000000..36e384520 --- /dev/null +++ b/config/operator/rbac/auth_proxy_service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + control-plane: controller-operator + name: controller-operator-metrics-service-operator + namespace: system +spec: + ports: + - name: https + port: 8443 + protocol: TCP + targetPort: https + selector: + openstack.org/operator-name: openstack-operator diff --git a/config/operator/rbac/kustomization.yaml b/config/operator/rbac/kustomization.yaml new file mode 100644 index 000000000..731832a6a --- /dev/null +++ b/config/operator/rbac/kustomization.yaml @@ -0,0 +1,18 @@ +resources: +# All RBAC will be applied under this service account in +# the deployment namespace. You may comment out this resource +# if your manager will use a service account that exists at +# runtime. Be sure to update RoleBinding and ClusterRoleBinding +# subjects if changing service account names. +- service_account.yaml +- role.yaml +- role_binding.yaml +- leader_election_role.yaml +- leader_election_role_binding.yaml +# Comment the following 4 lines if you want to disable +# the auth proxy (https://github.com/brancz/kube-rbac-proxy) +# which protects your /metrics endpoint. +- auth_proxy_service.yaml +- auth_proxy_role.yaml +- auth_proxy_role_binding.yaml +- auth_proxy_client_clusterrole.yaml diff --git a/config/operator/rbac/leader_election_role.yaml b/config/operator/rbac/leader_election_role.yaml new file mode 100644 index 000000000..78acf677e --- /dev/null +++ b/config/operator/rbac/leader_election_role.yaml @@ -0,0 +1,37 @@ +# permissions to do leader election. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: leader-election-role-operator +rules: +- apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - "" + resources: + - events + verbs: + - create + - patch diff --git a/config/operator/rbac/leader_election_role_binding.yaml b/config/operator/rbac/leader_election_role_binding.yaml new file mode 100644 index 000000000..80e2f271c --- /dev/null +++ b/config/operator/rbac/leader_election_role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: leader-election-rolebinding-operator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: leader-election-role-operator +subjects: +- kind: ServiceAccount + name: controller-operator + namespace: system diff --git a/config/operator/rbac/role.yaml b/config/operator/rbac/role.yaml new file mode 100644 index 000000000..d865d0b51 --- /dev/null +++ b/config/operator/rbac/role.yaml @@ -0,0 +1,115 @@ +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: operator-role +rules: +- apiGroups: + - "" + resources: + - configmaps + - namespaces + - serviceaccounts + verbs: + - '*' +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - '*' +- apiGroups: + - apiextensions.k8s.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - cert-manager.io + resources: + - certificates + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - cert-manager.io + resources: + - issuers + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - services + verbs: + - '*' +- apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - create + - get + - list + - update + - watch +- apiGroups: + - operator.openstack.org + resources: + - openstacks + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - operator.openstack.org + resources: + - openstacks/finalizers + verbs: + - update +- apiGroups: + - operator.openstack.org + resources: + - openstacks/status + verbs: + - get + - patch + - update +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterrolebindings + - clusterroles + - rolebindings + - roles + verbs: + - '*' diff --git a/config/operator/rbac/role_binding.yaml b/config/operator/rbac/role_binding.yaml new file mode 100644 index 000000000..edc1eb232 --- /dev/null +++ b/config/operator/rbac/role_binding.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: operator-rolebinding +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: operator-role +subjects: +- kind: ServiceAccount + name: controller-operator + namespace: system diff --git a/config/operator/rbac/service_account.yaml b/config/operator/rbac/service_account.yaml new file mode 100644 index 000000000..72275ca0d --- /dev/null +++ b/config/operator/rbac/service_account.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: controller-operator + namespace: system diff --git a/config/rbac/kustomization.yaml b/config/rbac/kustomization.yaml index 731832a6a..e9c4ef55f 100644 --- a/config/rbac/kustomization.yaml +++ b/config/rbac/kustomization.yaml @@ -1,3 +1,13 @@ +# Adds namespace to all resources. +namespace: '{{ .OperatorNamespace }}' + +# Value of this field is prepended to the +# names of all resources, e.g. a deployment named +# "wordpress" becomes "alices-wordpress". +# Note that it should also match with the prefix (text before '-') of the namespace +# field above. +namePrefix: openstack-operator- + resources: # All RBAC will be applied under this service account in # the deployment namespace. You may comment out this resource diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 479bdd51f..4a072bbcc 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -662,32 +662,6 @@ rules: verbs: - get - list -- apiGroups: - - operator.openstack.org - resources: - - openstacks - verbs: - - create - - delete - - get - - list - - patch - - update - - watch -- apiGroups: - - operator.openstack.org - resources: - - openstacks/finalizers - verbs: - - update -- apiGroups: - - operator.openstack.org - resources: - - openstacks/status - verbs: - - get - - patch - - update - apiGroups: - ovn.openstack.org resources: diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index 1dc0a3b7a..138d15b6b 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -3,11 +3,11 @@ # we do not have space for long examples here and want # to guide users to documentation instead resources: -- core_v1beta1_openstackcontrolplane_empty.yaml -- client_v1beta1_openstackclient_empty.yaml -- core_v1beta1_openstackversion_empty.yaml -- dataplane_v1beta1_openstackdataplanenodeset_empty.yaml -- dataplane_v1beta1_openstackdataplaneservice_empty.yaml -- dataplane_v1beta1_openstackdataplanedeployment_empty.yaml +#- core_v1beta1_openstackcontrolplane_empty.yaml +#- client_v1beta1_openstackclient_empty.yaml +#- core_v1beta1_openstackversion_empty.yaml +#- dataplane_v1beta1_openstackdataplanenodeset_empty.yaml +#- dataplane_v1beta1_openstackdataplaneservice_empty.yaml +#- dataplane_v1beta1_openstackdataplanedeployment_empty.yaml - operator_v1beta1_openstack.yaml #+kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/samples/operator_v1beta1_openstack.yaml b/config/samples/operator_v1beta1_openstack.yaml index 4eaf5baa0..3ed688957 100644 --- a/config/samples/operator_v1beta1_openstack.yaml +++ b/config/samples/operator_v1beta1_openstack.yaml @@ -3,10 +3,8 @@ kind: OpenStack metadata: labels: app.kubernetes.io/name: openstack - app.kubernetes.io/instance: openstack-sample + app.kubernetes.io/instance: openstack app.kubernetes.io/part-of: openstack-operator app.kubernetes.io/managed-by: kustomize app.kubernetes.io/created-by: openstack-operator - name: openstack-sample -spec: - # TODO(user): Add fields here + name: openstack diff --git a/controllers/operator/openstack_controller.go b/controllers/operator/openstack_controller.go index 8cb6cbd7c..c1ab48305 100644 --- a/controllers/operator/openstack_controller.go +++ b/controllers/operator/openstack_controller.go @@ -1,5 +1,5 @@ /* -Copyright 2022. +Copyright 2024. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -18,14 +18,35 @@ package operator import ( "context" + "fmt" + "os" + "path/filepath" + "sort" + "strings" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + "github.com/go-logr/logr" + condition "github.com/openstack-k8s-operators/lib-common/modules/common/condition" + "github.com/openstack-k8s-operators/lib-common/modules/common/helper" + "github.com/openstack-k8s-operators/lib-common/modules/common/util" operatorv1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/operator/v1beta1" + "github.com/openstack-k8s-operators/openstack-operator/pkg/operator/bindata" + "github.com/pkg/errors" + appsv1 "k8s.io/api/apps/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/log" +) + +const ( + OperatorCount = 22 // like wow! ) // OpenStackReconciler reconciles a OpenStack object @@ -35,30 +56,344 @@ type OpenStackReconciler struct { Kclient kubernetes.Interface } +// GetLog returns a logger object with a prefix of "controller.name" and aditional controller context fields +func (r *OpenStackReconciler) GetLogger(ctx context.Context) logr.Logger { + return log.FromContext(ctx).WithName("Controllers").WithName("OpenStackControlPlane") +} + +var ( + envRelatedOperatorImages (map[string]*string) // operatorName -> image + rabbitmqImage string +) + +// SetupEnv - +func SetupEnv() { + envRelatedOperatorImages = make(map[string]*string) + for _, name := range os.Environ() { + envArr := strings.Split(name, "=") + + if strings.HasSuffix(envArr[0], "_OPERATOR_MANAGER_IMAGE_URL") { + operatorName := strings.TrimPrefix(envArr[0], "RELATED_IMAGE_") + operatorName = strings.TrimSuffix(operatorName, "_OPERATOR_MANAGER_IMAGE_URL") + operatorName = strings.ToLower(operatorName) + operatorName = strings.ReplaceAll(operatorName, "_", "-") + // rabbitmq-cluster is a special case with an alternate deployment template + if operatorName == "rabbitmq-cluster" { + rabbitmqImage = envArr[1] + } else { + envRelatedOperatorImages[operatorName] = &envArr[1] + } + log.Log.Info("Found operator related image", "operator", operatorName, "image", envArr[1]) + } + } +} + //+kubebuilder:rbac:groups=operator.openstack.org,resources=openstacks,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=operator.openstack.org,resources=openstacks/status,verbs=get;update;patch //+kubebuilder:rbac:groups=operator.openstack.org,resources=openstacks/finalizers,verbs=update +// +kubebuilder:rbac:groups=admissionregistration.k8s.io,resources=mutatingwebhookconfigurations;validatingwebhookconfigurations,verbs="*" +// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterroles;clusterrolebindings;rolebindings;roles,verbs="*" +// +kubebuilder:rbac:groups=apiextensions.k8s.io,resources="*",verbs="*" +// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete; +// +kubebuilder:rbac:groups="",resources=serviceaccounts;configmaps;namespaces,verbs="*" +// +kubebuilder:rbac:groups=core,resources=services,verbs="*"; +// +kubebuilder:rbac:groups=cert-manager.io,resources=issuers,verbs=get;list;watch;create;update;patch;delete; +// +kubebuilder:rbac:groups=cert-manager.io,resources=certificates,verbs=get;list;watch;create;update;patch;delete; +// +kubebuilder:rbac:groups="monitoring.coreos.com",resources=servicemonitors,verbs=list;get;watch;update;create // Reconcile is part of the main kubernetes reconciliation loop which aims to // move the current state of the cluster closer to the desired state. -// TODO(user): Modify the Reconcile function to compare the state specified by -// the OpenStack object against the actual cluster state, and then -// perform operations to make the cluster state reflect the state specified by -// the user. // // For more details, check Reconcile and its Result here: // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.14.1/pkg/reconcile -func (r *OpenStackReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) +func (r *OpenStackReconciler) Reconcile(ctx context.Context, req ctrl.Request) (result ctrl.Result, _err error) { + Log := r.GetLogger(ctx) + + // Fetch the OpenStack instance + instanceList := &operatorv1beta1.OpenStackList{} + err := r.Client.List(ctx, instanceList, &client.ListOptions{}) + if err != nil { + return ctrl.Result{}, errors.Wrap(err, "failed listing all OpenStack instances") + } + instance := &operatorv1beta1.OpenStack{} + err = r.Client.Get(ctx, req.NamespacedName, instance) + if err != nil { + if apierrors.IsNotFound(err) { + // Request object not found, could have been deleted after reconcile req. + // Owned objects are automatically garbage collected. For additional cleanup logic use finalizers. + // Return and don't requeue + return ctrl.Result{}, nil + } + // Error reading the object - requeue the req. + return ctrl.Result{}, err + } + + versionHelper, err := helper.NewHelper( + instance, + r.Client, + r.Kclient, + r.Scheme, + Log, + ) + if err != nil { + Log.Error(err, "unable to create helper") + return ctrl.Result{}, err + } - // TODO(user): your logic here + isNewInstance := instance.Status.Conditions == nil + if isNewInstance { + instance.Status.Conditions = condition.Conditions{} + } + // Save a copy of the condtions so that we can restore the LastTransitionTime + // when a condition's state doesn't change. + savedConditions := instance.Status.Conditions.DeepCopy() + + // Always patch the instance status when exiting this function so we can persist any changes. + defer func() { + // update the Ready condition based on the sub conditions + if instance.Status.Conditions.AllSubConditionIsTrue() { + instance.Status.Conditions.MarkTrue( + condition.ReadyCondition, condition.ReadyMessage) + } else { + // something is not ready so reset the Ready condition + instance.Status.Conditions.MarkUnknown( + condition.ReadyCondition, condition.InitReason, condition.ReadyInitMessage) + // and recalculate it based on the state of the rest of the conditions + instance.Status.Conditions.Set( + instance.Status.Conditions.Mirror(condition.ReadyCondition)) + } + + condition.RestoreLastTransitionTimes( + &instance.Status.Conditions, savedConditions) + + err := versionHelper.PatchInstance(ctx, instance) + if err != nil { + _err = err + return + } + }() + + cl := condition.CreateList( + condition.UnknownCondition(operatorv1beta1.OpenStackOperatorReadyCondition, condition.InitReason, string(operatorv1beta1.OpenStackOperatorReadyInitMessage)), + ) + instance.Status.Conditions.Init(&cl) + instance.Status.ObservedGeneration = instance.Generation + + instance.Status.Conditions.Set(condition.FalseCondition( + operatorv1beta1.OpenStackOperatorReadyCondition, + condition.RequestedReason, + condition.SeverityInfo, + operatorv1beta1.OpenStackOperatorReadyRunningMessage)) + + // We only want one instance of OpenStack. Ignore anything after that. + if len(instanceList.Items) > 0 { + if len(instanceList.Items) > 1 { + sort.Slice(instanceList.Items, func(i, j int) bool { + return instanceList.Items[j].CreationTimestamp.After(instanceList.Items[i].CreationTimestamp.Time) + }) + } + if instanceList.Items[0].Name != req.Name { + Log.Info("Ignoring OpenStack.operator.openstack.org because one already exists and does not match existing name") + err = r.Client.Delete(ctx, instance, &client.DeleteOptions{}) + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + operatorv1beta1.OpenStackOperatorReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + operatorv1beta1.OpenStackOperatorErrorMessage, + err)) + Log.Error(err, "failed to remove OpenStack.operator.openstack.org instance") + } + return ctrl.Result{}, nil + } + } + + // TODO: cleanup obsolete resources here (remove old CSVs, etc) + /* + if err := r.cleanupObsoleteResources(ctx); err != nil { + return ctrl.Result{}, err + } + */ + + if err := r.applyManifests(ctx, instance); err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + operatorv1beta1.OpenStackOperatorReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + operatorv1beta1.OpenStackOperatorErrorMessage, + err)) + return ctrl.Result{}, err + } + + // Check if all deployments are running + deploymentsRunning, err := r.countDeployments(ctx, instance) + instance.Status.DeployedOperatorCount = &deploymentsRunning + if err != nil { + instance.Status.Conditions.Set(condition.FalseCondition( + operatorv1beta1.OpenStackOperatorReadyCondition, + condition.ErrorReason, + condition.SeverityWarning, + operatorv1beta1.OpenStackOperatorErrorMessage, + err)) + return ctrl.Result{}, err + } + if deploymentsRunning < OperatorCount { + Log.Info("Waiting for all deployments to be running", "current", deploymentsRunning, "expected", OperatorCount) + return ctrl.Result{}, nil + } + + instance.Status.Conditions.MarkTrue( + operatorv1beta1.OpenStackOperatorReadyCondition, + operatorv1beta1.OpenStackOperatorReadyMessage) + + Log.Info("Reconcile complete.") return ctrl.Result{}, nil + +} + +// countDeployments - +func (r *OpenStackReconciler) countDeployments(ctx context.Context, instance *operatorv1beta1.OpenStack) (int, error) { + deployments := &appsv1.DeploymentList{} + err := r.Client.List(ctx, deployments, &client.ListOptions{Namespace: instance.Namespace}) + if err != nil { + return 0, err + } + + count := 0 + for _, deployment := range deployments.Items { + if metav1.IsControlledBy(&deployment, instance) { + if deployment.Status.ReadyReplicas > 0 { + count++ + } + } + } + return count, nil +} + +func (r *OpenStackReconciler) applyManifests(ctx context.Context, instance *operatorv1beta1.OpenStack) error { + if err := r.applyCRDs(ctx, instance); err != nil { + log.Log.Error(err, "failed applying CRD manifests") + return err + } + + if err := r.applyRBAC(ctx, instance); err != nil { + log.Log.Error(err, "failed applying RBAC manifests") + return err + } + + if err := r.applyOperator(ctx, instance); err != nil { + log.Log.Error(err, "failed applying Operator manifests") + return err + } + + return nil +} + +func (r *OpenStackReconciler) applyCRDs(ctx context.Context, instance *operatorv1beta1.OpenStack) error { + data := bindata.MakeRenderData() + return r.renderAndApply(ctx, instance, data, "crds", false) +} + +func (r *OpenStackReconciler) applyRBAC(ctx context.Context, instance *operatorv1beta1.OpenStack) error { + data := bindata.MakeRenderData() + data.Data["OperatorNamespace"] = instance.Namespace + return r.renderAndApply(ctx, instance, data, "rbac", false) +} + +func (r *OpenStackReconciler) applyOperator(ctx context.Context, instance *operatorv1beta1.OpenStack) error { + data := bindata.MakeRenderData() + data.Data["OperatorNamespace"] = instance.Namespace + data.Data["OperatorImages"] = envRelatedOperatorImages + data.Data["RabbitmqImage"] = rabbitmqImage + return r.renderAndApply(ctx, instance, data, "operator", true) +} + +func (r *OpenStackReconciler) renderAndApply( + ctx context.Context, + instance *operatorv1beta1.OpenStack, + data bindata.RenderData, + sourceDirectory string, + setControllerReference bool, +) error { + var err error + + bindir := util.GetEnvVar("BASE_BINDATA", "/bindata") + + sourceFullDirectory := filepath.Join(bindir, sourceDirectory) + objs, err := bindata.RenderDir(sourceFullDirectory, &data) + if err != nil { + return errors.Wrapf(err, "failed to render openstack-operator - %s", sourceDirectory) + } + + // If no file found in directory - return error + if len(objs) == 0 { + return fmt.Errorf("no manifests rendered from %s", sourceFullDirectory) + } + + for _, obj := range objs { + // RenderDir seems to add an extra null entry to the list. It appears to be because of the + // nested templates. This just makes sure we don't try to apply an empty obj. + if obj.GetName() == "" { + continue + } + if setControllerReference { + // Set the controller reference. When the CR is removed, it will remove the CRDs as well + if obj.GetNamespace() != "" { + log.Log.Info("Setting controller reference", "object", obj.GetName(), "controller", instance.Name) + err = controllerutil.SetControllerReference(instance, obj, r.Scheme) + if err != nil { + return errors.Wrap(err, "failed to set owner reference") + } + } else { + log.Log.Info("skipping controller reference (cluster scoped)", "object", obj.GetName(), "controller", instance.Name) + } + } + + // Now apply the object + err = bindata.ApplyObject(ctx, r.Client, obj) + if err != nil { + return errors.Wrapf(err, "failed to apply object %v", obj) + } + } + return nil } // SetupWithManager sets up the controller with the Manager. func (r *OpenStackReconciler) SetupWithManager(mgr ctrl.Manager) error { + + deploymentFunc := handler.EnqueueRequestsFromMapFunc(func(ctx context.Context, o client.Object) []reconcile.Request { + Log := r.GetLogger(ctx) + + instanceList := &operatorv1beta1.OpenStackList{} + err := r.Client.List(ctx, instanceList) + if err != nil { + Log.Error(err, "Unable to retrieve OpenStack instances") + return nil + } + + if len(instanceList.Items) == 0 { + return nil + } + + instance := &instanceList.Items[0] + if metav1.IsControlledBy(o, instance) { + Log.Info("Reconcile request for OpenStack instance", "instance", instance.Name) + return []reconcile.Request{ + { + NamespacedName: client.ObjectKey{ + Namespace: instance.Namespace, + Name: instance.Name, + }, + }, + } + } + + return nil + }) + return ctrl.NewControllerManagedBy(mgr). + Watches(&appsv1.Deployment{}, deploymentFunc). For(&operatorv1beta1.OpenStack{}). Complete(r) } diff --git a/controllers/operator/suite_test.go b/controllers/operator/suite_test.go deleted file mode 100644 index 5cef7a757..000000000 --- a/controllers/operator/suite_test.go +++ /dev/null @@ -1,80 +0,0 @@ -/* -Copyright 2022. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package operator - -import ( - "path/filepath" - "testing" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "k8s.io/client-go/kubernetes/scheme" - "k8s.io/client-go/rest" - "sigs.k8s.io/controller-runtime/pkg/client" - "sigs.k8s.io/controller-runtime/pkg/envtest" - logf "sigs.k8s.io/controller-runtime/pkg/log" - "sigs.k8s.io/controller-runtime/pkg/log/zap" - - operatorv1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/operator/v1beta1" - //+kubebuilder:scaffold:imports -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -var cfg *rest.Config -var k8sClient client.Client -var testEnv *envtest.Environment - -func TestAPIs(t *testing.T) { - RegisterFailHandler(Fail) - - RunSpecs(t, "Controller Suite") -} - -var _ = BeforeSuite(func() { - logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true))) - - By("bootstrapping test environment") - testEnv = &envtest.Environment{ - CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")}, - ErrorIfCRDPathMissing: true, - } - - var err error - // cfg is defined in this file globally. - cfg, err = testEnv.Start() - Expect(err).NotTo(HaveOccurred()) - Expect(cfg).NotTo(BeNil()) - - err = operatorv1beta1.AddToScheme(scheme.Scheme) - Expect(err).NotTo(HaveOccurred()) - - //+kubebuilder:scaffold:scheme - - k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) - Expect(err).NotTo(HaveOccurred()) - Expect(k8sClient).NotTo(BeNil()) - -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - err := testEnv.Stop() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/dependencies.yaml b/dependencies.yaml index d0b38a66e..4b16a5eec 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -1,81 +1,13 @@ dependencies: - type: olm.package value: - packageName: rabbitmq-cluster-operator + packageName: openshift-cert-manager-operator version: ">=0.0.0" - type: olm.package value: - packageName: barbican-operator + packageName: metallb-operator version: ">=0.0.0" - type: olm.package value: - packageName: cinder-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: glance-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: horizon-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: heat-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: infra-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: ironic-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: keystone-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: manila-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: mariadb-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: neutron-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: nova-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: openstack-baremetal-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: ovn-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: placement-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: swift-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: telemetry-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: octavia-operator - version: ">=0.0.0" - - type: olm.package - value: - packageName: designate-operator + packageName: cluster-observability-operator version: ">=0.0.0" diff --git a/go.mod b/go.mod index 22fa1b3da..e4c5e9f70 100644 --- a/go.mod +++ b/go.mod @@ -39,6 +39,7 @@ require ( github.com/openstack-k8s-operators/swift-operator/api v0.5.1-0.20241114094619-107d1aac9458 github.com/openstack-k8s-operators/telemetry-operator/api v0.5.1-0.20241111235825-227a5c47eff2 github.com/openstack-k8s-operators/test-operator/api v0.5.1-0.20241114145659-bda006a5385d + github.com/pkg/errors v0.9.1 github.com/rabbitmq/cluster-operator/v2 v2.11.0 go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 @@ -84,7 +85,6 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/openstack-k8s-operators/lib-common/modules/openstack v0.5.1-0.20241104140916-71a0e9d9766d // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.19.0 // indirect github.com/prometheus/client_model v0.6.0 // indirect github.com/prometheus/common v0.53.0 // indirect diff --git a/hack/export_operator_related_images.sh b/hack/export_operator_related_images.sh new file mode 100644 index 000000000..4a9eb1eba --- /dev/null +++ b/hack/export_operator_related_images.sh @@ -0,0 +1,23 @@ +# NOTE: this file is automatically generated by hack/sync-bindata.sh! + +export RELATED_IMAGE_BARBICAN_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/barbican-operator@sha256:f6c85e80f70b7b7334d74fe6d9f86a9b2a5006566db9a6024d0f8966c80167cf +export RELATED_IMAGE_CINDER_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/cinder-operator@sha256:23972d5bc7d91b5ce22a12d7d7f8cba5c68c8eade0bf7c0d27c1cb5be7168468 +export RELATED_IMAGE_DESIGNATE_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/designate-operator@sha256:98b7d7960bdfceec9b682fb48401b332a360eb2047d3e745553c81a9c3c8e1fd +export RELATED_IMAGE_GLANCE_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/glance-operator@sha256:9838dad960de475da993d98b8d5d543ee8f0030efc9f47b4a534ab90cc098556 +export RELATED_IMAGE_HEAT_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/heat-operator@sha256:59fdb9653bd85003cadd7a05161a665bda2ecb77a464bf30fc73064fd13519a5 +export RELATED_IMAGE_HORIZON_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/horizon-operator@sha256:6eabb8c57ce9de3d1ba9f4748bd36c5bbd36c8acb223375211b95ac9904e4e2a +export RELATED_IMAGE_INFRA_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/infra-operator@sha256:a7f2d7883d811d2dea6bbb20f215def498afbb0c428508b54ca2792a86d68bdd +export RELATED_IMAGE_IRONIC_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/ironic-operator@sha256:c26aee3592941c2ea62834d0a03f471d95ef777ae339b26bc5115a384aa48b3a +export RELATED_IMAGE_KEYSTONE_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/keystone-operator@sha256:d8c3c098edcb972bcee5b944f8182113951d3435aabf5794c02ff39da1d36bba +export RELATED_IMAGE_MANILA_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/manila-operator@sha256:07fb8c80d9648b5c1f2f0c47855542861374c214b9df9df27906b736ccfa79fc +export RELATED_IMAGE_MARIADB_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/mariadb-operator@sha256:4e539d5414535f03c274051013b304339741e19f797632a39861ba2309b3518a +export RELATED_IMAGE_NEUTRON_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/neutron-operator@sha256:bf373ff7eb87a3b587b10ef6b2b276ff8d5c5166772f3c09233e735d6ac308f5 +export RELATED_IMAGE_NOVA_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/nova-operator@sha256:468f90dcdbc174cc789dde192493bb170fa18f688c8af5a97c2a81000e7bb6bd +export RELATED_IMAGE_OCTAVIA_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/octavia-operator@sha256:b376450aa86e083e2a9b93b4af6b6efd6978451187990d5d21ac967e5ef0ef8c +export RELATED_IMAGE_OPENSTACK_BAREMETAL_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/openstack-baremetal-operator@sha256:fd552ef3c74923dc69f7fc5ce44f1a5de91bb8e85839f0c4b48387f769e79820 +export RELATED_IMAGE_OVN_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/ovn-operator@sha256:b900bb87fef70e4c6eded20fc4be5a595cfe3d4b3ebacc88af7dff2af29991a5 +export RELATED_IMAGE_PLACEMENT_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/placement-operator@sha256:70f80e0f966c61504a6d64dd3d2937ef7d7b17a65e9c1c9501a13abfb535a5b7 +export RELATED_IMAGE_RABBITMQ_CLUSTER_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/rabbitmq-cluster-operator@sha256:225524223bf2a7f3a4ce95958fc9ca6fdab02745fb70374e8ff5bf1ddaceda4b +export RELATED_IMAGE_SWIFT_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/swift-operator@sha256:0c7b99f5d18487c3a3c834fd099fd32a9fbd595a8bfb0dc401390088dbe07662 +export RELATED_IMAGE_TELEMETRY_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/telemetry-operator@sha256:b18442d853a996d3cdde52944815c722861e7ea2ae87a75c6396b606ee571e1d +export RELATED_IMAGE_TEST_OPERATOR_MANAGER_IMAGE_URL=quay.io/openstack-k8s-operators/test-operator@sha256:1840e87b584328ad53cde0635d28550d2f75a27995b8bc2c9419bd2083614b04 diff --git a/hack/sync-bindata.sh b/hack/sync-bindata.sh new file mode 100755 index 000000000..fc128c84f --- /dev/null +++ b/hack/sync-bindata.sh @@ -0,0 +1,174 @@ +#!/bin/bash + +# extract select data from bundles: +# -CSV's +# -TODO: role data +set -ex + +function extract_bundle { + local IN_DIR=$1 + local OUT_DIR=$2 + for X in $(file ${IN_DIR}/* | grep gzip | cut -f 1 -d ':'); do + tar xvf $X -C ${OUT_DIR}/; + done +} + +OUT_DATA=bindata +EXTRACT_DIR=tmp/bindata + +mkdir -p "$EXTRACT_DIR" +mkdir -p "$OUT_DATA/crds" + +for BUNDLE in $(hack/pin-bundle-images.sh | tr "," " "); do + skopeo copy "docker://$BUNDLE" dir:${EXTRACT_DIR}/tmp; + extract_bundle "${EXTRACT_DIR}/tmp" "${OUT_DATA}/" +done + +cd "$OUT_DATA" +# copy CRDS into crds basedir +grep -l CustomResourceDefinition manifests/* | xargs -I % sh -c 'cp % ./crds/' + +# extract role, clusterRole, and deployment from CSV's +for X in $(ls manifests/*clusterserviceversion.yaml); do + echo $OPERATOR_NAME + OPERATOR_NAME=$(echo $X | sed -e "s|manifests\/\([^\.]*\)\..*|\1|") + LEADER_ELECTION_ROLE_RULES=$(cat $X | yq -r .spec.install.spec.permissions | sed -e 's|- rules:|rules:|' | sed -e 's| ||' | sed -e '/ serviceAccountName.*/d' +) + CLUSTER_ROLE_RULES=$(cat $X | yq -r .spec.install.spec.clusterPermissions| sed -e 's|- rules:|rules:|' | sed -e 's| ||' | sed -e '/ serviceAccountName.*/d' +) + +mkdir -p rbac +cat > rbac/$OPERATOR_NAME-rbac.yaml < ../config/operator/manager_operator_images.yaml < ../hack/export_operator_related_images.sh <> ../config/operator/manager_operator_images.yaml <> ../hack/export_operator_related_images.sh <