From 17daa5ef8d6f5b38fc51c7bf2b811337e617575c Mon Sep 17 00:00:00 2001 From: Ricardo Zanini Date: Sun, 4 Oct 2020 15:44:27 -0300 Subject: [PATCH] Fixes #161,#157,#154: Cluster scoped operator Signed-off-by: Ricardo Zanini --- README.md | 11 +- RELEASE_NOTES.md | 3 + cmd/manager/main.go | 2 +- deploy/namespace.yaml | 4 + ...operator.v0.4.0.clusterserviceversion.yaml | 66 +-- .../nexus-operator.clusterserviceversion.yaml | 68 +-- deploy/operator.yaml | 4 +- deploy/role.yaml | 2 +- deploy/role_binding.yaml | 5 +- hack/generate-manifests.sh | 2 + hack/generate-yaml-installer.sh | 35 ++ hack/install.sh | 29 +- nexus-operator.yaml | 553 ++++++++++++++++++ .../nexus/resource/deployment/manager.go | 2 +- .../nexus/resource/deployment/service.go | 3 +- .../nexus/resource/deployment/service_test.go | 2 +- pkg/controller/nexus/server/nexus.go | 2 +- pkg/controller/nexus/server/nexus_test.go | 3 +- pkg/framework/controller_watcher.go | 2 +- 19 files changed, 689 insertions(+), 109 deletions(-) create mode 100644 RELEASE_NOTES.md create mode 100644 deploy/namespace.yaml create mode 100755 hack/generate-yaml-installer.sh create mode 100644 nexus-operator.yaml diff --git a/README.md b/README.md index 19072626..5da227c8 100644 --- a/README.md +++ b/README.md @@ -46,19 +46,14 @@ If you have any questions please either [open an issue](https://github.com/m88i/ ## Quick Install -The installation procedure will create a Namespace named `nexus` and a Nexus 3.x server for you: +The installation procedure will create a Namespace named `operators` and will install every resources needed for the operator to run: ```bash make install ``` -You can then edit or customize the installation as you pleased, just run: - -```bash -kubectl edit nexus -``` - -If you're running on Kubernetes, edit the Nexus resource to add a [valid host for the Ingress](#network-on-kubernetes-114) to work. +You can choose any flavors of Nexus 3.x server from our [`examples`](examples) directory and apply the YAML in any namespace in your cluster. +Use this examples as a starting point to customize the server to meet your requirements. ### Openshift diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md new file mode 100644 index 00000000..d4629475 --- /dev/null +++ b/RELEASE_NOTES.md @@ -0,0 +1,3 @@ +## Version 0.4.0 + +- #161 - Nexus Operator is now cluster-scoped, meaning that you can install the operator and the Nexus CRs in separated namespaces. See [Operator Scopes](https://sdk.operatorframework.io/docs/building-operators/golang/operator-scope/) for more information. \ No newline at end of file diff --git a/cmd/manager/main.go b/cmd/manager/main.go index b53c34ab..607766a4 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -108,7 +108,7 @@ func main() { // Set default manager options options := manager.Options{ - Namespace: namespace, + Namespace: "", MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort), } diff --git a/deploy/namespace.yaml b/deploy/namespace.yaml new file mode 100644 index 00000000..8269bfee --- /dev/null +++ b/deploy/namespace.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: operators diff --git a/deploy/olm-catalog/nexus-operator/0.4.0/nexus-operator.v0.4.0.clusterserviceversion.yaml b/deploy/olm-catalog/nexus-operator/0.4.0/nexus-operator.v0.4.0.clusterserviceversion.yaml index 97c3672c..12e0085a 100644 --- a/deploy/olm-catalog/nexus-operator/0.4.0/nexus-operator.v0.4.0.clusterserviceversion.yaml +++ b/deploy/olm-catalog/nexus-operator/0.4.0/nexus-operator.v0.4.0.clusterserviceversion.yaml @@ -150,39 +150,7 @@ spec: mediatype: image/svg+xml install: spec: - deployments: - - name: nexus-operator - spec: - replicas: 1 - selector: - matchLabels: - name: nexus-operator - strategy: {} - template: - metadata: - labels: - name: nexus-operator - spec: - containers: - - command: - - nexus-operator - env: - - name: WATCH_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.annotations['olm.targetNamespaces'] - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: OPERATOR_NAME - value: nexus-operator - image: quay.io/m88i/nexus-operator:0.4.0 - imagePullPolicy: Always - name: nexus-operator - resources: {} - serviceAccountName: nexus-operator - permissions: + clusterPermissions: - rules: - apiGroups: - "" @@ -283,6 +251,38 @@ spec: verbs: - get serviceAccountName: nexus-operator + deployments: + - name: nexus-operator + spec: + replicas: 1 + selector: + matchLabels: + name: nexus-operator + strategy: {} + template: + metadata: + labels: + name: nexus-operator + spec: + containers: + - command: + - nexus-operator + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.annotations['olm.targetNamespaces'] + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: nexus-operator + image: quay.io/m88i/nexus-operator:0.4.0 + imagePullPolicy: Always + name: nexus-operator + resources: {} + serviceAccountName: nexus-operator strategy: deployment installModes: - supported: true diff --git a/deploy/olm-catalog/nexus-operator/manifests/nexus-operator.clusterserviceversion.yaml b/deploy/olm-catalog/nexus-operator/manifests/nexus-operator.clusterserviceversion.yaml index 97c3672c..420b0f86 100644 --- a/deploy/olm-catalog/nexus-operator/manifests/nexus-operator.clusterserviceversion.yaml +++ b/deploy/olm-catalog/nexus-operator/manifests/nexus-operator.clusterserviceversion.yaml @@ -150,39 +150,7 @@ spec: mediatype: image/svg+xml install: spec: - deployments: - - name: nexus-operator - spec: - replicas: 1 - selector: - matchLabels: - name: nexus-operator - strategy: {} - template: - metadata: - labels: - name: nexus-operator - spec: - containers: - - command: - - nexus-operator - env: - - name: WATCH_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.annotations['olm.targetNamespaces'] - - name: POD_NAME - valueFrom: - fieldRef: - fieldPath: metadata.name - - name: OPERATOR_NAME - value: nexus-operator - image: quay.io/m88i/nexus-operator:0.4.0 - imagePullPolicy: Always - name: nexus-operator - resources: {} - serviceAccountName: nexus-operator - permissions: + clusterPermissions: - rules: - apiGroups: - "" @@ -283,13 +251,45 @@ spec: verbs: - get serviceAccountName: nexus-operator + deployments: + - name: nexus-operator + spec: + replicas: 1 + selector: + matchLabels: + name: nexus-operator + strategy: {} + template: + metadata: + labels: + name: nexus-operator + spec: + containers: + - command: + - nexus-operator + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.annotations['olm.targetNamespaces'] + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: nexus-operator + image: quay.io/m88i/nexus-operator:0.4.0 + imagePullPolicy: Always + name: nexus-operator + resources: {} + serviceAccountName: nexus-operator strategy: deployment installModes: - supported: true type: OwnNamespace - supported: true type: SingleNamespace - - supported: false + - supported: true type: MultiNamespace - supported: true type: AllNamespaces diff --git a/deploy/operator.yaml b/deploy/operator.yaml index 369a61cf..5dc613bd 100644 --- a/deploy/operator.yaml +++ b/deploy/operator.yaml @@ -21,9 +21,7 @@ spec: imagePullPolicy: Always env: - name: WATCH_NAMESPACE - valueFrom: - fieldRef: - fieldPath: metadata.namespace + value: "" - name: POD_NAME valueFrom: fieldRef: diff --git a/deploy/role.yaml b/deploy/role.yaml index b2289562..592cb84a 100644 --- a/deploy/role.yaml +++ b/deploy/role.yaml @@ -1,5 +1,5 @@ apiVersion: rbac.authorization.k8s.io/v1 -kind: Role +kind: ClusterRole metadata: creationTimestamp: null name: nexus-operator diff --git a/deploy/role_binding.yaml b/deploy/role_binding.yaml index bc9e1f88..d4e4a070 100644 --- a/deploy/role_binding.yaml +++ b/deploy/role_binding.yaml @@ -1,11 +1,12 @@ -kind: RoleBinding +kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: nexus-operator subjects: - kind: ServiceAccount name: nexus-operator + namespace: ${NAMESPACE} roleRef: - kind: Role + kind: ClusterRole name: nexus-operator apiGroup: rbac.authorization.k8s.io diff --git a/hack/generate-manifests.sh b/hack/generate-manifests.sh index f6d6158d..bf88d632 100755 --- a/hack/generate-manifests.sh +++ b/hack/generate-manifests.sh @@ -25,3 +25,5 @@ operator-sdk generate csv --apis-dir ./pkg/apis/apps/v1alpha1 --verbose --operat # our package doesn't have the same name as the operator rm ./deploy/olm-catalog/nexus-operator/nexus-operator.package.yaml -rf + +source ./hack/generate-yaml-installer.sh \ No newline at end of file diff --git a/hack/generate-yaml-installer.sh b/hack/generate-yaml-installer.sh new file mode 100755 index 00000000..289fbed6 --- /dev/null +++ b/hack/generate-yaml-installer.sh @@ -0,0 +1,35 @@ +#!/bin/bash +# Copyright 2020 Nexus Operator and/or its authors +# +# 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. + +# generating all in one yaml file +sed -i '4 a \ \ namespace: operators' ./deploy/operator.yaml +sed -i '4 a \ \ namespace: operators' ./deploy/service_account.yaml + +cat ./deploy/namespace.yaml > nexus-operator.yaml +echo "---" >> nexus-operator.yaml +cat ./deploy/crds/apps.m88i.io_nexus_crd.yaml >> nexus-operator.yaml +echo "---" >> nexus-operator.yaml +cat ./deploy/service_account.yaml >> nexus-operator.yaml +echo "---" >> nexus-operator.yaml +cat ./deploy/role.yaml >> nexus-operator.yaml +echo "---" >> nexus-operator.yaml +cat ./deploy/role_binding.yaml >> nexus-operator.yaml +echo "---" >> nexus-operator.yaml +cat ./deploy/operator.yaml >> nexus-operator.yaml + +sed -i '5d' ./deploy/operator.yaml +sed -i '5d' ./deploy/service_account.yaml + +sed -i "s/\${NAMESPACE}/operators/g" nexus-operator.yaml \ No newline at end of file diff --git a/hack/install.sh b/hack/install.sh index 371f4def..1cff626b 100755 --- a/hack/install.sh +++ b/hack/install.sh @@ -14,27 +14,16 @@ # limitations under the License. -# The git command will fetch the most recent tag across all branches -LATEST_TAG=$(git describe --tags $(git rev-list --tags --max-count=1)) -NAMESPACE=nexus +VERSION=$1 -echo "[INFO] The repository will be checked out at the latest release" -echo "....... Checkout code at ${LATEST_TAG} ......" -git checkout tags/${LATEST_TAG} +if [ -z ${VERSION} ]; then + echo "Please inform the desired version" + exit(1) +fi -echo "....... Creating namespace ......." -kubectl create namespace ${NAMESPACE} +echo "Downloading latest version" +curl -LO https://github.com/m88i/nexus-operator/releases/download/${VERSION}/nexus-operator.yaml -echo "....... Applying CRDS ......." -kubectl apply -f deploy/crds/apps.m88i.io_nexus_crd.yaml +echo "....... Installing Nexus Operator ......." -echo "....... Applying Rules and Service Account ......." -kubectl apply -f deploy/role.yaml -n ${NAMESPACE} -kubectl apply -f deploy/role_binding.yaml -n ${NAMESPACE} -kubectl apply -f deploy/service_account.yaml -n ${NAMESPACE} - -echo "....... Applying Nexus Operator ......." -kubectl apply -f deploy/operator.yaml -n ${NAMESPACE} - -echo "....... Creating the Nexus 3.x Server ......." -kubectl apply -f examples/nexus3-centos-no-volume.yaml -n ${NAMESPACE} +kubectl apply -f nexus-operator.yaml \ No newline at end of file diff --git a/nexus-operator.yaml b/nexus-operator.yaml new file mode 100644 index 00000000..66a5bf14 --- /dev/null +++ b/nexus-operator.yaml @@ -0,0 +1,553 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: operators +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: nexus.apps.m88i.io +spec: + group: apps.m88i.io + names: + kind: Nexus + listKind: NexusList + plural: nexus + singular: nexus + scope: Namespaced + subresources: + status: {} + validation: + openAPIV3Schema: + description: Nexus custom resource to deploy the Nexus Server + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: NexusSpec defines the desired state of Nexus + properties: + automaticUpdate: + description: Automatic updates configuration + properties: + disabled: + description: Whether or not the Operator should perform automatic + updates. Defaults to `false` (auto updates are enabled). Is set + to `false` if `spec.image` is not empty and is different from + the default community image. + type: boolean + minorVersion: + description: The Nexus image minor version the deployment should + stay in. If left blank and automatic updates are enabled the latest + minor is set. + minimum: 0 + type: integer + type: object + generateRandomAdminPassword: + description: 'GenerateRandomAdminPassword enables the random password + generation. Defaults to `false`: the default password for a newly + created instance is ''admin123'', which should be changed in the first + login. If set to `true`, you must use the automatically generated + ''admin'' password, stored in the container''s file system at `/nexus-data/admin.password`. + The operator uses the default credentials to create a user for itself + to create default repositories. If set to `true`, the repositories + won''t be created since the operator won''t fetch for the random password.' + type: boolean + image: + description: 'Full image tag name for this specific deployment. Will + be ignored if `spec.useRedHatImage` is set to `true`. Default: docker.io/sonatype/nexus3:latest' + type: string + imagePullPolicy: + description: 'The image pull policy for the Nexus image. If left blank + behavior will be determined by the image tag (`Always` if "latest" + and `IfNotPresent` otherwise). Possible values: `Always`, `IfNotPresent` + or `Never`.' + enum: + - Always + - IfNotPresent + - Never + type: string + livenessProbe: + description: LivenessProbe describes how the Nexus container liveness + probe should work + properties: + failureThreshold: + description: Minimum consecutive failures for the probe to be considered + failed after having succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + minimum: 1 + type: integer + initialDelaySeconds: + description: Number of seconds after the container has started before + probes are initiated. Defaults to 240 seconds. Minimum value is + 0. + format: int32 + minimum: 0 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Defaults + to 10 seconds. Minimum value is 1. + format: int32 + minimum: 1 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered + successful after having failed. Defaults to 1. Must be 1 for liveness + and startup. Minimum value is 1. + format: int32 + minimum: 1 + type: integer + timeoutSeconds: + description: Number of seconds after which the probe times out. + Defaults to 15 seconds. Minimum value is 1. + format: int32 + minimum: 1 + type: integer + type: object + networking: + description: Networking definition + properties: + expose: + description: Set to `true` to expose the Nexus application. Defaults + to `false`. + type: boolean + exposeAs: + description: 'Type of networking exposure: NodePort, Route or Ingress. + Defaults to Route on OpenShift and Ingress on Kubernetes. Routes + are only available on Openshift and Ingresses are only available + on Kubernetes.' + enum: + - NodePort + - Route + - Ingress + type: string + host: + description: Host where the Nexus service is exposed. This attribute + is required if the service is exposed via Ingress. + type: string + nodePort: + description: NodePort defined in the exposed service. Required if + exposed via NodePort. + format: int32 + type: integer + tls: + description: TLS/SSL-related configuration + properties: + mandatory: + description: When exposing via Route, set to `true` to only + allow encrypted traffic using TLS (disables HTTP in favor + of HTTPS). Defaults to `false`. + type: boolean + secretName: + description: When exposing via Ingress, inform the name of the + TLS secret containing certificate and private key for TLS + encryption. It must be present in the same namespace as the + Operator. + type: string + type: object + type: object + persistence: + description: Persistence definition + properties: + persistent: + description: Flag to indicate if this instance will be persistent + or not + type: boolean + storageClass: + description: StorageClass used by the managed PVC. + type: string + volumeSize: + description: 'If persistent, the size of the Volume. Defaults: 10Gi' + type: string + required: + - persistent + type: object + readinessProbe: + description: ReadinessProbe describes how the Nexus container readiness + probe should work + properties: + failureThreshold: + description: Minimum consecutive failures for the probe to be considered + failed after having succeeded. Defaults to 3. Minimum value is + 1. + format: int32 + minimum: 1 + type: integer + initialDelaySeconds: + description: Number of seconds after the container has started before + probes are initiated. Defaults to 240 seconds. Minimum value is + 0. + format: int32 + minimum: 0 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. Defaults + to 10 seconds. Minimum value is 1. + format: int32 + minimum: 1 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be considered + successful after having failed. Defaults to 1. Must be 1 for liveness + and startup. Minimum value is 1. + format: int32 + minimum: 1 + type: integer + timeoutSeconds: + description: Number of seconds after which the probe times out. + Defaults to 15 seconds. Minimum value is 1. + format: int32 + minimum: 1 + type: integer + type: object + replicas: + description: Number of pod replicas desired. Defaults to 0. + format: int32 + maximum: 100 + minimum: 0 + type: integer + resources: + description: Defined Resources for the Nexus instance + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute resources + required. If Requests is omitted for a container, it defaults + to Limits if that is explicitly specified, otherwise to an implementation-defined + value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/' + type: object + type: object + serverOperations: + description: ServerOperations describes the options for the operations + performed on the deployed server instance + properties: + disableOperatorUserCreation: + description: DisableOperatorUserCreation disables the auto-creation + of the `nexus-operator` user on the deployed server. This user + performs all the operations on the server (such as creating the + community repos). If disabled, the Operator will use the default + `admin` user. Defaults to `false` (always create the user). Setting + this to `true` is not recommended as it grants the Operator more + privileges than it needs and it would not be possible to tell + apart operations performed by the `admin` and the Operator. + type: boolean + disableRepositoryCreation: + description: DisableRepositoryCreation disables the auto-creation + of Apache, JBoss and Red Hat repositories and their addition to + the Maven Public group in this Nexus instance. Defaults to `false` + (always try to create the repos). Set this to `true` to not create + them. Only works if `spec.generateRandomAdminPassword` is `false`. + type: boolean + type: object + serviceAccountName: + description: ServiceAccountName is the name of the ServiceAccount used + to run the Pods. If left blank, a default ServiceAccount is created + with the same name as the Nexus CR (`metadata.name`). + type: string + useRedHatImage: + description: If you have access to Red Hat Container Catalog, set this + to `true` to use the certified image provided by Sonatype Defaults + to `false` + type: boolean + required: + - persistence + - replicas + - useRedHatImage + type: object + status: + description: NexusStatus defines the observed state of Nexus + properties: + deploymentStatus: + description: Condition status for the Nexus deployment + properties: + availableReplicas: + description: Total number of available pods (ready for at least + minReadySeconds) targeted by this deployment. + format: int32 + type: integer + collisionCount: + description: Count of hash collisions for the Deployment. The Deployment + controller uses this field as a collision avoidance mechanism + when it needs to create the name for the newest ReplicaSet. + format: int32 + type: integer + conditions: + description: Represents the latest available observations of a deployment's + current state. + items: + description: DeploymentCondition describes the state of a deployment + at a certain point. + properties: + lastTransitionTime: + description: Last time the condition transitioned from one + status to another. + format: date-time + type: string + lastUpdateTime: + description: The last time this condition was updated. + format: date-time + type: string + message: + description: A human readable message indicating details about + the transition. + type: string + reason: + description: The reason for the condition's last transition. + type: string + status: + description: Status of the condition, one of True, False, + Unknown. + type: string + type: + description: Type of deployment condition. + type: string + required: + - status + - type + type: object + type: array + observedGeneration: + description: The generation observed by the deployment controller. + format: int64 + type: integer + readyReplicas: + description: Total number of ready pods targeted by this deployment. + format: int32 + type: integer + replicas: + description: Total number of non-terminated pods targeted by this + deployment (their labels match the selector). + format: int32 + type: integer + unavailableReplicas: + description: Total number of unavailable pods targeted by this deployment. + This is the total number of pods that are still required for the + deployment to have 100% available capacity. They may either be + pods that are running but not yet available or pods that still + have not been created. + format: int32 + type: integer + updatedReplicas: + description: Total number of non-terminated pods targeted by this + deployment that have the desired template spec. + format: int32 + type: integer + type: object + nexusRoute: + description: Route for external service access + type: string + nexusStatus: + description: Will be "OK" when this Nexus instance is up + type: string + reason: + description: Gives more information about a failure status + type: string + serverOperationsStatus: + description: ServerOperationsStatus describes the general status for + the operations performed in the Nexus server instance + properties: + communityRepositoriesCreated: + type: boolean + mavenCentralUpdated: + type: boolean + operatorUserCreated: + type: boolean + reason: + type: string + serverReady: + type: boolean + type: object + updateConditions: + description: Conditions reached during an update + items: + type: string + type: array + x-kubernetes-list-type: atomic + type: object + type: object + version: v1alpha1 + versions: + - name: v1alpha1 + served: true + storage: true +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: nexus-operator + namespace: operators +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: nexus-operator +rules: + - apiGroups: + - "" + resources: + - events + - persistentvolumeclaims + - secrets + - services + - serviceaccounts + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - apps + resources: + - deployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - get + - create + - apiGroups: + - apps + resourceNames: + - nexus-operator + resources: + - deployments/finalizers + verbs: + - update + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - apiGroups: + - apps.m88i.io + resources: + - "*" + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - route.openshift.io + resources: + - routes + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + resources: + - configmaps + verbs: + - get + - create + - apiGroups: + - apps + resources: + - replicasets + verbs: + - get +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: nexus-operator +subjects: +- kind: ServiceAccount + name: nexus-operator + namespace: operators +roleRef: + kind: ClusterRole + name: nexus-operator + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nexus-operator + namespace: operators +spec: + replicas: 1 + selector: + matchLabels: + name: nexus-operator + template: + metadata: + labels: + name: nexus-operator + spec: + serviceAccountName: nexus-operator + containers: + - name: nexus-operator + image: quay.io/m88i/nexus-operator:0.4.0 + command: + - nexus-operator + imagePullPolicy: Always + env: + - name: WATCH_NAMESPACE + value: "" + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: "nexus-operator" diff --git a/pkg/controller/nexus/resource/deployment/manager.go b/pkg/controller/nexus/resource/deployment/manager.go index 06061a25..1b187683 100644 --- a/pkg/controller/nexus/resource/deployment/manager.go +++ b/pkg/controller/nexus/resource/deployment/manager.go @@ -136,4 +136,4 @@ func normalizeSecurityContext(depDeployment, reqDeployment *appsv1.Deployment) { if reqDeployment.Spec.Template.Spec.SecurityContext == nil { depDeployment.Spec.Template.Spec.SecurityContext = nil } -} \ No newline at end of file +} diff --git a/pkg/controller/nexus/resource/deployment/service.go b/pkg/controller/nexus/resource/deployment/service.go index 282059c2..9db29868 100644 --- a/pkg/controller/nexus/resource/deployment/service.go +++ b/pkg/controller/nexus/resource/deployment/service.go @@ -24,6 +24,7 @@ import ( const ( NexusPortName = "http" NexusServicePort = 8081 + defaultHTTPPort = 80 ) func newService(nexus *v1alpha1.Nexus) *corev1.Service { @@ -34,7 +35,7 @@ func newService(nexus *v1alpha1.Nexus) *corev1.Service { { Name: NexusPortName, Protocol: corev1.ProtocolTCP, - Port: NexusServicePort, + Port: defaultHTTPPort, TargetPort: intstr.IntOrString{ IntVal: NexusServicePort, }, diff --git a/pkg/controller/nexus/resource/deployment/service_test.go b/pkg/controller/nexus/resource/deployment/service_test.go index be946bb5..dbe9e422 100644 --- a/pkg/controller/nexus/resource/deployment/service_test.go +++ b/pkg/controller/nexus/resource/deployment/service_test.go @@ -40,7 +40,7 @@ func Test_newService(t *testing.T) { svc := newService(nexus) assert.Len(t, svc.Spec.Ports, 1) - assert.Equal(t, int32(NexusServicePort), svc.Spec.Ports[0].Port) + assert.Equal(t, int32(defaultHTTPPort), svc.Spec.Ports[0].Port) assert.Equal(t, appName, svc.Labels[meta.AppLabel]) assert.Equal(t, appName, svc.Spec.Selector[meta.AppLabel]) } diff --git a/pkg/controller/nexus/server/nexus.go b/pkg/controller/nexus/server/nexus.go index 453754e1..e6a64e29 100644 --- a/pkg/controller/nexus/server/nexus.go +++ b/pkg/controller/nexus/server/nexus.go @@ -88,7 +88,7 @@ func (s *server) getNexusEndpoint() (string, error) { if err := s.k8sclient.Get(context.TODO(), types.NamespacedName{Name: s.nexus.Name, Namespace: s.nexus.Namespace}, svc); err != nil { return "", err } - return fmt.Sprintf("http://%s:%s", svc.Name, svc.Spec.Ports[0].TargetPort.String()), nil + return fmt.Sprintf("http://%s.%s", svc.Name, svc.Namespace), nil } // isServerReady checks if the given Nexus instance is ready to receive requests diff --git a/pkg/controller/nexus/server/nexus_test.go b/pkg/controller/nexus/server/nexus_test.go index 54f072c8..9c083899 100644 --- a/pkg/controller/nexus/server/nexus_test.go +++ b/pkg/controller/nexus/server/nexus_test.go @@ -66,7 +66,7 @@ func Test_server_getNexusEndpoint(t *testing.T) { { Name: "http", Protocol: corev1.ProtocolTCP, - Port: 8081, + Port: 80, TargetPort: intstr.IntOrString{ IntVal: 8081, }, @@ -85,7 +85,6 @@ func Test_server_getNexusEndpoint(t *testing.T) { assert.NoError(t, err) assert.NotEmpty(t, URL) assert.Contains(t, URL, nexus.Name) - assert.Contains(t, URL, "8081") _, err = url.Parse(URL) assert.NoError(t, err) } diff --git a/pkg/framework/controller_watcher.go b/pkg/framework/controller_watcher.go index ac73341c..5c3e1dd1 100644 --- a/pkg/framework/controller_watcher.go +++ b/pkg/framework/controller_watcher.go @@ -99,7 +99,7 @@ func (c *controllerWatcher) Watch(watchedObjects ...WatchedObjects) (err error) delete(c.groupsNotWatched, object.GroupVersion.Group) } else { c.groupsNotWatched[object.GroupVersion.Group] = true - log.Warnf("Impossible to register GroupVersion %s. CRD not installed in the cluster, controller might not behave as expected", object.GroupVersion) + log.Infof("Skipping registration of GroupVersion %s. CRD not installed in the cluster", object.GroupVersion) } } }