From 2cdddcf59df26a27c186b5d7420433237e7406b8 Mon Sep 17 00:00:00 2001 From: John Peterson Date: Fri, 2 Oct 2020 20:25:06 -0700 Subject: [PATCH] Artifactory Operator v1.1.0 published --- .../operator/artifactory-ha-operator/PROJECT | 4 + .../artifactory-ha-operator/README.md | 8 +- ...operator.v1.1.0.clusterserviceversion.yaml | 4 +- ...operator.v1.1.0.clusterserviceversion.yaml | 4 +- ...enshiftartifactoryha-operator.package.yaml | 5 + .../bundle/bundle-1.1.0.Dockerfile | 7 - ...che.jfrog.com_openshiftartifactoryhas.yaml | 388 ++++++ ...lm.k8s.io_openshiftartifactoryhas_crd.yaml | 23 + .../config/crd/kustomization.yaml | 6 + .../config/manager/manager.yaml | 50 +- .../config/rbac/namespace.yaml | 4 + .../openshiftartifactoryha_editor_role.yaml | 24 + .../openshiftartifactoryha_viewer_role.yaml | 20 + .../config/rbac/project.yaml | 89 ++ .../config/rbac/role.yaml | 126 +- .../config/rbac/role_binding.yaml | 15 +- .../config/rbac/service_account.yaml | 4 + ...cache_v1alpha1_openshiftartifactoryha.yaml | 1093 +++++++++++++++++ ...io_v1alpha1_openshiftartifactoryha_cr.yaml | 97 ++ .../config/samples/kustomization.yaml | 4 + .../artifactory-ha-operator/watches.yaml | 2 +- 21 files changed, 1912 insertions(+), 65 deletions(-) create mode 100644 Openshift4/operator/artifactory-ha-operator/bundle/1.1.0/metadata/openshiftartifactoryha-operator.package.yaml create mode 100644 Openshift4/operator/artifactory-ha-operator/config/crd/bases/cache.jfrog.com_openshiftartifactoryhas.yaml create mode 100644 Openshift4/operator/artifactory-ha-operator/config/crd/bases/charts.helm.k8s.io_openshiftartifactoryhas_crd.yaml create mode 100644 Openshift4/operator/artifactory-ha-operator/config/crd/kustomization.yaml create mode 100644 Openshift4/operator/artifactory-ha-operator/config/rbac/namespace.yaml create mode 100644 Openshift4/operator/artifactory-ha-operator/config/rbac/openshiftartifactoryha_editor_role.yaml create mode 100644 Openshift4/operator/artifactory-ha-operator/config/rbac/openshiftartifactoryha_viewer_role.yaml create mode 100644 Openshift4/operator/artifactory-ha-operator/config/rbac/project.yaml create mode 100644 Openshift4/operator/artifactory-ha-operator/config/rbac/service_account.yaml create mode 100644 Openshift4/operator/artifactory-ha-operator/config/samples/cache_v1alpha1_openshiftartifactoryha.yaml create mode 100644 Openshift4/operator/artifactory-ha-operator/config/samples/charts.helm.k8s.io_v1alpha1_openshiftartifactoryha_cr.yaml create mode 100644 Openshift4/operator/artifactory-ha-operator/config/samples/kustomization.yaml diff --git a/Openshift4/operator/artifactory-ha-operator/PROJECT b/Openshift4/operator/artifactory-ha-operator/PROJECT index f6e99ea..e2ba05e 100644 --- a/Openshift4/operator/artifactory-ha-operator/PROJECT +++ b/Openshift4/operator/artifactory-ha-operator/PROJECT @@ -1,4 +1,8 @@ domain: jfrog.com layout: helm.sdk.operatorframework.io/v1 projectName: artifactory-ha-operator +resources: +- group: cache + kind: OpenshiftArtifactoryHa + version: v1alpha1 version: 3-alpha diff --git a/Openshift4/operator/artifactory-ha-operator/README.md b/Openshift4/operator/artifactory-ha-operator/README.md index 9a96d75..5e3ac52 100644 --- a/Openshift4/operator/artifactory-ha-operator/README.md +++ b/Openshift4/operator/artifactory-ha-operator/README.md @@ -4,6 +4,12 @@ This code base is intended to deploy Artifactory HA as an operator to an Openshi Openshift OperatorHub has the latest official supported Cluster Service Version (CSV) for the OLM catalog. +# Breaking Changes + +``` +v1.1.0 breaks existing upgrade path due to base helm chart breaking changes +``` + ## Getting Started These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. See deployment for notes on how to deploy the project on a live system. @@ -141,4 +147,4 @@ We use [SemVer](http://semver.org/) for versioning. For the versions available, ## Contact -Github Issues \ No newline at end of file +Github Issues diff --git a/Openshift4/operator/artifactory-ha-operator/bundle/1.1.0/artifactory-ha-operator.v1.1.0.clusterserviceversion.yaml b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.0/artifactory-ha-operator.v1.1.0.clusterserviceversion.yaml index 54370c8..08e5515 100644 --- a/Openshift4/operator/artifactory-ha-operator/bundle/1.1.0/artifactory-ha-operator.v1.1.0.clusterserviceversion.yaml +++ b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.0/artifactory-ha-operator.v1.1.0.clusterserviceversion.yaml @@ -108,7 +108,9 @@ spec: name: '' version: apps/v1 version: v1alpha1 - description: '## Overview + description: '## [BREAKING] Upgrades from 1.0.0 to 1.1.x currently are not supported. New installations only. + + ## Overview Openshift Operator to deploy JFrog Artifactory Enterprise into your Openshift cluster. diff --git a/Openshift4/operator/artifactory-ha-operator/bundle/1.1.0/manifests/artifactory-ha-operator.v1.1.0.clusterserviceversion.yaml b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.0/manifests/artifactory-ha-operator.v1.1.0.clusterserviceversion.yaml index 0acb529..73e213f 100644 --- a/Openshift4/operator/artifactory-ha-operator/bundle/1.1.0/manifests/artifactory-ha-operator.v1.1.0.clusterserviceversion.yaml +++ b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.0/manifests/artifactory-ha-operator.v1.1.0.clusterserviceversion.yaml @@ -110,7 +110,9 @@ spec: name: '' version: apps/v1 version: v1alpha1 - description: '## Overview + description: '## [BREAKING] Upgrades from 1.0.0 to 1.1.x currently are not supported. New installations only. + + ## Overview Openshift Operator to deploy JFrog Artifactory Enterprise into your Openshift cluster. diff --git a/Openshift4/operator/artifactory-ha-operator/bundle/1.1.0/metadata/openshiftartifactoryha-operator.package.yaml b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.0/metadata/openshiftartifactoryha-operator.package.yaml new file mode 100644 index 0000000..397bc5c --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.0/metadata/openshiftartifactoryha-operator.package.yaml @@ -0,0 +1,5 @@ +channels: +- currentCSV: artifactory-ha-operator.v1.1.1 + name: alpha +defaultChannel: '' +packageName: openshiftartifactoryha-operator diff --git a/Openshift4/operator/artifactory-ha-operator/bundle/bundle-1.1.0.Dockerfile b/Openshift4/operator/artifactory-ha-operator/bundle/bundle-1.1.0.Dockerfile index a8bc459..31268f3 100644 --- a/Openshift4/operator/artifactory-ha-operator/bundle/bundle-1.1.0.Dockerfile +++ b/Openshift4/operator/artifactory-ha-operator/bundle/bundle-1.1.0.Dockerfile @@ -1,12 +1,5 @@ FROM scratch -LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1 -LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ -LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ -LABEL operators.operatorframework.io.bundle.package.v1=openshiftartifactoryha-operator -LABEL operators.operatorframework.io.bundle.channels.v1=alpha -LABEL operators.operatorframework.io.bundle.channel.default.v1=alpha - LABEL operators.operatorframework.io.bundle.mediatype.v1=registry+v1 LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ diff --git a/Openshift4/operator/artifactory-ha-operator/config/crd/bases/cache.jfrog.com_openshiftartifactoryhas.yaml b/Openshift4/operator/artifactory-ha-operator/config/crd/bases/cache.jfrog.com_openshiftartifactoryhas.yaml new file mode 100644 index 0000000..73b9b38 --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/config/crd/bases/cache.jfrog.com_openshiftartifactoryhas.yaml @@ -0,0 +1,388 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + alm-examples: |- + [ + { + "apiVersion": "charts.helm.k8s.io/v1alpha1", + "kind": "OpenshiftArtifactoryHa", + "metadata": { + "name": "openshiftartifactoryha" + }, + "spec": { + "artifactory-ha": { + "artifactory": { + "image": { + "registry": "registry.connect.redhat.com", + "repository": "jfrog/artifactory-pro", + "tag": "7.9.0" + }, + "joinKey": "OVERRIDE", + "masterKey": "OVERRIDE", + "uid": "1000721030", + "node": { + "replicaCount": 2, + "waitForPrimaryStartup": { + "enabled": false + } + } + }, + "database": { + "driver": "OVERRIDE", + "password": "OVERRIDE", + "type": "OVERRIDE", + "url": "OVERRIDE", + "user": "OVERRIDE" + }, + "initContainerImage": "registry.connect.redhat.com/jfrog/init:1.0.1", + "nginx": { + "uid": "1000720104", + "gid": "1000720107", + "http": { + "externalPort": 80, + "internalPort": 8080 + }, + "https": { + "externalPort": 443, + "internalPort": 8443 + }, + "image": { + "registry": "registry.redhat.io", + "repository": "rhel8/nginx-116", + "tag": "latest" + }, + "service": { + "ssloffload": false + }, + "tlsSecretName": "OVERRIDE" + }, + "postgresql": { + "enabled": false + }, + "waitForDatabase": true + } + } + } + ] + capabilities: Seamless Upgrades + operators.operatorframework.io/builder: operator-sdk-v1.0.1 + operators.operatorframework.io/project_layout: helm.sdk.operatorframework.io/v1 + categories: Developer Tools,Integration & Delivery + certified: 'true' + containerImage: registry.connect.redhat.com/jfrog/artifactory-operator:7.9.0 + createdAt: 2020-03-25 00:00:00+00:00 + description: JFrog Artifactory Enterprise deploys Artifactory in a high availability + environment across multiple pods + repository: https://github.com/jfrog/JFrog-Cloud-Installers/tree/openshift4/Openshift4 + support: JFrog + creationTimestamp: null + name: artifactory-ha-operator.v1.1.0 + namespace: default +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: + - description: Represents Artifactory HA Instances + displayName: Artifactory HA + kind: OpenshiftArtifactoryHa + name: openshiftartifactoryhas.charts.helm.k8s.io + resources: + - kind: Deployment + name: '' + version: v1 + - kind: Service + name: '' + version: v1 + - kind: ReplicaSet + name: '' + version: v1 + - kind: Pod + name: '' + version: v1 + - kind: Secret + name: '' + version: v1 + - kind: ConfigMap + name: '' + version: v1 + - kind: StatefulSet + name: '' + version: apps/v1 + version: v1alpha1 + description: '## Overview + + Openshift Operator to deploy JFrog Artifactory Enterprise into your Openshift + cluster. + + + ## Usage + + + An external DB is required. The operator will not deploy a DB but will require + you to specify the configuration values to connect to it. + + + Search for JFrog and click JFrog Artifactory Enterprise Operator to install. + + + Go to the Installed Operators. + + + Wait for the JFrog Artifactory Enterprise Operator to complete the installation. + + + Open the Operator and click on the provided API: Artifactory HA. + + + Click Create New Instance and provide the following parameters for your DB configuration: + + + ``` + + DATABASE_TYPE + + DATABASE_DRIVER + + DATABASE_URL + + DATABASE_USER + + DATABASE_PASSWORD + + ``` + + Master key and Join key must be supplied. To generate a new key for each run the command below: + + ``` + # Create a key + export JOIN_KEY=$(openssl rand -hex 32) + echo ${JOIN_KEY} + ``` + + To use TLS you will need to first create a k8s tls secret to store + your .crt and .key file into. + + Then supply the value of this k8s secret into the TLS_SECRET field. + + Click Create for Artifactory Enterprise to deploy into OpenShift and connect to + it on the external IP exposed by the load balancer. + + ' + displayName: JFrog Artifactory Enterprise Operator + icon: + - base64data: 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 + mediatype: image/png + install: + spec: + deployments: + - name: artifactory-ha-operatorvi + spec: + replicas: 1 + selector: + matchLabels: + name: artifactory-ha-operator + strategy: {} + template: + metadata: + labels: + name: artifactory-ha-operator + spec: + containers: + - env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.annotations['olm.targetNamespaces'] + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: artifactory-ha-operator + - name: RELATED_IMAGE_ARTIFACTORY_IMAGE_REPOSITORY + value: registry.connect.redhat.com/jfrog/artifactory-pro:7.9.0 + - name: RELATED_IMAGE_NGINX_IMAGE_REPOSITORY + value: registry.redhat.io/rhel8/nginx-116:latest + image: registry.connect.redhat.com/jfrog/artifactory-operator:7.9.0 + imagePullPolicy: Always + name: artifactory-ha-operator + resources: {} + serviceAccountName: artifactory-ha-operator + permissions: + - rules: + - apiGroups: + - '' + resources: + - pods + - services + - services/finalizers + - endpoints + - persistentvolumeclaims + - events + - configmaps + - secrets + - serviceaccounts + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - apps + resources: + - deployments + - daemonsets + - replicasets + - statefulsets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - '' + resources: + - namespaces + verbs: + - get + - apiGroups: + - '' + resourceNames: + - artifactory-ha-operator + resources: + - '*' + verbs: + - '*' + - apiGroups: + - '' + resources: + - events + verbs: + - create + - apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - get + - create + - apiGroups: + - apps + resourceNames: + - artifactory-ha-operator + resources: + - deployments/finalizers + verbs: + - update + - apiGroups: + - '' + resources: + - pods + verbs: + - get + - apiGroups: + - apps + resources: + - replicasets + - deployments + verbs: + - get + - apiGroups: + - charts.helm.k8s.io + resources: + - '*' + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - charts.helm.k8s.io/v1alpha1 + resources: + - '*' + verbs: + - create + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - networking.k8s.io + resources: + - '*' + verbs: + - '*' + - apiGroups: + - policy + resources: + - '*' + verbs: + - '*' + - apiGroups: + - rbac.authorization.k8s.io + resources: + - '*' + verbs: + - '*' + serviceAccountName: artifactory-ha-operator + strategy: deployment + installModes: + - supported: true + type: OwnNamespace + - supported: true + type: SingleNamespace + - supported: false + type: MultiNamespace + - supported: true + type: AllNamespaces + keywords: + - DevOps + - CI/CD + - Developers + - Software + - Productivity + - Artifact Repository + - Repository Manager + - Docker + - Maven + - Git + - Helm + - npm + - go + - golang + - kubernetes + - k8s + - rpm + - yum + links: + - name: JFrog + url: https://www.jfrog.com + - name: JFrog Artifact Repository + url: https://jfrog.com/artifactory/ + - name: Artifactory Video + url: https://www.youtube.com/watch?v=r2_A5CPo43U + maintainers: + - email: partner-support@jfrog.com + name: JFrog + maturity: alpha + provider: + name: JFrog + replaces: artifactory-ha-operator.v1.0.3 + version: 1.1.0 +status: + certsLastUpdated: null + certsRotateAt: null + lastTransitionTime: null + lastUpdateTime: null diff --git a/Openshift4/operator/artifactory-ha-operator/config/crd/bases/charts.helm.k8s.io_openshiftartifactoryhas_crd.yaml b/Openshift4/operator/artifactory-ha-operator/config/crd/bases/charts.helm.k8s.io_openshiftartifactoryhas_crd.yaml new file mode 100644 index 0000000..17df5a1 --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/config/crd/bases/charts.helm.k8s.io_openshiftartifactoryhas_crd.yaml @@ -0,0 +1,23 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: openshiftartifactoryhas.charts.helm.k8s.io +spec: + group: charts.helm.k8s.io + names: + kind: OpenshiftArtifactoryHa + listKind: OpenshiftArtifactoryHaList + plural: openshiftartifactoryhas + singular: openshiftartifactoryha + scope: Namespaced + subresources: + status: {} + validation: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + version: v1alpha1 + versions: + - name: v1alpha1 + served: true + storage: true diff --git a/Openshift4/operator/artifactory-ha-operator/config/crd/kustomization.yaml b/Openshift4/operator/artifactory-ha-operator/config/crd/kustomization.yaml new file mode 100644 index 0000000..1b3363b --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/config/crd/kustomization.yaml @@ -0,0 +1,6 @@ +# This kustomization.yaml is not intended to be run by itself, +# since it depends on service name and namespace that are out of this kustomize package. +# It should be run by config/default +resources: +- bases/cache.jfrog.com_openshiftartifactoryhas.yaml +# +kubebuilder:scaffold:crdkustomizeresource diff --git a/Openshift4/operator/artifactory-ha-operator/config/manager/manager.yaml b/Openshift4/operator/artifactory-ha-operator/config/manager/manager.yaml index 09188c1..4d16016 100644 --- a/Openshift4/operator/artifactory-ha-operator/config/manager/manager.yaml +++ b/Openshift4/operator/artifactory-ha-operator/config/manager/manager.yaml @@ -1,38 +1,34 @@ -apiVersion: v1 -kind: Namespace -metadata: - labels: - control-plane: controller-manager - name: system ---- apiVersion: apps/v1 kind: Deployment metadata: - name: controller-manager - namespace: system - labels: - control-plane: controller-manager + name: artifactory-ha-operator spec: + replicas: 1 selector: matchLabels: - control-plane: controller-manager - replicas: 1 + name: artifactory-ha-operator template: metadata: labels: - control-plane: controller-manager + name: artifactory-ha-operator spec: + serviceAccountName: artifactory-ha-operator containers: - - image: controller:latest - args: - - "--enable-leader-election" - - "--leader-election-id=artifactory-ha-operator" - name: manager - resources: - limits: - cpu: 100m - memory: 90Mi - requests: - cpu: 100m - memory: 60Mi - terminationGracePeriodSeconds: 10 + - name: artifactory-ha-operator + image: registry.connect.redhat.com/jfrog/artifactory-operator + imagePullPolicy: Always + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: "artifactory-ha-operator" + - name: RELATED_IMAGE_ARTIFACTORY_IMAGE_REPOSITORY + value: "registry.connect.redhat.com/jfrog/artifactory-pro" + - name: RELATED_IMAGE_NGINX_IMAGE_REPOSITORY + value: "registry.redhat.io/rhel8/nginx-116" \ No newline at end of file diff --git a/Openshift4/operator/artifactory-ha-operator/config/rbac/namespace.yaml b/Openshift4/operator/artifactory-ha-operator/config/rbac/namespace.yaml new file mode 100644 index 0000000..b94caf4 --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/config/rbac/namespace.yaml @@ -0,0 +1,4 @@ +kind: Namespace +apiVersion: v1 +metadata: + name: jfrog-artifactory diff --git a/Openshift4/operator/artifactory-ha-operator/config/rbac/openshiftartifactoryha_editor_role.yaml b/Openshift4/operator/artifactory-ha-operator/config/rbac/openshiftartifactoryha_editor_role.yaml new file mode 100644 index 0000000..3ab4d99 --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/config/rbac/openshiftartifactoryha_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit openshiftartifactoryhas. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: openshiftartifactoryha-editor-role +rules: +- apiGroups: + - cache.jfrog.com + resources: + - openshiftartifactoryhas + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - cache.jfrog.com + resources: + - openshiftartifactoryhas/status + verbs: + - get diff --git a/Openshift4/operator/artifactory-ha-operator/config/rbac/openshiftartifactoryha_viewer_role.yaml b/Openshift4/operator/artifactory-ha-operator/config/rbac/openshiftartifactoryha_viewer_role.yaml new file mode 100644 index 0000000..26bf705 --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/config/rbac/openshiftartifactoryha_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view openshiftartifactoryhas. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: openshiftartifactoryha-viewer-role +rules: +- apiGroups: + - cache.jfrog.com + resources: + - openshiftartifactoryhas + verbs: + - get + - list + - watch +- apiGroups: + - cache.jfrog.com + resources: + - openshiftartifactoryhas/status + verbs: + - get diff --git a/Openshift4/operator/artifactory-ha-operator/config/rbac/project.yaml b/Openshift4/operator/artifactory-ha-operator/config/rbac/project.yaml new file mode 100644 index 0000000..c290689 --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/config/rbac/project.yaml @@ -0,0 +1,89 @@ +apiVersion: template.openshift.io/v1 +kind: Template +metadata: + creationTimestamp: null + name: project-request +objects: +- apiVersion: project.openshift.io/v1 + kind: Project + metadata: + annotations: + openshift.io/description: JFrog Artifactory + openshift.io/display-name: jfrog-artifactory + openshift.io/requester: integrations@jfrog.com + creationTimestamp: null + name: jfrog-artifactory + spec: {} + status: {} +- apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + annotations: + openshift.io/description: Allows all pods in this namespace to pull images from + this namespace. It is auto-managed by a controller; remove subjects to disable. + creationTimestamp: null + name: system:image-pullers + namespace: jfrog-artifactory + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:image-puller + subjects: + - apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:serviceaccounts:jfrog-artifactory +- apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + annotations: + openshift.io/description: Allows builds in this namespace to push images to + this namespace. It is auto-managed by a controller; remove subjects to disable. + creationTimestamp: null + name: system:image-builders + namespace: jfrog-artifactory + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:image-builder + subjects: + - kind: ServiceAccount + name: builder + namespace: jfrog-artifactory +- apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + annotations: + openshift.io/description: Allows deploymentconfigs in this namespace to rollout + pods in this namespace. It is auto-managed by a controller; remove subjects + to disable. + creationTimestamp: null + name: system:deployers + namespace: jfrog-artifactory + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:deployer + subjects: + - kind: ServiceAccount + name: deployer + namespace: jfrog-artifactory +- apiVersion: rbac.authorization.k8s.io/v1 + kind: RoleBinding + metadata: + creationTimestamp: null + name: admin + namespace: jfrog-artifactory + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: admin + subjects: + - apiGroup: rbac.authorization.k8s.io + kind: User + name: kubeadmin +parameters: +- name: PROJECT_NAME +- name: PROJECT_DISPLAYNAME +- name: PROJECT_DESCRIPTION +- name: PROJECT_ADMIN_USER +- name: PROJECT_REQUESTING_USER diff --git a/Openshift4/operator/artifactory-ha-operator/config/rbac/role.yaml b/Openshift4/operator/artifactory-ha-operator/config/rbac/role.yaml index 61e7591..0cdfc5b 100644 --- a/Openshift4/operator/artifactory-ha-operator/config/rbac/role.yaml +++ b/Openshift4/operator/artifactory-ha-operator/config/rbac/role.yaml @@ -1,31 +1,119 @@ apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole +kind: Role metadata: - name: manager-role + creationTimestamp: null + name: artifactory-ha-operator rules: -## -## Base operator rules -## -# We need to get namespaces so the operator can read namespaces to ensure they exist - apiGroups: - - "" + - "" resources: - - namespaces + - pods + - services + - services/finalizers + - endpoints + - persistentvolumeclaims + - events + - configmaps + - secrets + - serviceaccounts verbs: - - get -# We need to manage Helm release secrets + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - - "" + - apps resources: - - secrets + - deployments + - daemonsets + - replicasets + - statefulsets verbs: - - "*" -# We need to create events on CRs about things happening during reconciliation + - create + - delete + - get + - list + - patch + - update + - watch - apiGroups: - - "" + - "" resources: - - events + - namespaces verbs: - - create - -# +kubebuilder:scaffold:rules + - get +- apiGroups: + - "" + resourceNames: + - artifactory-ha-operator + resources: + - '*' + verbs: + - '*' +- apiGroups: + - "" + resources: + - events + verbs: + - create +- apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - get + - create +- apiGroups: + - apps + resourceNames: + - artifactory-ha-operator + resources: + - deployments/finalizers + verbs: + - update +- apiGroups: + - "" + resources: + - pods + verbs: + - get +- apiGroups: + - apps + resources: + - replicasets + - deployments + verbs: + - get +- apiGroups: + - charts.helm.k8s.io + resources: + - '*' + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - networking.k8s.io + resources: + - '*' + verbs: + - '*' +- apiGroups: + - policy + resources: + - '*' + verbs: + - '*' +- apiGroups: + - 'rbac.authorization.k8s.io' + resources: + - '*' + verbs: + - '*' diff --git a/Openshift4/operator/artifactory-ha-operator/config/rbac/role_binding.yaml b/Openshift4/operator/artifactory-ha-operator/config/rbac/role_binding.yaml index 8f26587..5e1093e 100644 --- a/Openshift4/operator/artifactory-ha-operator/config/rbac/role_binding.yaml +++ b/Openshift4/operator/artifactory-ha-operator/config/rbac/role_binding.yaml @@ -1,12 +1,11 @@ +kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding metadata: - name: manager-rolebinding -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: manager-role + name: artifactory-ha-operator subjects: - kind: ServiceAccount - name: default - namespace: system + name: artifactory-ha-operator +roleRef: + kind: Role + name: artifactory-ha-operator + apiGroup: rbac.authorization.k8s.io diff --git a/Openshift4/operator/artifactory-ha-operator/config/rbac/service_account.yaml b/Openshift4/operator/artifactory-ha-operator/config/rbac/service_account.yaml new file mode 100644 index 0000000..37ccebe --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/config/rbac/service_account.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: artifactory-ha-operator diff --git a/Openshift4/operator/artifactory-ha-operator/config/samples/cache_v1alpha1_openshiftartifactoryha.yaml b/Openshift4/operator/artifactory-ha-operator/config/samples/cache_v1alpha1_openshiftartifactoryha.yaml new file mode 100644 index 0000000..bd7bf63 --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/config/samples/cache_v1alpha1_openshiftartifactoryha.yaml @@ -0,0 +1,1093 @@ +apiVersion: cache.jfrog.com/v1alpha1 +kind: OpenshiftArtifactoryHa +metadata: + name: openshiftartifactoryha-sample +spec: + # Default values copied from /helm-charts/openshift-artifactory-ha/values.yaml + artifactory-ha: + access: + accessConfig: + security: + tls: false + database: + maxOpenConnections: 80 + tomcat: + connector: + extraConfig: acceptCount="100" + maxThreads: 50 + artifactory: + admin: + ip: 127.0.0.1 + username: admin + annotations: {} + binarystore: + enabled: true + catalinaLoggers: [] + catalinaLoggersResources: {} + configMapName: null + configMaps: "" + consoleLog: false + copyOnEveryStartup: null + customInitContainers: "" + customInitContainersBegin: "" + customPersistentPodVolumeClaim: {} + customPersistentVolumeClaim: {} + customSecrets: null + customSidecarContainers: "" + customVolumeMounts: "" + customVolumes: "" + database: + maxOpenConnections: 80 + deleteDBPropertiesOnStartup: true + externalArtifactoryPort: 8081 + externalPort: 8082 + extraEnvironmentVariables: null + haBackupDir: + enabled: false + haDataDir: + enabled: false + image: + pullPolicy: IfNotPresent + registry: registry.connect.redhat.com + repository: jfrog/artifactory-pro + tag: 7.9.0 + internalArtifactoryPort: 8081 + internalPort: 8082 + javaOpts: {} + joinKey: OVERRIDE + license: {} + livenessProbe: + enabled: true + failureThreshold: 10 + initialDelaySeconds: 180 + path: /router/api/v1/system/health + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + loggers: [] + loggersResources: {} + masterKey: OVERRIDE + migration: + enabled: true + timeoutSeconds: 3600 + name: artifactory-ha + node: + affinity: {} + javaOpts: + corePoolSize: 16 + jmx: + authenticate: false + enabled: false + port: 9010 + ssl: false + labels: {} + minAvailable: 1 + name: artifactory-ha-member + nodeSelector: {} + persistence: + existingClaim: false + podAntiAffinity: + topologyKey: kubernetes.io/hostname + type: "" + replicaCount: 2 + resources: {} + tolerations: [] + waitForPrimaryStartup: + enabled: false + time: null + persistence: + accessMode: ReadWriteOnce + awsS3: + bucketName: artifactory-ha-aws + httpsOnly: true + path: artifactory-ha/filestore + properties: {} + refreshCredentials: true + s3AwsVersion: AWS4-HMAC-SHA256 + testConnection: false + awsS3V3: + bucketName: artifactory-aws + enableSignedUrlRedirect: false + maxConnections: 50 + path: artifactory/filestore + signatureExpirySeconds: 300 + testConnection: false + useInstanceCredentials: true + usePresigning: false + azureBlob: + testConnection: false + binarystoreXml: | + {{- if eq .Values.artifactory.persistence.type "file-system" }} + + {{- if .Values.artifactory.persistence.fileSystem.existingSharedClaim.enabled }} + + + + + + {{- range $sharedClaimNumber, $e := until (.Values.artifactory.persistence.fileSystem.existingSharedClaim.numberOfExistingClaims|int) -}} + + {{- end }} + + + + + + {{ .Values.artifactory.persistence.maxCacheSize }} + {{ .Values.artifactory.persistence.cacheProviderDir }} + + + // Specify the read and write strategy and redundancy for the sharding binary provider + + roundRobin + percentageFreeSpace + 2 + + + {{- range $sharedClaimNumber, $e := until (.Values.artifactory.persistence.fileSystem.existingSharedClaim.numberOfExistingClaims|int) -}} + //For each sub-provider (mount), specify the filestore location + + filestore{{ $sharedClaimNumber }} + + {{- end }} + + {{- else }} + + + + + crossNetworkStrategy + crossNetworkStrategy + {{ .Values.artifactory.persistence.redundancy }} + 2 + 2 + + + + + + + + + {{ .Values.artifactory.persistence.maxCacheSize }} + {{ .Values.artifactory.persistence.cacheProviderDir }} + + + + + shard-fs-1 + local + + + + + 30 + tester-remote1 + 10000 + remote + + + + {{- end }} + {{- end }} + {{- if eq .Values.artifactory.persistence.type "google-storage" }} + + + + + + crossNetworkStrategy + crossNetworkStrategy + {{ .Values.artifactory.persistence.redundancy }} + 2 + + + + + + + + + + + + + + {{ .Values.artifactory.persistence.maxCacheSize }} + {{ .Values.artifactory.persistence.cacheProviderDir }} + + + + local + + + + 30 + 10000 + remote + + + + {{ .Values.artifactory.persistence.mountPath }}/data/filestore + /tmp + + + + google-cloud-storage + {{ .Values.artifactory.persistence.googleStorage.endpoint }} + {{ .Values.artifactory.persistence.googleStorage.httpsOnly }} + {{ .Values.artifactory.persistence.googleStorage.bucketName }} + {{ .Values.artifactory.persistence.googleStorage.identity }} + {{ .Values.artifactory.persistence.googleStorage.credential }} + {{ .Values.artifactory.persistence.googleStorage.path }} + {{ .Values.artifactory.persistence.googleStorage.bucketExists }} + + + {{- end }} + {{- if eq .Values.artifactory.persistence.type "aws-s3-v3" }} + + + + + + + + + + + + + + + + + crossNetworkStrategy + crossNetworkStrategy + {{ .Values.artifactory.persistence.redundancy }} + + + + + remote + + + + local + + + + + {{ .Values.artifactory.persistence.maxCacheSize }} + {{ .Values.artifactory.persistence.cacheProviderDir }} + + + {{- with .Values.artifactory.persistence.awsS3V3 }} + + {{ .testConnection }} + {{- if .identity }} + {{ .identity }} + {{- end }} + {{- if .credential }} + {{ .credential }} + {{- end }} + {{ .region }} + {{ .bucketName }} + {{ .path }} + {{ .endpoint }} + {{- with .maxConnections }} + {{ . }} + {{- end }} + {{- with .kmsServerSideEncryptionKeyId }} + {{ . }} + {{- end }} + {{- with .kmsKeyRegion }} + {{ . }} + {{- end }} + {{- with .kmsCryptoMode }} + {{ . }} + {{- end }} + {{- if .useInstanceCredentials }} + true + {{- else }} + false + {{- end }} + {{ .usePresigning }} + {{ .signatureExpirySeconds }} + {{- with .cloudFrontDomainName }} + {{ . }} + {{- end }} + {{- with .cloudFrontKeyPairId }} + {{ .cloudFrontKeyPairId }} + {{- end }} + {{- with .cloudFrontPrivateKey }} + {{ . }} + {{- end }} + {{- with .enableSignedUrlRedirect }} + {{ . }} + {{- end }} + + {{- end }} + + {{- end }} + + {{- if eq .Values.artifactory.persistence.type "aws-s3" }} + + + + + + + + + + + + + + + + + + {{ .Values.artifactory.persistence.maxCacheSize }} + {{ .Values.artifactory.persistence.cacheProviderDir }} + + + + local + + + + 30 + 10000 + remote + + + + crossNetworkStrategy + crossNetworkStrategy + {{ .Values.artifactory.persistence.redundancy }} + + + + + {{ .Values.artifactory.persistence.awsS3.endpoint }} + {{- if .Values.artifactory.persistence.awsS3.roleName }} + {{ .Values.artifactory.persistence.awsS3.roleName }} + true + {{- else }} + {{ .Values.artifactory.persistence.awsS3.refreshCredentials }} + {{- end }} + {{ .Values.artifactory.persistence.awsS3.s3AwsVersion }} + {{ .Values.artifactory.persistence.awsS3.testConnection }} + {{ .Values.artifactory.persistence.awsS3.httpsOnly }} + {{ .Values.artifactory.persistence.awsS3.region }} + {{ .Values.artifactory.persistence.awsS3.bucketName }} + {{- if .Values.artifactory.persistence.awsS3.identity }} + {{ .Values.artifactory.persistence.awsS3.identity }} + {{- end }} + {{- if .Values.artifactory.persistence.awsS3.credential }} + {{ .Values.artifactory.persistence.awsS3.credential }} + {{- end }} + {{ .Values.artifactory.persistence.awsS3.path }} + {{- range $key, $value := .Values.artifactory.persistence.awsS3.properties }} + + {{- end }} + + + {{- end }} + {{- if eq .Values.artifactory.persistence.type "azure-blob" }} + + + + + + + + + + + + + + + + + + {{ .Values.artifactory.persistence.maxCacheSize }} + {{ .Values.artifactory.persistence.cacheProviderDir }} + + + + + crossNetworkStrategy + crossNetworkStrategy + 2 + 1 + + + + + remote + + + + local + + + + + {{ .Values.artifactory.persistence.azureBlob.accountName }} + {{ .Values.artifactory.persistence.azureBlob.accountKey }} + {{ .Values.artifactory.persistence.azureBlob.endpoint }} + {{ .Values.artifactory.persistence.azureBlob.containerName }} + {{ .Values.artifactory.persistence.azureBlob.testConnection }} + + + {{- end }} + cacheProviderDir: cache + enabled: true + eventual: + numberOfThreads: 10 + fileSystem: + existingSharedClaim: + backupDir: /var/opt/jfrog/artifactory-backup + dataDir: '{{ .Values.artifactory.persistence.mountPath }}/artifactory-data' + enabled: false + numberOfExistingClaims: 1 + googleStorage: + bucketExists: false + bucketName: artifactory-ha-gcp + endpoint: storage.googleapis.com + gcpServiceAccount: + enabled: false + httpsOnly: false + path: artifactory-ha/filestore + local: false + maxCacheSize: 50000000000 + mountPath: /var/opt/jfrog/artifactory + nfs: + backupDir: /var/opt/jfrog/artifactory-backup + capacity: 200Gi + dataDir: /var/opt/jfrog/artifactory-ha + haBackupMount: /backup + haDataMount: /data + mountOptions: [] + redundancy: 3 + size: 200Gi + type: file-system + primary: + affinity: {} + javaOpts: + corePoolSize: 16 + jmx: + authenticate: false + enabled: false + port: 9010 + ssl: false + labels: {} + name: artifactory-ha-primary + nodeSelector: {} + persistence: + existingClaim: false + podAntiAffinity: + topologyKey: kubernetes.io/hostname + type: "" + resources: {} + tolerations: [] + priorityClass: + create: false + value: 1000000000 + readinessProbe: + enabled: true + failureThreshold: 10 + initialDelaySeconds: 90 + path: /router/api/v1/system/health + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + replicator: + enabled: false + ingress: + annotations: {} + hosts: [] + tls: [] + service: + annotations: {} + loadBalancerSourceRanges: [] + name: artifactory + pool: members + type: ClusterIP + ssh: + enabled: false + externalPort: 1339 + internalPort: 1339 + systemYaml: | + shared: + logging: + consoleLog: + enabled: {{ .Values.artifactory.consoleLog }} + extraJavaOpts: > + -Dartifactory.access.client.max.connections={{ .Values.access.tomcat.connector.maxThreads }} + {{- with .Values.artifactory.primary.javaOpts }} + -Dartifactory.async.corePoolSize={{ .corePoolSize }} + {{- if .xms }} + -Xms{{ .xms }} + {{- end }} + {{- if .xmx }} + -Xmx{{ .xmx }} + {{- end }} + {{- if .jmx.enabled }} + -Dcom.sun.management.jmxremote + -Dcom.sun.management.jmxremote.port={{ .jmx.port }} + -Dcom.sun.management.jmxremote.rmi.port={{ .jmx.port }} + -Dcom.sun.management.jmxremote.ssl={{ .jmx.ssl }} + {{- if .jmx.host }} + -Djava.rmi.server.hostname={{ tpl .jmx.host $ }} + {{- else }} + -Djava.rmi.server.hostname={{ template "artifactory-ha.fullname" $ }} + {{- end }} + {{- if .jmx.authenticate }} + -Dcom.sun.management.jmxremote.authenticate=true + -Dcom.sun.management.jmxremote.access.file={{ .jmx.accessFile }} + -Dcom.sun.management.jmxremote.password.file={{ .jmx.passwordFile }} + {{- else }} + -Dcom.sun.management.jmxremote.authenticate=false + {{- end }} + {{- end }} + {{- if .other }} + {{ .other }} + {{- end }} + {{- end }} + database: + {{- if .Values.postgresql.enabled }} + type: postgresql + url: "jdbc:postgresql://{{ .Release.Name }}-postgresql:{{ .Values.postgresql.service.port }}/{{ .Values.postgresql.postgresqlDatabase }}" + host: "" + driver: org.postgresql.Driver + username: "{{ .Values.postgresql.postgresqlUsername }}" + {{ else }} + type: "{{ .Values.database.type }}" + driver: "{{ .Values.database.driver }}" + {{- end }} + artifactory: + {{- if or .Values.artifactory.haDataDir.enabled .Values.artifactory.haBackupDir.enabled }} + node: + {{- if .Values.artifactory.haDataDir.path }} + haDataDir: {{ .Values.artifactory.haDataDir.path }} + {{- end }} + {{- if .Values.artifactory.haBackupDir.path }} + haBackupDir: {{ .Values.artifactory.haBackupDir.path }} + {{- end }} + {{- end }} + database: + maxOpenConnections: {{ .Values.artifactory.database.maxOpenConnections }} + tomcat: + connector: + maxThreads: {{ .Values.artifactory.tomcat.connector.maxThreads }} + extraConfig: {{ .Values.artifactory.tomcat.connector.extraConfig }} + frontend: + session: + timeMinutes: {{ .Values.frontend.session.timeoutMinutes }} + access: + database: + maxOpenConnections: {{ .Values.access.database.maxOpenConnections }} + tomcat: + connector: + maxThreads: {{ .Values.access.tomcat.connector.maxThreads }} + extraConfig: {{ .Values.access.tomcat.connector.extraConfig }} + {{- if .Values.access.database.enabled }} + type: "{{ .Values.access.database.type }}" + url: "{{ .Values.access.database.url }}" + driver: "{{ .Values.access.database.driver }}" + username: "{{ .Values.access.database.user }}" + password: "{{ .Values.access.database.password }}" + {{- end }} + metadata: + database: + maxOpenConnections: {{ .Values.metadata.database.maxOpenConnections }} + {{- if .Values.artifactory.replicator.enabled }} + replicator: + enabled: true + {{- end }} + terminationGracePeriodSeconds: 30 + tomcat: + connector: + extraConfig: acceptCount="100" + maxThreads: 200 + uid: "1000721030" + userPluginSecrets: null + database: + driver: OVERRIDE + password: OVERRIDE + secrets: {} + type: OVERRIDE + url: OVERRIDE + user: OVERRIDE + filebeat: + enabled: false + filebeatYml: | + logging.level: info + path.data: {{ .Values.artifactory.persistence.mountPath }}/log/filebeat + name: artifactory-filebeat + queue.spool: ~ + filebeat.inputs: + - type: log + enabled: true + close_eof: ${CLOSE:false} + paths: + - {{ .Values.artifactory.persistence.mountPath }}/log/*.log + fields: + service: "jfrt" + log_type: "artifactory" + output: + logstash: + hosts: ["{{ .Values.filebeat.logstashUrl }}"] + image: + repository: docker.elastic.co/beats/filebeat + version: 7.9.2 + livenessProbe: + exec: + command: + - sh + - -c + - | + #!/usr/bin/env bash -e + curl --fail 127.0.0.1:5066 + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + logstashUrl: logstash:5044 + name: artifactory-filebeat + readinessProbe: + exec: + command: + - sh + - -c + - | + #!/usr/bin/env bash -e + filebeat test output + failureThreshold: 3 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + resources: {} + terminationGracePeriod: 10 + frontend: + session: + timeoutMinutes: "30" + global: {} + ingress: + additionalRules: [] + annotations: {} + artifactoryPath: /artifactory/ + defaultBackend: + enabled: true + enabled: false + hosts: [] + labels: {} + routerPath: / + tls: [] + initContainerImage: registry.connect.redhat.com/jfrog/init:1.0.1 + initContainers: + resources: {} + installer: {} + installerInfo: '{ "productId": "Openshift_artifactory-ha/{{ .Chart.Version }}", "features": [ { "featureId": "ArtifactoryVersion/{{ default .Chart.AppVersion .Values.artifactory.image.version }}" }, { "featureId": "{{ if .Values.postgresql.enabled }}postgresql{{ else }}{{ .Values.database.type }}{{ end }}/0.0.0" }, { "featureId": "Platform/Openshift" }, { "featureId": "Partner/ACC-006983" }, { "featureId": "Channel/Openshift" } ] }' + logger: + image: + registry: docker.bintray.io + repository: busybox + tag: 1.31.1 + metadata: + database: + maxOpenConnections: 80 + networkpolicy: + - egress: + - {} + ingress: + - {} + name: artifactory + podSelector: + matchLabels: + app: artifactory-ha + nginx: + affinity: {} + artifactoryConf: | + {{- if .Values.nginx.https.enabled }} + ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; + ssl_certificate {{ .Values.nginx.persistence.mountPath }}/ssl/tls.crt; + ssl_certificate_key {{ .Values.nginx.persistence.mountPath }}/ssl/tls.key; + ssl_session_cache shared:SSL:1m; + ssl_prefer_server_ciphers on; + {{- end }} + ## server configuration + server { + {{- if .Values.nginx.internalPortHttps }} + listen {{ .Values.nginx.internalPortHttps }} ssl; + {{- else -}} + {{- if .Values.nginx.https.enabled }} + listen {{ .Values.nginx.https.internalPort }} ssl; + {{- end }} + {{- end }} + {{- if .Values.nginx.internalPortHttp }} + listen {{ .Values.nginx.internalPortHttp }}; + {{- else -}} + {{- if .Values.nginx.http.enabled }} + listen {{ .Values.nginx.http.internalPort }}; + {{- end }} + {{- end }} + server_name ~(?.+)\.{{ include "artifactory-ha.fullname" . }} {{ include "artifactory-ha.fullname" . }} + {{- range .Values.ingress.hosts -}} + {{- if contains "." . -}} + {{ "" | indent 0 }} ~(?.+)\.{{ . }} + {{- end -}} + {{- end -}}; + if ($http_x_forwarded_proto = '') { + set $http_x_forwarded_proto $scheme; + } + ## Application specific logs + ## access_log /var/log/nginx/artifactory-access.log timing; + ## error_log /var/log/nginx/artifactory-error.log; + rewrite ^/artifactory/?$ / redirect; + if ( $repo != "" ) { + rewrite ^/(v1|v2)/(.*) /artifactory/api/docker/$repo/$1/$2 break; + } + chunked_transfer_encoding on; + client_max_body_size 0; + + location / { + proxy_read_timeout 900; + proxy_pass_header Server; + proxy_cookie_path ~*^/.* /; + proxy_pass {{ include "artifactory-ha.scheme" . }}://{{ include "artifactory-ha.fullname" . }}:{{ .Values.artifactory.externalPort }}/; + {{- if .Values.nginx.service.ssloffload}} + proxy_set_header X-JFrog-Override-Base-Url $http_x_forwarded_proto://$host; + {{- else }} + proxy_set_header X-JFrog-Override-Base-Url $http_x_forwarded_proto://$host:$server_port; + proxy_set_header X-Forwarded-Port $server_port; + {{- end }} + proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; + proxy_set_header Host $http_host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + location /artifactory/ { + if ( $request_uri ~ ^/artifactory/(.*)$ ) { + proxy_pass {{ include "artifactory-ha.scheme" . }}://{{ include "artifactory-ha.fullname" . }}:{{ .Values.artifactory.externalArtifactoryPort }}/artifactory/$1; + } + proxy_pass {{ include "artifactory-ha.scheme" . }}://{{ include "artifactory-ha.fullname" . }}:{{ .Values.artifactory.externalArtifactoryPort }}/artifactory/; + } + } + } + customArtifactoryConfigMap: null + customConfigMap: null + enabled: true + gid: "1000720107" + http: + enabled: true + externalPort: 80 + internalPort: 8080 + https: + enabled: true + externalPort: 443 + internalPort: 8443 + image: + pullPolicy: IfNotPresent + registry: registry.redhat.io + repository: rhel8/nginx-116 + tag: latest + kind: Deployment + labels: {} + livenessProbe: + enabled: true + failureThreshold: 10 + initialDelaySeconds: 180 + path: /router/api/v1/system/health + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + loggers: [] + loggersResources: {} + logs: + level: warn + stderr: false + mainConf: | + # Main Nginx configuration file + worker_processes 4; + error_log {{ .Values.nginx.persistence.mountPath }}/logs//error.log warn; + pid /tmp/nginx.pid; + events { + worker_connections 1024; + } + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + variables_hash_max_size 1024; + variables_hash_bucket_size 64; + server_names_hash_max_size 4096; + server_names_hash_bucket_size 128; + types_hash_max_size 2048; + types_hash_bucket_size 64; + proxy_read_timeout 2400s; + client_header_timeout 2400s; + client_body_timeout 2400s; + proxy_connect_timeout 75s; + proxy_send_timeout 2400s; + proxy_buffer_size 32k; + proxy_buffers 40 32k; + proxy_busy_buffers_size 64k; + proxy_temp_file_write_size 250m; + proxy_http_version 1.1; + client_body_buffer_size 128k; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + log_format timing 'ip = $remote_addr ' + 'user = \"$remote_user\" ' + 'local_time = \"$time_local\" ' + 'host = $host ' + 'request = \"$request\" ' + 'status = $status ' + 'bytes = $body_bytes_sent ' + 'upstream = \"$upstream_addr\" ' + 'upstream_time = $upstream_response_time ' + 'request_time = $request_time ' + 'referer = \"$http_referer\" ' + 'UA = \"$http_user_agent\"'; + access_log {{ .Values.nginx.persistence.mountPath }}/logs/access.log timing; + sendfile on; + #tcp_nopush on; + keepalive_timeout 65; + #gzip on; + include {{ .Values.nginx.persistence.mountPath }}/conf.d/*.conf; + } + minAvailable: 0 + name: nginx + nodeSelector: {} + persistence: + accessMode: ReadWriteOnce + enabled: false + mountPath: /var/opt/jfrog/nginx + size: 5Gi + readinessProbe: + enabled: true + failureThreshold: 10 + initialDelaySeconds: 120 + path: /router/api/v1/system/health + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 10 + replicaCount: 1 + resources: {} + service: + externalTrafficPolicy: Cluster + labels: {} + loadBalancerIP: null + loadBalancerSourceRanges: [] + ssloffload: false + type: LoadBalancer + ssh: + externalPort: 1339 + internalPort: 1339 + tlsSecretName: OVERRIDE + tolerations: [] + uid: "1000720104" + postgresql: + common: + exampleValue: common-chart + global: + postgresql: {} + commonAnnotations: {} + enabled: false + extraEnv: [] + global: + postgresql: {} + image: + debug: false + pullPolicy: IfNotPresent + registry: docker.bintray.io + repository: bitnami/postgresql + tag: 12.3.0-debian-10-r71 + ldap: + baseDN: "" + bindDN: "" + enabled: false + port: "" + prefix: "" + scheme: "" + search_attr: "" + search_filter: "" + server: "" + suffix: "" + tls: false + url: "" + livenessProbe: + enabled: true + failureThreshold: 6 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + master: + affinity: {} + annotations: {} + extraInitContainers: [] + extraVolumeMounts: [] + extraVolumes: [] + labels: {} + nodeSelector: {} + podAnnotations: {} + podLabels: {} + priorityClassName: "" + service: {} + sidecars: [] + tolerations: [] + metrics: + enabled: false + extraEnvVars: {} + image: + pullPolicy: IfNotPresent + registry: docker.io + repository: bitnami/postgres-exporter + tag: 0.8.0-debian-10-r188 + livenessProbe: + enabled: true + failureThreshold: 6 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + prometheusRule: + additionalLabels: {} + enabled: false + namespace: "" + rules: [] + readinessProbe: + enabled: true + failureThreshold: 6 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + securityContext: + enabled: false + runAsUser: 1001 + service: + annotations: + prometheus.io/port: "9187" + prometheus.io/scrape: "true" + type: ClusterIP + serviceMonitor: + additionalLabels: {} + enabled: false + networkPolicy: + allowExternal: true + enabled: false + explicitNamespacesSelector: {} + persistence: + accessModes: + - ReadWriteOnce + annotations: {} + enabled: true + mountPath: /bitnami/postgresql + size: 50Gi + subPath: "" + postgresqlDataDir: /bitnami/postgresql/data + postgresqlDatabase: artifactory + postgresqlExtendedConf: + listenAddresses: '''*''' + maxConnections: "1500" + postgresqlPassword: "" + postgresqlUsername: artifactory + psp: + create: false + rbac: + create: false + readinessProbe: + enabled: true + failureThreshold: 6 + initialDelaySeconds: 5 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + replication: + applicationName: my_application + enabled: false + numSynchronousReplicas: 0 + password: repl_password + slaveReplicas: 1 + synchronousCommit: "off" + user: repl_user + resources: + requests: + cpu: 250m + memory: 256Mi + securityContext: + enabled: true + fsGroup: 1001 + runAsUser: 1001 + service: + annotations: {} + port: 5432 + type: ClusterIP + serviceAccount: + enabled: false + shmVolume: + chmod: + enabled: true + enabled: true + slave: + affinity: {} + annotations: {} + extraInitContainers: | + # - name: do-something + # image: busybox + # command: ['do', 'something'] + extraVolumeMounts: [] + extraVolumes: [] + labels: {} + nodeSelector: {} + persistence: + enabled: true + podAnnotations: {} + podLabels: {} + priorityClassName: "" + service: {} + sidecars: [] + tolerations: [] + tls: + certFilename: "" + certKeyFilename: "" + certificatesSecret: "" + enabled: false + preferServerCiphers: true + updateStrategy: + type: RollingUpdate + volumePermissions: + enabled: false + image: + pullPolicy: Always + registry: docker.io + repository: bitnami/minideb + tag: buster + securityContext: + runAsUser: 0 + rbac: + create: true + role: + rules: + - apiGroups: + - "" + resources: + - services + - endpoints + - pods + verbs: + - get + - watch + - list + serviceAccount: + annotations: {} + create: true + waitForDatabase: true + + diff --git a/Openshift4/operator/artifactory-ha-operator/config/samples/charts.helm.k8s.io_v1alpha1_openshiftartifactoryha_cr.yaml b/Openshift4/operator/artifactory-ha-operator/config/samples/charts.helm.k8s.io_v1alpha1_openshiftartifactoryha_cr.yaml new file mode 100644 index 0000000..3d68c69 --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/config/samples/charts.helm.k8s.io_v1alpha1_openshiftartifactoryha_cr.yaml @@ -0,0 +1,97 @@ +apiVersion: charts.helm.k8s.io/v1alpha1 +kind: OpenshiftArtifactoryHa +metadata: + name: openshiftartifactoryha +spec: + artifactory-ha: + database: + type: "OVERRIDE" + driver: "OVERRIDE" + url: "OVERRIDE" + user: "OVERRIDE" + password: "OVERRIDE" + initContainerImage: registry.connect.redhat.com/jfrog/init:1.0.1 + waitForDatabase: true + installerInfo: '{ "productId": "Openshift_artifactory-ha/{{ .Chart.Version }}", "features": [ { "featureId": "ArtifactoryVersion/{{ default .Chart.AppVersion .Values.artifactory.image.version }}" }, { "featureId": "{{ if .Values.postgresql.enabled }}postgresql{{ else }}{{ .Values.database.type }}{{ end }}/0.0.0" }, { "featureId": "Platform/Openshift" }, { "featureId": "Partner/ACC-006983" }, { "featureId": "Channel/Openshift" } ] }' + artifactory: + uid: "1000721030" + ## Change to use RH UBI images + image: + registry: registry.connect.redhat.com + repository: jfrog/artifactory-pro + tag: 7.9.0 + node: + replicaCount: 2 + waitForPrimaryStartup: + enabled: false + masterKey: "OVERRIDE" + joinKey: "OVERRIDE" + postgresql: + enabled: false + nginx: + uid: "1000720104" + gid: "1000720107" + image: + registry: registry.redhat.io + repository: rhel8/nginx-116 + tag: latest + ## K8S secret name for the TLS secret to be used for SSL + tlsSecretName: "OVERRIDE" + service: + ssloffload: false + http: + externalPort: 80 + internalPort: 8080 + https: + externalPort: 443 + internalPort: 8443 + mainConf: | + # Main Nginx configuration file + worker_processes 4; + error_log {{ .Values.nginx.persistence.mountPath }}/logs//error.log warn; + pid /tmp/nginx.pid; + events { + worker_connections 1024; + } + http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + variables_hash_max_size 1024; + variables_hash_bucket_size 64; + server_names_hash_max_size 4096; + server_names_hash_bucket_size 128; + types_hash_max_size 2048; + types_hash_bucket_size 64; + proxy_read_timeout 2400s; + client_header_timeout 2400s; + client_body_timeout 2400s; + proxy_connect_timeout 75s; + proxy_send_timeout 2400s; + proxy_buffer_size 32k; + proxy_buffers 40 32k; + proxy_busy_buffers_size 64k; + proxy_temp_file_write_size 250m; + proxy_http_version 1.1; + client_body_buffer_size 128k; + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + log_format timing 'ip = $remote_addr ' + 'user = \"$remote_user\" ' + 'local_time = \"$time_local\" ' + 'host = $host ' + 'request = \"$request\" ' + 'status = $status ' + 'bytes = $body_bytes_sent ' + 'upstream = \"$upstream_addr\" ' + 'upstream_time = $upstream_response_time ' + 'request_time = $request_time ' + 'referer = \"$http_referer\" ' + 'UA = \"$http_user_agent\"'; + access_log {{ .Values.nginx.persistence.mountPath }}/logs/access.log timing; + sendfile on; + #tcp_nopush on; + keepalive_timeout 65; + #gzip on; + include {{ .Values.nginx.persistence.mountPath }}/conf.d/*.conf; + } diff --git a/Openshift4/operator/artifactory-ha-operator/config/samples/kustomization.yaml b/Openshift4/operator/artifactory-ha-operator/config/samples/kustomization.yaml new file mode 100644 index 0000000..94bc7e6 --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/config/samples/kustomization.yaml @@ -0,0 +1,4 @@ +## Append samples you want in your CSV to this file as resources ## +resources: +- cache_v1alpha1_openshiftartifactoryha.yaml +# +kubebuilder:scaffold:manifestskustomizesamples diff --git a/Openshift4/operator/artifactory-ha-operator/watches.yaml b/Openshift4/operator/artifactory-ha-operator/watches.yaml index 5e71caa..d956392 100644 --- a/Openshift4/operator/artifactory-ha-operator/watches.yaml +++ b/Openshift4/operator/artifactory-ha-operator/watches.yaml @@ -5,4 +5,4 @@ chart: helm-charts/openshift-artifactory-ha overrideValues: artifactory-ha.artifactory.image.override: $RELATED_IMAGE_ARTIFACTORY_IMAGE_REPOSITORY - artifactory-ha.nginx.image.override: $RELATED_IMAGE_NGINX_IMAGE_REPOSITORY \ No newline at end of file + artifactory-ha.nginx.image.override: $RELATED_IMAGE_NGINX_IMAGE_REPOSITORY