From 1098936d6f4edc6e12f598f8e750cd6203a6e45d Mon Sep 17 00:00:00 2001 From: John Peterson Date: Fri, 23 Oct 2020 15:10:40 -0700 Subject: [PATCH 1/5] Openshift IaaS upgrades --- .../openshift-artifactory-ha/CHANGELOG.md | 3 + .../helm/openshift-artifactory-ha/Chart.yaml | 4 +- .../openshift-artifactory-ha/helminstall.sh | 12 +- .../openshift-artifactory-ha/helmupgrade.sh | 4 +- .../requirements.lock | 6 +- .../requirements.yaml | 2 +- .../helm/openshift-artifactory-ha/values.yaml | 4 +- Openshift4/helm/openshift-xray/CHANGELOG.md | 3 + Openshift4/helm/openshift-xray/Chart.yaml | 4 +- Openshift4/helm/openshift-xray/helminstall.sh | 8 +- .../openshift-xray/helmupgrade.sh} | 10 +- .../helm/openshift-xray/requirements.lock | 6 +- .../helm/openshift-xray/requirements.yaml | 2 +- Openshift4/helm/openshift-xray/values.yaml | 9 +- .../artifactory-ha-operator/CHANGELOG.md | 3 + ...operator.v1.1.2.clusterserviceversion.yaml | 396 +++++++++++++++ ...artifactoryhas.charts.helm.k8s.io.crd.yaml | 29 ++ .../bundle/1.1.2/metadata/annotations.yaml | 12 + ...enshiftartifactoryha-operator.package.yaml | 2 +- .../bundle/1.1.2/tests/scorecard/config.yaml | 43 ++ .../bundle/bundle-1.1.2.Dockerfile | 19 + .../openshift-artifactory-ha/CHANGELOG.md | 3 + .../openshift-artifactory-ha/Chart.yaml | 4 +- .../openshift-artifactory-ha/helminstall.sh | 12 +- .../openshift-artifactory-ha/helmupgrade.sh | 4 +- .../requirements.lock | 6 +- .../requirements.yaml | 2 +- .../openshift-artifactory-ha/values.yaml | 4 +- ...nshiftpipeline.charts.helm.k8s.io.crd.yaml | 0 ...perator.v1.0.0.clusterserviceversion.yaml} | 8 +- .../metadata/annotations.yaml | 0 .../openshiftpipeline-operator.package.yaml | 2 +- .../tests/scorecard/config.yaml | 0 ...1.1.Dockerfile => bundle-1.0.0.Dockerfile} | 5 +- .../operator/pipeline-operator/watches.yaml | 6 +- ...openshiftxrays.charts.helm.k8s.io.crd.yaml | 29 ++ ...operator.v1.1.2.clusterserviceversion.yaml | 463 ++++++++++++++++++ .../bundle/1.1.2/metadata/annotations.yaml | 12 + .../openshiftxray-operator.package.yaml | 5 + .../bundle/bundle-1.1.2.Dockerfile | 19 + .../helm-charts/openshift-xray/CHANGELOG.md | 3 + .../helm-charts/openshift-xray/Chart.yaml | 4 +- .../helm-charts/openshift-xray/rabbitmq.yaml | 25 - .../openshift-xray/rabbitmqservice.yaml | 26 - .../openshift-xray/requirements.lock | 6 +- .../openshift-xray/requirements.yaml | 2 +- .../helm-charts/openshift-xray/values.yaml | 24 +- .../operator/xray-operator/watches.yaml | 8 + 48 files changed, 1143 insertions(+), 120 deletions(-) rename Openshift4/{operator/xray-operator/helm-charts/openshift-xray/helminstall.sh => helm/openshift-xray/helmupgrade.sh} (84%) create mode 100644 Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/manifests/artifactory-ha-operator.v1.1.2.clusterserviceversion.yaml create mode 100644 Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/manifests/openshiftartifactoryhas.charts.helm.k8s.io.crd.yaml create mode 100644 Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/metadata/annotations.yaml rename Openshift4/operator/artifactory-ha-operator/bundle/{ => 1.1.2/metadata}/openshiftartifactoryha-operator.package.yaml (66%) create mode 100644 Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/tests/scorecard/config.yaml create mode 100644 Openshift4/operator/artifactory-ha-operator/bundle/bundle-1.1.2.Dockerfile rename Openshift4/operator/pipeline-operator/bundle/{1.1.1 => 1.0.0}/manifests/openshiftpipeline.charts.helm.k8s.io.crd.yaml (100%) rename Openshift4/operator/pipeline-operator/bundle/{1.1.1/manifests/pipeline-operator.v1.1.1.clusterserviceversion.yaml => 1.0.0/manifests/pipeline-operator.v1.0.0.clusterserviceversion.yaml} (99%) rename Openshift4/operator/pipeline-operator/bundle/{1.1.1 => 1.0.0}/metadata/annotations.yaml (100%) rename Openshift4/operator/pipeline-operator/bundle/{1.1.1 => 1.0.0}/metadata/openshiftpipeline-operator.package.yaml (68%) rename Openshift4/operator/pipeline-operator/bundle/{1.1.1 => 1.0.0}/tests/scorecard/config.yaml (100%) rename Openshift4/operator/pipeline-operator/bundle/{bundle-1.1.1.Dockerfile => bundle-1.0.0.Dockerfile} (91%) create mode 100644 Openshift4/operator/xray-operator/bundle/1.1.2/manifests/openshiftxrays.charts.helm.k8s.io.crd.yaml create mode 100644 Openshift4/operator/xray-operator/bundle/1.1.2/manifests/xray-operator.v1.1.2.clusterserviceversion.yaml create mode 100644 Openshift4/operator/xray-operator/bundle/1.1.2/metadata/annotations.yaml create mode 100644 Openshift4/operator/xray-operator/bundle/1.1.2/metadata/openshiftxray-operator.package.yaml create mode 100644 Openshift4/operator/xray-operator/bundle/bundle-1.1.2.Dockerfile delete mode 100644 Openshift4/operator/xray-operator/helm-charts/openshift-xray/rabbitmq.yaml delete mode 100644 Openshift4/operator/xray-operator/helm-charts/openshift-xray/rabbitmqservice.yaml diff --git a/Openshift4/helm/openshift-artifactory-ha/CHANGELOG.md b/Openshift4/helm/openshift-artifactory-ha/CHANGELOG.md index 0175b11..191e736 100755 --- a/Openshift4/helm/openshift-artifactory-ha/CHANGELOG.md +++ b/Openshift4/helm/openshift-artifactory-ha/CHANGELOG.md @@ -1,6 +1,9 @@ # JFrog Openshift Artifactory-ha Chart Changelog All changes to this chart will be documented in this file. +## [4.4.1] - Oct 22, 2020 +* Updating to latest jfrog/artifactory-ha helm chart version 4.4.1 artifactory version 7.10.2 + ## [4.2.0] - Oct 6, 2020 * Fixed upgrade path from 3.1.0 to 4.2.0 * Updating to latest jfrog/artifactory-ha helm chart version 4.2.0 artifactory version 7.9.0 diff --git a/Openshift4/helm/openshift-artifactory-ha/Chart.yaml b/Openshift4/helm/openshift-artifactory-ha/Chart.yaml index a5b536a..67353a1 100755 --- a/Openshift4/helm/openshift-artifactory-ha/Chart.yaml +++ b/Openshift4/helm/openshift-artifactory-ha/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: 7.9.0 +appVersion: 7.10.2 description: Openshift JFrog Artifactory HA subcharting Artifactory HA to work in Openshift environment home: https://www.jfrog.com/artifactory/ icon: https://raw.githubusercontent.com/jfrog/charts/master/stable/artifactory-ha/logo/artifactory-logo.png @@ -16,4 +16,4 @@ name: openshift-artifactory-ha sources: - https://bintray.com/jfrog/product/JFrog-Artifactory-Pro/view - https://github.com/jfrog/charts -version: 4.2.0 +version: 4.4.1 diff --git a/Openshift4/helm/openshift-artifactory-ha/helminstall.sh b/Openshift4/helm/openshift-artifactory-ha/helminstall.sh index 09e060d..e9210a6 100755 --- a/Openshift4/helm/openshift-artifactory-ha/helminstall.sh +++ b/Openshift4/helm/openshift-artifactory-ha/helminstall.sh @@ -41,6 +41,9 @@ else fi fi +MASTER_KEY=$(openssl rand -hex 32) +JOIN_KEY=$(openssl rand -hex 32) + # install via helm with default postgresql configuration helm install artifactory-ha . \ --set artifactory-ha.nginx.service.ssloffload=true \ @@ -52,6 +55,11 @@ helm install artifactory-ha . \ --set artifactory-ha.database.url=jdbc:postgresql://postgres-postgresql:5432/artifactory \ --set artifactory-ha.database.user=artifactory \ --set artifactory-ha.database.password=password \ - --set artifactory-ha.artifactory.joinKey=EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE \ - --set artifactory-ha.artifactory.masterKey=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + --set artifactory-ha.artifactory.joinKey=$JOIN_KEY \ + --set artifactory-ha.artifactory.masterKey=$MASTER_KEY + +echo "*** IMPORTANT ****" +echo "export MASTER_KEY=$MASTER_KEY" +echo "export JOIN_KEY=$JOIN_KEY" +echo "*** SUCCESS ****" diff --git a/Openshift4/helm/openshift-artifactory-ha/helmupgrade.sh b/Openshift4/helm/openshift-artifactory-ha/helmupgrade.sh index a0f83ff..09fb776 100755 --- a/Openshift4/helm/openshift-artifactory-ha/helmupgrade.sh +++ b/Openshift4/helm/openshift-artifactory-ha/helmupgrade.sh @@ -11,7 +11,7 @@ helm upgrade --install artifactory-ha . \ --set artifactory-ha.database.url=jdbc:postgresql://postgres-postgresql:5432/artifactory \ --set artifactory-ha.database.user=artifactory \ --set artifactory-ha.database.password=password \ - --set artifactory-ha.artifactory.joinKey=EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE \ - --set artifactory-ha.artifactory.masterKey=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF \ + --set artifactory-ha.artifactory.joinKey=$JOIN_KEY \ + --set artifactory-ha.artifactory.masterKey=$MASTER_KEY \ --set artifactory-ha.databaseUpgradeReady=true diff --git a/Openshift4/helm/openshift-artifactory-ha/requirements.lock b/Openshift4/helm/openshift-artifactory-ha/requirements.lock index 161561a..fb85a38 100644 --- a/Openshift4/helm/openshift-artifactory-ha/requirements.lock +++ b/Openshift4/helm/openshift-artifactory-ha/requirements.lock @@ -1,6 +1,6 @@ dependencies: - name: artifactory-ha repository: https://charts.jfrog.io/ - version: 4.2.0 -digest: sha256:c5d4c457266ce8d7e0e8c6dcf326267c3ca4cbb8a03c81db68a8a0b45fde3d3e -generated: "2020-10-06T15:10:01.551465-07:00" + version: 4.4.1 +digest: sha256:36d606673a7c0e6ae47e615c90d5df7e203c75e574da6d5166ed0ebf8bb8e44c +generated: "2020-10-22T12:12:43.277532-07:00" diff --git a/Openshift4/helm/openshift-artifactory-ha/requirements.yaml b/Openshift4/helm/openshift-artifactory-ha/requirements.yaml index 89466d5..350a272 100644 --- a/Openshift4/helm/openshift-artifactory-ha/requirements.yaml +++ b/Openshift4/helm/openshift-artifactory-ha/requirements.yaml @@ -1,4 +1,4 @@ dependencies: - name: artifactory-ha - version: 4.2.0 + version: 4.4.1 repository: https://charts.jfrog.io/ diff --git a/Openshift4/helm/openshift-artifactory-ha/values.yaml b/Openshift4/helm/openshift-artifactory-ha/values.yaml index a201a72..5cd872e 100755 --- a/Openshift4/helm/openshift-artifactory-ha/values.yaml +++ b/Openshift4/helm/openshift-artifactory-ha/values.yaml @@ -10,7 +10,7 @@ artifactory-ha: url: "OVERRIDE" user: "OVERRIDE" password: "OVERRIDE" - initContainerImage: registry.connect.redhat.com/jfrog/init:1.0.1 + initContainerImage: registry.connect.redhat.com/jfrog/init:7.10.2-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: @@ -19,7 +19,7 @@ artifactory-ha: image: registry: registry.connect.redhat.com repository: jfrog/artifactory-pro - tag: 7.9.0 + tag: 7.10.2-1 node: replicaCount: 2 waitForPrimaryStartup: diff --git a/Openshift4/helm/openshift-xray/CHANGELOG.md b/Openshift4/helm/openshift-xray/CHANGELOG.md index a4c6f3b..09067a3 100755 --- a/Openshift4/helm/openshift-xray/CHANGELOG.md +++ b/Openshift4/helm/openshift-xray/CHANGELOG.md @@ -1,6 +1,9 @@ # JFrog Openshift Artifactory-Xray Chart Changelog All changes to this chart will be documented in this file. +## [6.1.2] Oct 22nd, 2020 +* Updating to Xray chart version 6.1.2 and Xray app version 3.9.1 + ## [6.0.6] Oct 1st, 2020 * Updating to Xray chart version 6.0.6 and Xray app version 3.8.8 diff --git a/Openshift4/helm/openshift-xray/Chart.yaml b/Openshift4/helm/openshift-xray/Chart.yaml index aa8c6b6..51784ef 100755 --- a/Openshift4/helm/openshift-xray/Chart.yaml +++ b/Openshift4/helm/openshift-xray/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: 3.8.8 +appVersion: 3.9.1 description: Universal component scan for security and license inventory and impact analysis sources: - https://bintray.com/jfrog/product/xray/view @@ -13,4 +13,4 @@ maintainers: - email: johnp@jfrog.com name: John Peterson name: openshift-xray -version: 6.0.6 +version: 6.1.2 diff --git a/Openshift4/helm/openshift-xray/helminstall.sh b/Openshift4/helm/openshift-xray/helminstall.sh index c488669..55e471e 100755 --- a/Openshift4/helm/openshift-xray/helminstall.sh +++ b/Openshift4/helm/openshift-xray/helminstall.sh @@ -58,9 +58,9 @@ JFROGURL="" if [[ -z "$4" ]] then # HELM - JFROGURL="http://artifactory-ha-nginx" + #JFROGURL="http://artifactory-ha-nginx" # OPERATOR - #JFROGURL="http://openshiftartifactoryha-nginx" + JFROGURL="http://openshiftartifactoryha-nginx" else JFROGURL=$4 fi @@ -72,5 +72,5 @@ helm install xray . \ --set xray.database.user=$DBUSER \ --set xray.database.password=$DBPASS \ --set xray.xray.jfrogUrl=$JFROGURL \ - --set xray.xray.joinKey=EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE \ - --set xray.xray.masterKey=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + --set xray.xray.joinKey=$JOIN_KEY \ + --set xray.xray.masterKey=$MASTER_KEY diff --git a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/helminstall.sh b/Openshift4/helm/openshift-xray/helmupgrade.sh similarity index 84% rename from Openshift4/operator/xray-operator/helm-charts/openshift-xray/helminstall.sh rename to Openshift4/helm/openshift-xray/helmupgrade.sh index e19987c..54ed23d 100755 --- a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/helminstall.sh +++ b/Openshift4/helm/openshift-xray/helmupgrade.sh @@ -58,19 +58,19 @@ JFROGURL="" if [[ -z "$4" ]] then # HELM - JFROGURL="http://artifactory-ha-nginx" + #JFROGURL="http://artifactory-ha-nginx" # OPERATOR - # JFROGURL="http://openshiftartifactoryha-nginx" + JFROGURL="http://openshiftartifactoryha-nginx" else JFROGURL=$4 fi # install via helm with default postgresql configuration -helm install xray . \ +helm upgrade --install xray . \ --set xray.database.url=$DBURL \ --set xray.database.user=$DBUSER \ --set xray.database.password=$DBPASS \ --set xray.xray.jfrogUrl=$JFROGURL \ - --set xray.xray.joinKey=EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE \ - --set xray.xray.masterKey=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + --set xray.xray.joinKey=$JOIN_KEY \ + --set xray.xray.masterKey=$MASTER_KEY diff --git a/Openshift4/helm/openshift-xray/requirements.lock b/Openshift4/helm/openshift-xray/requirements.lock index d53cf7c..de38552 100644 --- a/Openshift4/helm/openshift-xray/requirements.lock +++ b/Openshift4/helm/openshift-xray/requirements.lock @@ -1,6 +1,6 @@ dependencies: - name: xray repository: https://charts.jfrog.io/ - version: 6.0.6 -digest: sha256:339b5ec4e309ce2970ed34ebc700d6fe8f436d6cbe8dd5d352f0b080401752af -generated: "2020-10-01T15:04:29.008985-07:00" + version: 6.2.1 +digest: sha256:7bce8744ad24ebe2d962738cb688412c44c200b0b0015afb4471df479d826fde +generated: "2020-10-23T12:58:46.07336-07:00" diff --git a/Openshift4/helm/openshift-xray/requirements.yaml b/Openshift4/helm/openshift-xray/requirements.yaml index f6311b7..276689d 100644 --- a/Openshift4/helm/openshift-xray/requirements.yaml +++ b/Openshift4/helm/openshift-xray/requirements.yaml @@ -1,4 +1,4 @@ dependencies: - name: xray - version: 6.0.6 + version: 6.2.1 repository: https://charts.jfrog.io/ diff --git a/Openshift4/helm/openshift-xray/values.yaml b/Openshift4/helm/openshift-xray/values.yaml index ab9d4c7..fcb1656 100755 --- a/Openshift4/helm/openshift-xray/values.yaml +++ b/Openshift4/helm/openshift-xray/values.yaml @@ -17,6 +17,7 @@ xray: common: xrayUserId: "1000721035" xrayGroupId: "1000721035" + xrayVersion: "3.10.3-1" customInitContainers: | - name: "prepare-uid-persistent-volume" image: "{{ .Values.initContainerImage }}" @@ -36,7 +37,6 @@ xray: image: registry: registry.connect.redhat.com repository: jfrog/xray-analysis - tag: 3.8.8 updateStrategy: RollingUpdate podManagementPolicy: Parallel preStartCommand: @@ -45,7 +45,6 @@ xray: image: registry: registry.connect.redhat.com repository: jfrog/xray-indexer - tag: 3.8.8 updateStrategy: RollingUpdate podManagementPolicy: Parallel persist: @@ -53,7 +52,6 @@ xray: image: registry: registry.connect.redhat.com repository: jfrog/xray-persist - tag: 3.8.8 updateStrategy: RollingUpdate podManagementPolicy: Parallel persistence: @@ -64,7 +62,6 @@ xray: image: registry: registry.connect.redhat.com repository: jfrog/xray-server - tag: 3.8.8 updateStrategy: RollingUpdate podManagementPolicy: Parallel replicaCount: 1 @@ -73,14 +70,14 @@ xray: image: registry: registry.connect.redhat.com repository: jfrog/xray-router - tag: 1.4.3 imagePullPolicy: IfNotPresent + tag: 3.10.3-1 rabbitmq-ha: enabled: true replicaCount: 1 image: repository: registry.connect.redhat.com/jfrog/xray-rabbitmq - tag: 3.8.9 + tag: 3.10.3-1 rabbitmqEpmdPort: 4369 rabbitmqNodePort: 5672 rabbitmqManagerPort: 15672 diff --git a/Openshift4/operator/artifactory-ha-operator/CHANGELOG.md b/Openshift4/operator/artifactory-ha-operator/CHANGELOG.md index 391de7e..3d8bd43 100755 --- a/Openshift4/operator/artifactory-ha-operator/CHANGELOG.md +++ b/Openshift4/operator/artifactory-ha-operator/CHANGELOG.md @@ -1,6 +1,9 @@ # JFrog Openshift Artifactory-ha Chart Changelog All changes to this chart will be documented in this file. +## [1.1.2] - Oct 22, 2020 +* Updating Operator to latest jfrog/artifactory-ha helm chart version 4.4.1 artifactory version 7.10.2 + ## [1.1.1] - Oct 6, 2020 * Upgrade path fixed for both operator version 1.0.3 and 1.1.0 * Updating Operator to latest jfrog/artifactory-ha helm chart version 4.2.0 artifactory version 7.9.0 diff --git a/Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/manifests/artifactory-ha-operator.v1.1.2.clusterserviceversion.yaml b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/manifests/artifactory-ha-operator.v1.1.2.clusterserviceversion.yaml new file mode 100644 index 0000000..eaba5a7 --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/manifests/artifactory-ha-operator.v1.1.2.clusterserviceversion.yaml @@ -0,0 +1,396 @@ +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.10.2-1" + }, + "joinKey": "OVERRIDE", + "masterKey": "OVERRIDE", + "uid": "1000721030", + "node": { + "replicaCount": 2, + "waitForPrimaryStartup": { + "enabled": false + } + } + }, + "databaseUpgradeReady": true, + "database": { + "driver": "OVERRIDE", + "password": "OVERRIDE", + "type": "OVERRIDE", + "url": "OVERRIDE", + "user": "OVERRIDE" + }, + "initContainerImage": "registry.connect.redhat.com/jfrog/init:7.10.2-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.10.2 + 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.2 + 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. + + ## Security Context Constraints + + To deploy this helm chart you will need to be a cluster admin w/ access to the anyuid scc and add the operator service account to the anyuid scc. + + + ``` + + oc adm policy add-scc-to-user anyuid -z artifactory-ha-operator + + ``` + + + ## 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.10.2-1 + - name: RELATED_IMAGE_NGINX_IMAGE_REPOSITORY + value: registry.redhat.io/rhel8/nginx-116:latest + image: registry.connect.redhat.com/jfrog/artifactory-operator:7.10.2 + 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: + - 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.1.1 + version: 1.1.2 +status: + certsLastUpdated: null + certsRotateAt: null + lastTransitionTime: null + lastUpdateTime: null diff --git a/Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/manifests/openshiftartifactoryhas.charts.helm.k8s.io.crd.yaml b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/manifests/openshiftartifactoryhas.charts.helm.k8s.io.crd.yaml new file mode 100644 index 0000000..f312d8c --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/manifests/openshiftartifactoryhas.charts.helm.k8s.io.crd.yaml @@ -0,0 +1,29 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + 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 + version: v1alpha1 + versions: + - name: v1alpha1 + served: true + storage: true +status: + acceptedNames: + kind: '' + plural: '' + conditions: null + storedVersions: null diff --git a/Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/metadata/annotations.yaml b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/metadata/annotations.yaml new file mode 100644 index 0000000..8994ddd --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/metadata/annotations.yaml @@ -0,0 +1,12 @@ +annotations: + operators.operatorframework.io.bundle.channel.default.v1: alpha + operators.operatorframework.io.bundle.channels.v1: alpha + operators.operatorframework.io.bundle.manifests.v1: manifests/ + operators.operatorframework.io.bundle.mediatype.v1: registry+v1 + operators.operatorframework.io.bundle.metadata.v1: metadata/ + operators.operatorframework.io.bundle.package.v1: openshiftartifactoryha-operator + operators.operatorframework.io.metrics.builder: operator-sdk-v1.0.1 + operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 + operators.operatorframework.io.metrics.project_layout: helm.sdk.operatorframework.io/v1 + operators.operatorframework.io.test.config.v1: tests/scorecard/ + operators.operatorframework.io.test.mediatype.v1: scorecard+v1 \ No newline at end of file diff --git a/Openshift4/operator/artifactory-ha-operator/bundle/openshiftartifactoryha-operator.package.yaml b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/metadata/openshiftartifactoryha-operator.package.yaml similarity index 66% rename from Openshift4/operator/artifactory-ha-operator/bundle/openshiftartifactoryha-operator.package.yaml rename to Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/metadata/openshiftartifactoryha-operator.package.yaml index 397bc5c..08fb784 100644 --- a/Openshift4/operator/artifactory-ha-operator/bundle/openshiftartifactoryha-operator.package.yaml +++ b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/metadata/openshiftartifactoryha-operator.package.yaml @@ -1,5 +1,5 @@ channels: -- currentCSV: artifactory-ha-operator.v1.1.1 +- currentCSV: artifactory-ha-operator.v1.1.2 name: alpha defaultChannel: '' packageName: openshiftartifactoryha-operator diff --git a/Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/tests/scorecard/config.yaml b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/tests/scorecard/config.yaml new file mode 100644 index 0000000..7f704f3 --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/bundle/1.1.2/tests/scorecard/config.yaml @@ -0,0 +1,43 @@ +kind: Configuration +apiversion: scorecard.operatorframework.io/v1alpha3 +metadata: + name: config +stages: +- parallel: true + tests: + - image: quay.io/operator-framework/scorecard-test:latest + entrypoint: + - scorecard-test + - basic-check-spec + labels: + suite: basic + test: basic-check-spec-test + - image: quay.io/operator-framework/scorecard-test:latest + entrypoint: + - scorecard-test + - olm-bundle-validation + labels: + suite: olm + test: olm-bundle-validation-test + - image: quay.io/operator-framework/scorecard-test:latest + entrypoint: + - scorecard-test + - olm-crds-have-validation + labels: + suite: olm + test: olm-crds-have-validation-test + - image: quay.io/operator-framework/scorecard-test:latest + entrypoint: + - scorecard-test + - olm-crds-have-resources + labels: + suite: olm + test: olm-crds-have-resources-test + - image: quay.io/operator-framework/scorecard-test:latest + entrypoint: + - scorecard-test + - olm-spec-descriptors + labels: + suite: olm + test: olm-spec-descriptors-test + diff --git a/Openshift4/operator/artifactory-ha-operator/bundle/bundle-1.1.2.Dockerfile b/Openshift4/operator/artifactory-ha-operator/bundle/bundle-1.1.2.Dockerfile new file mode 100644 index 0000000..94a4e77 --- /dev/null +++ b/Openshift4/operator/artifactory-ha-operator/bundle/bundle-1.1.2.Dockerfile @@ -0,0 +1,19 @@ +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.metrics.builder=operator-sdk-v1.0.1 +LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 +LABEL operators.operatorframework.io.metrics.project_layout=helm.sdk.operatorframework.io/v1 +LABEL operators.operatorframework.io.test.config.v1=tests/scorecard/ +LABEL operators.operatorframework.io.test.mediatype.v1=scorecard+v1 + +COPY 1.1.2/manifests /manifests/ +COPY 1.1.2/metadata /metadata/ +LABEL com.redhat.openshift.versions="v4.5,v4.6" +LABEL com.redhat.delivery.operator.bundle=true +LABEL com.redhat.delivery.backport=true diff --git a/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/CHANGELOG.md b/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/CHANGELOG.md index 0175b11..191e736 100755 --- a/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/CHANGELOG.md +++ b/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/CHANGELOG.md @@ -1,6 +1,9 @@ # JFrog Openshift Artifactory-ha Chart Changelog All changes to this chart will be documented in this file. +## [4.4.1] - Oct 22, 2020 +* Updating to latest jfrog/artifactory-ha helm chart version 4.4.1 artifactory version 7.10.2 + ## [4.2.0] - Oct 6, 2020 * Fixed upgrade path from 3.1.0 to 4.2.0 * Updating to latest jfrog/artifactory-ha helm chart version 4.2.0 artifactory version 7.9.0 diff --git a/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/Chart.yaml b/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/Chart.yaml index a5b536a..67353a1 100755 --- a/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/Chart.yaml +++ b/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: 7.9.0 +appVersion: 7.10.2 description: Openshift JFrog Artifactory HA subcharting Artifactory HA to work in Openshift environment home: https://www.jfrog.com/artifactory/ icon: https://raw.githubusercontent.com/jfrog/charts/master/stable/artifactory-ha/logo/artifactory-logo.png @@ -16,4 +16,4 @@ name: openshift-artifactory-ha sources: - https://bintray.com/jfrog/product/JFrog-Artifactory-Pro/view - https://github.com/jfrog/charts -version: 4.2.0 +version: 4.4.1 diff --git a/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/helminstall.sh b/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/helminstall.sh index 09e060d..e9210a6 100755 --- a/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/helminstall.sh +++ b/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/helminstall.sh @@ -41,6 +41,9 @@ else fi fi +MASTER_KEY=$(openssl rand -hex 32) +JOIN_KEY=$(openssl rand -hex 32) + # install via helm with default postgresql configuration helm install artifactory-ha . \ --set artifactory-ha.nginx.service.ssloffload=true \ @@ -52,6 +55,11 @@ helm install artifactory-ha . \ --set artifactory-ha.database.url=jdbc:postgresql://postgres-postgresql:5432/artifactory \ --set artifactory-ha.database.user=artifactory \ --set artifactory-ha.database.password=password \ - --set artifactory-ha.artifactory.joinKey=EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE \ - --set artifactory-ha.artifactory.masterKey=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + --set artifactory-ha.artifactory.joinKey=$JOIN_KEY \ + --set artifactory-ha.artifactory.masterKey=$MASTER_KEY + +echo "*** IMPORTANT ****" +echo "export MASTER_KEY=$MASTER_KEY" +echo "export JOIN_KEY=$JOIN_KEY" +echo "*** SUCCESS ****" diff --git a/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/helmupgrade.sh b/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/helmupgrade.sh index a0f83ff..09fb776 100755 --- a/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/helmupgrade.sh +++ b/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/helmupgrade.sh @@ -11,7 +11,7 @@ helm upgrade --install artifactory-ha . \ --set artifactory-ha.database.url=jdbc:postgresql://postgres-postgresql:5432/artifactory \ --set artifactory-ha.database.user=artifactory \ --set artifactory-ha.database.password=password \ - --set artifactory-ha.artifactory.joinKey=EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE \ - --set artifactory-ha.artifactory.masterKey=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF \ + --set artifactory-ha.artifactory.joinKey=$JOIN_KEY \ + --set artifactory-ha.artifactory.masterKey=$MASTER_KEY \ --set artifactory-ha.databaseUpgradeReady=true diff --git a/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/requirements.lock b/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/requirements.lock index 161561a..fb85a38 100644 --- a/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/requirements.lock +++ b/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/requirements.lock @@ -1,6 +1,6 @@ dependencies: - name: artifactory-ha repository: https://charts.jfrog.io/ - version: 4.2.0 -digest: sha256:c5d4c457266ce8d7e0e8c6dcf326267c3ca4cbb8a03c81db68a8a0b45fde3d3e -generated: "2020-10-06T15:10:01.551465-07:00" + version: 4.4.1 +digest: sha256:36d606673a7c0e6ae47e615c90d5df7e203c75e574da6d5166ed0ebf8bb8e44c +generated: "2020-10-22T12:12:43.277532-07:00" diff --git a/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/requirements.yaml b/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/requirements.yaml index 89466d5..350a272 100644 --- a/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/requirements.yaml +++ b/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/requirements.yaml @@ -1,4 +1,4 @@ dependencies: - name: artifactory-ha - version: 4.2.0 + version: 4.4.1 repository: https://charts.jfrog.io/ diff --git a/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/values.yaml b/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/values.yaml index a201a72..5cd872e 100755 --- a/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/values.yaml +++ b/Openshift4/operator/artifactory-ha-operator/helm-charts/openshift-artifactory-ha/values.yaml @@ -10,7 +10,7 @@ artifactory-ha: url: "OVERRIDE" user: "OVERRIDE" password: "OVERRIDE" - initContainerImage: registry.connect.redhat.com/jfrog/init:1.0.1 + initContainerImage: registry.connect.redhat.com/jfrog/init:7.10.2-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: @@ -19,7 +19,7 @@ artifactory-ha: image: registry: registry.connect.redhat.com repository: jfrog/artifactory-pro - tag: 7.9.0 + tag: 7.10.2-1 node: replicaCount: 2 waitForPrimaryStartup: diff --git a/Openshift4/operator/pipeline-operator/bundle/1.1.1/manifests/openshiftpipeline.charts.helm.k8s.io.crd.yaml b/Openshift4/operator/pipeline-operator/bundle/1.0.0/manifests/openshiftpipeline.charts.helm.k8s.io.crd.yaml similarity index 100% rename from Openshift4/operator/pipeline-operator/bundle/1.1.1/manifests/openshiftpipeline.charts.helm.k8s.io.crd.yaml rename to Openshift4/operator/pipeline-operator/bundle/1.0.0/manifests/openshiftpipeline.charts.helm.k8s.io.crd.yaml diff --git a/Openshift4/operator/pipeline-operator/bundle/1.1.1/manifests/pipeline-operator.v1.1.1.clusterserviceversion.yaml b/Openshift4/operator/pipeline-operator/bundle/1.0.0/manifests/pipeline-operator.v1.0.0.clusterserviceversion.yaml similarity index 99% rename from Openshift4/operator/pipeline-operator/bundle/1.1.1/manifests/pipeline-operator.v1.1.1.clusterserviceversion.yaml rename to Openshift4/operator/pipeline-operator/bundle/1.0.0/manifests/pipeline-operator.v1.0.0.clusterserviceversion.yaml index d8345ca..118f4bf 100644 --- a/Openshift4/operator/pipeline-operator/bundle/1.1.1/manifests/pipeline-operator.v1.1.1.clusterserviceversion.yaml +++ b/Openshift4/operator/pipeline-operator/bundle/1.0.0/manifests/pipeline-operator.v1.0.0.clusterserviceversion.yaml @@ -167,13 +167,13 @@ metadata: capabilities: Seamless Upgrades categories: Developer Tools,Integration & Delivery certified: 'true' - containerImage: registry.connect.redhat.com/jfrog/pipelines-operator:1.8 + containerImage: registry.connect.redhat.com/jfrog/pipelines-operator:1.8.1 createdAt: 2020-10-09 00:00:00+00:00 description: JFrog Pipeline Enterprise deploys Pipeline CI/CD Openshift (Requires Jfrog Artifactory) repository: https://github.com/jfrog/JFrog-Cloud-Installers/tree/openshift4/Openshift4 support: JFrog creationTimestamp: null - name: pipeline-operator.v1.1.1 + name: pipeline-operator.v1.0.0 namespace: default spec: apiservicedefinitions: {} @@ -349,7 +349,7 @@ spec: value: registry.connect.redhat.com/jfrog/pipelines-vault-init:1.8.0 - name: RELATED_IMAGE_PIPELINE_VAULT_IMAGE_REPOSITORY value: registry.connect.redhat.com/jfrog/pipelines-vault:1.8.0 - image: registry.connect.redhat.com/jfrog/pipelines-operator:1.8 + image: registry.connect.redhat.com/jfrog/pipelines-operator:1.8.1 imagePullPolicy: Always name: pipeline-operator resources: {} @@ -512,7 +512,7 @@ spec: maturity: alpha provider: name: JFrog - version: 1.1.1 + version: 1.0.0 status: certsLastUpdated: null certsRotateAt: null diff --git a/Openshift4/operator/pipeline-operator/bundle/1.1.1/metadata/annotations.yaml b/Openshift4/operator/pipeline-operator/bundle/1.0.0/metadata/annotations.yaml similarity index 100% rename from Openshift4/operator/pipeline-operator/bundle/1.1.1/metadata/annotations.yaml rename to Openshift4/operator/pipeline-operator/bundle/1.0.0/metadata/annotations.yaml diff --git a/Openshift4/operator/pipeline-operator/bundle/1.1.1/metadata/openshiftpipeline-operator.package.yaml b/Openshift4/operator/pipeline-operator/bundle/1.0.0/metadata/openshiftpipeline-operator.package.yaml similarity index 68% rename from Openshift4/operator/pipeline-operator/bundle/1.1.1/metadata/openshiftpipeline-operator.package.yaml rename to Openshift4/operator/pipeline-operator/bundle/1.0.0/metadata/openshiftpipeline-operator.package.yaml index 39830f1..3d94fb8 100644 --- a/Openshift4/operator/pipeline-operator/bundle/1.1.1/metadata/openshiftpipeline-operator.package.yaml +++ b/Openshift4/operator/pipeline-operator/bundle/1.0.0/metadata/openshiftpipeline-operator.package.yaml @@ -1,5 +1,5 @@ channels: -- currentCSV: pipeline-operator.v1.1.1 +- currentCSV: pipeline-operator.v1.0.0 name: alpha defaultChannel: '' packageName: openshiftpipeline-operator diff --git a/Openshift4/operator/pipeline-operator/bundle/1.1.1/tests/scorecard/config.yaml b/Openshift4/operator/pipeline-operator/bundle/1.0.0/tests/scorecard/config.yaml similarity index 100% rename from Openshift4/operator/pipeline-operator/bundle/1.1.1/tests/scorecard/config.yaml rename to Openshift4/operator/pipeline-operator/bundle/1.0.0/tests/scorecard/config.yaml diff --git a/Openshift4/operator/pipeline-operator/bundle/bundle-1.1.1.Dockerfile b/Openshift4/operator/pipeline-operator/bundle/bundle-1.0.0.Dockerfile similarity index 91% rename from Openshift4/operator/pipeline-operator/bundle/bundle-1.1.1.Dockerfile rename to Openshift4/operator/pipeline-operator/bundle/bundle-1.0.0.Dockerfile index c7c0f11..86b6ede 100644 --- a/Openshift4/operator/pipeline-operator/bundle/bundle-1.1.1.Dockerfile +++ b/Openshift4/operator/pipeline-operator/bundle/bundle-1.0.0.Dockerfile @@ -12,9 +12,8 @@ LABEL operators.operatorframework.io.metrics.project_layout=helm.sdk.operatorfra LABEL operators.operatorframework.io.test.config.v1=tests/scorecard/ LABEL operators.operatorframework.io.test.mediatype.v1=scorecard+v1 -COPY 1.1.1/manifests /manifests/ -COPY 1.1.1/metadata /metadata/ -COPY 1.1.1/tests /tests/ +COPY 1.0.0/manifests /manifests/ +COPY 1.0.0/metadata /metadata/ LABEL com.redhat.openshift.versions="v4.5,v4.6" LABEL com.redhat.delivery.operator.bundle=true LABEL com.redhat.delivery.backport=true diff --git a/Openshift4/operator/pipeline-operator/watches.yaml b/Openshift4/operator/pipeline-operator/watches.yaml index 5343af8..0063334 100644 --- a/Openshift4/operator/pipeline-operator/watches.yaml +++ b/Openshift4/operator/pipeline-operator/watches.yaml @@ -1,6 +1,6 @@ -# Use the 'create api' subcommand to add watches to this file. -- group: charts.helm.k8s.io - version: v1alpha1 +--- +- version: v1alpha1 + group: charts.helm.k8s.io kind: OpenshiftPipelines chart: helm-charts/openshift-pipelines # +kubebuilder:scaffold:watch diff --git a/Openshift4/operator/xray-operator/bundle/1.1.2/manifests/openshiftxrays.charts.helm.k8s.io.crd.yaml b/Openshift4/operator/xray-operator/bundle/1.1.2/manifests/openshiftxrays.charts.helm.k8s.io.crd.yaml new file mode 100644 index 0000000..e956a17 --- /dev/null +++ b/Openshift4/operator/xray-operator/bundle/1.1.2/manifests/openshiftxrays.charts.helm.k8s.io.crd.yaml @@ -0,0 +1,29 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + creationTimestamp: null + name: openshiftxrays.charts.helm.k8s.io +spec: + group: charts.helm.k8s.io + names: + kind: OpenshiftXray + listKind: OpenshiftXrayList + plural: openshiftxrays + singular: openshiftxray + scope: Namespaced + subresources: + status: {} + validation: + openAPIV3Schema: + type: object + version: v1alpha1 + versions: + - name: v1alpha1 + served: true + storage: true +status: + acceptedNames: + kind: '' + plural: '' + conditions: null + storedVersions: null diff --git a/Openshift4/operator/xray-operator/bundle/1.1.2/manifests/xray-operator.v1.1.2.clusterserviceversion.yaml b/Openshift4/operator/xray-operator/bundle/1.1.2/manifests/xray-operator.v1.1.2.clusterserviceversion.yaml new file mode 100644 index 0000000..dffeda3 --- /dev/null +++ b/Openshift4/operator/xray-operator/bundle/1.1.2/manifests/xray-operator.v1.1.2.clusterserviceversion.yaml @@ -0,0 +1,463 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: ClusterServiceVersion +metadata: + annotations: + alm-examples: |- + [ + { + "apiVersion": "charts.helm.k8s.io/v1alpha1", + "kind": "OpenshiftXray", + "metadata": { + "name": "openshiftxray" + }, + "spec": { + "xray": { + "initContainerImage": "registry.connect.redhat.com/jfrog/init:1.0.1", + "common": { + "xrayUserId": "1000721035", + "xrayGroupId": "1000721035", + "xrayVersion": "3.10.3-1" + }, + "analysis": { + "image": { + "registry": "registry.connect.redhat.com", + "repository": "jfrog/xray-analysis" + }, + "name": "xray-analysis", + "podManagementPolicy": "Parallel", + "preStartCommand": null, + "updateStrategy": "RollingUpdate" + }, + "database": { + "password": "OVERRIDE", + "url": "OVERRIDE", + "user": "OVERRIDE" + }, + "global": { + "postgresqlTlsSecret": null + }, + "indexer": { + "image": { + "registry": "registry.connect.redhat.com", + "repository": "jfrog/xray-indexer" + }, + "name": "xray-indexer", + "podManagementPolicy": "Parallel", + "updateStrategy": "RollingUpdate" + }, + "persist": { + "image": { + "registry": "registry.connect.redhat.com", + "repository": "jfrog/xray-persist" + }, + "name": "xray-persist", + "persistence": { + "size": "10Gi" + }, + "podManagementPolicy": "Parallel", + "preStartCommand": null, + "updateStrategy": "RollingUpdate" + }, + "postgresql": { + "enabled": false + }, + "rabbitmq-ha": { + "enabled": true, + "image": { + "repository": "registry.connect.redhat.com/jfrog/xray-rabbitmq", + "tag": "3.10.3-1" + }, + "rabbitmqUsername": "guest", + "rabbitmqPassword": "guest", + "managementUsername": "guest", + "managementPassword": "guest", + "initContainer": { + "enabled": false + }, + "securityContext": { + "fsGroup": 1000721035, + "runAsUser": 1000721035, + "runAsGroup": 1000721035 + }, + "replicaCount": 1 + }, + "replicaCount": 1, + "unifiedUpgradeAllowed": "true", + "router": { + "image": { + "imagePullPolicy": "IfNotPresent", + "registry": "registry.connect.redhat.com", + "repository": "jfrog/xray-router", + "tag": "3.10.3-1" + }, + "name": "router" + }, + "server": { + "image": { + "registry": "registry.connect.redhat.com", + "repository": "jfrog/xray-server" + }, + "name": "xray-server", + "podManagementPolicy": "Parallel", + "replicaCount": 1, + "updateStrategy": "RollingUpdate" + }, + "xray": { + "consoleLog": false, + "jfrogUrl": "OVERRIDE", + "joinKey": "OVERRIDE", + "masterKey": "OVERRIDE" + } + } + } + } + ] + capabilities: Seamless Upgrades + categories: Developer Tools,Integration & Delivery + certified: 'true' + containerImage: registry.connect.redhat.com/jfrog/xray-operator:3.10.3 + createdAt: 2020-05-22 00:00:00+00:00 + description: JFrog Xray Enterprise deploys Xray continuous security scanner into + Openshift (Requires Jfrog Artifactory) + repository: https://github.com/jfrog/JFrog-Cloud-Installers/tree/openshift4/Openshift4 + support: JFrog + creationTimestamp: null + name: xray-operator.v1.1.2 + namespace: default +spec: + apiservicedefinitions: {} + customresourcedefinitions: + owned: + - description: Represents Xray Instances + displayName: Xray + kind: OpenshiftXray + name: openshiftxrays.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 Xray Continuous Security scanner into your Openshift cluster. + + + ## Security Context Constraints + + To deploy this helm chart you will need to be a cluster admin w/ access to the anyuid scc and add the operator service account to the anyuid scc. + + + ``` + + oc adm policy add-scc-to-user anyuid -z xray-operator + + ``` + + ## 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 Xray Operator to install. + + + Go to the Installed Operators. + + + Wait for the JFrog Xray Operator to complete the installation. + + + Open the Operator and click on the provided API: Xray + + + Click Create New Instance and provide the following parameters for your DB configuration: + + + ``` + + JFROG_URL + + DATABASE_URL + + DATABASE_USER + + DATABASE_PASSWORD + + ``` + + + JFROG_URL is the external ip or DNS of your Artifactory to connect Xray to. Artifactory + is required to use this operator. + + + DATABASE_URL must be a Postgresql URL in the format: + + ``` + + postgres://postgres-postgresql:5432/xraydb?sslmode=disable + + ``` + + + DATABASE_USER and DATABASE_PASSWORD must supply a valid user on Postgresql. + + + Click Create for Xray to deploy into OpenShift. + + + Open Artifactory in a web browser to complete the onboarding wizard for Xray! + + + ## Air gap environments + + + To use Xray Operator in an air gap environment you will need to download the images as image streams into your Openshift air gap cluster manually. + + + Use the image overrides to then specify the image stream locations that are local to your cluster. + + + Next you will need to setup the database of index data for xray to use when scanning artifacts. + + + Follow the link below for instructions on setup: + + + https://www.jfrog.com/confluence/display/JFROG/Configuring+Xray#ConfiguringXray-SynchronizingtheDatabase + + ' + displayName: JFrog Xray Continuous Security Operator + icon: + - base64data: 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 + mediatype: image/png + install: + spec: + deployments: + - name: xray-operator + spec: + replicas: 1 + selector: + matchLabels: + name: xray-operator + strategy: {} + template: + metadata: + labels: + name: xray-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: xray-operator + - name: RELATED_IMAGE_XRAY_INIT_IMAGE_REPOSITORY + value: registry.connect.redhat.com/jfrog/init:1.0.1 + - name: RELATED_IMAGE_XRAY_SERVER_IMAGE_REPOSITORY + value: registry.connect.redhat.com/jfrog/xray-server:3.10.3-1 + - name: RELATED_IMAGE_XRAY_ANALYSIS_IMAGE_REPOSITORY + value: registry.connect.redhat.com/jfrog/xray-analysis:3.10.3-1 + - name: RELATED_IMAGE_XRAY_PERSIST_IMAGE_REPOSITORY + value: registry.connect.redhat.com/jfrog/xray-persist:3.10.3-1 + - name: RELATED_IMAGE_XRAY_INDEXER_IMAGE_REPOSITORY + value: registry.connect.redhat.com/jfrog/xray-indexer:3.10.3-1 + - name: RELATED_IMAGE_XRAY_ROUTER_IMAGE_REPOSITORY + value: registry.connect.redhat.com/jfrog/xray-router:3.10.3-1 + - name: RELATED_IMAGE_XRAY_RABBITMQ_IMAGE_REPOSITORY + value: registry.connect.redhat.com/jfrog/xray-rabbitmq:3.10.3-1 + image: registry.connect.redhat.com/jfrog/xray-operator:3.10.3 + imagePullPolicy: Always + name: xray-operator + resources: {} + serviceAccountName: xray-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: + - xray-operator + resources: + - '*' + verbs: + - '*' + - apiGroups: + - '' + resources: + - events + verbs: + - create + - apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - get + - create + - apiGroups: + - apps + resourceNames: + - xray-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: + - '*' + serviceAccountName: xray-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 Xray Continuous Security + url: https://jfrog.com/xray/ + - name: JFrog Xray Continuous Security Video + url: https://youtu.be/wGzyKlQklKQ + maintainers: + - email: partner-support@jfrog.com + name: JFrog + maturity: alpha + provider: + name: JFrog + replaces: xray-operator.v1.1.1 + version: 1.1.2 +status: + certsLastUpdated: null + certsRotateAt: null + lastTransitionTime: null + lastUpdateTime: null diff --git a/Openshift4/operator/xray-operator/bundle/1.1.2/metadata/annotations.yaml b/Openshift4/operator/xray-operator/bundle/1.1.2/metadata/annotations.yaml new file mode 100644 index 0000000..2b47077 --- /dev/null +++ b/Openshift4/operator/xray-operator/bundle/1.1.2/metadata/annotations.yaml @@ -0,0 +1,12 @@ +annotations: + operators.operatorframework.io.bundle.channel.default.v1: alpha + operators.operatorframework.io.bundle.channels.v1: alpha + operators.operatorframework.io.bundle.manifests.v1: manifests/ + operators.operatorframework.io.bundle.mediatype.v1: registry+v1 + operators.operatorframework.io.bundle.metadata.v1: metadata/ + operators.operatorframework.io.bundle.package.v1: openshiftxray-operator + operators.operatorframework.io.metrics.builder: operator-sdk-v1.0.1 + operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 + operators.operatorframework.io.metrics.project_layout: helm.sdk.operatorframework.io/v1 + operators.operatorframework.io.test.config.v1: tests/scorecard/ + operators.operatorframework.io.test.mediatype.v1: scorecard+v1 \ No newline at end of file diff --git a/Openshift4/operator/xray-operator/bundle/1.1.2/metadata/openshiftxray-operator.package.yaml b/Openshift4/operator/xray-operator/bundle/1.1.2/metadata/openshiftxray-operator.package.yaml new file mode 100644 index 0000000..5184456 --- /dev/null +++ b/Openshift4/operator/xray-operator/bundle/1.1.2/metadata/openshiftxray-operator.package.yaml @@ -0,0 +1,5 @@ +channels: +- currentCSV: xray-operator.v1.1.2 + name: alpha +defaultChannel: '' +packageName: openshiftxray-operator diff --git a/Openshift4/operator/xray-operator/bundle/bundle-1.1.2.Dockerfile b/Openshift4/operator/xray-operator/bundle/bundle-1.1.2.Dockerfile new file mode 100644 index 0000000..d148465 --- /dev/null +++ b/Openshift4/operator/xray-operator/bundle/bundle-1.1.2.Dockerfile @@ -0,0 +1,19 @@ +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=openshiftxray-operator +LABEL operators.operatorframework.io.bundle.channels.v1=alpha +LABEL operators.operatorframework.io.bundle.channel.default.v1=alpha +LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.0.1 +LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 +LABEL operators.operatorframework.io.metrics.project_layout=helm.sdk.operatorframework.io/v1 +LABEL operators.operatorframework.io.test.config.v1=tests/scorecard/ +LABEL operators.operatorframework.io.test.mediatype.v1=scorecard+v1 + +COPY 1.1.2/manifests /manifests/ +COPY 1.1.2/metadata /metadata/ +LABEL com.redhat.openshift.versions="v4.5,v4.6" +LABEL com.redhat.delivery.operator.bundle=true +LABEL com.redhat.delivery.backport=true diff --git a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/CHANGELOG.md b/Openshift4/operator/xray-operator/helm-charts/openshift-xray/CHANGELOG.md index a4c6f3b..09067a3 100755 --- a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/CHANGELOG.md +++ b/Openshift4/operator/xray-operator/helm-charts/openshift-xray/CHANGELOG.md @@ -1,6 +1,9 @@ # JFrog Openshift Artifactory-Xray Chart Changelog All changes to this chart will be documented in this file. +## [6.1.2] Oct 22nd, 2020 +* Updating to Xray chart version 6.1.2 and Xray app version 3.9.1 + ## [6.0.6] Oct 1st, 2020 * Updating to Xray chart version 6.0.6 and Xray app version 3.8.8 diff --git a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/Chart.yaml b/Openshift4/operator/xray-operator/helm-charts/openshift-xray/Chart.yaml index aa8c6b6..51784ef 100755 --- a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/Chart.yaml +++ b/Openshift4/operator/xray-operator/helm-charts/openshift-xray/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: 3.8.8 +appVersion: 3.9.1 description: Universal component scan for security and license inventory and impact analysis sources: - https://bintray.com/jfrog/product/xray/view @@ -13,4 +13,4 @@ maintainers: - email: johnp@jfrog.com name: John Peterson name: openshift-xray -version: 6.0.6 +version: 6.1.2 diff --git a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/rabbitmq.yaml b/Openshift4/operator/xray-operator/helm-charts/openshift-xray/rabbitmq.yaml deleted file mode 100644 index df49bf6..0000000 --- a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/rabbitmq.yaml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app: rabbitmq - name: rabbitmq - namespace: default -spec: - replicas: 1 - selector: - matchLabels: - app: rabbitmq - template: - metadata: - labels: - app: rabbitmq - spec: - containers: - - image: registry.connect.redhat.com/jfrog/xray-rabbitmq:3.8.9 - imagePullPolicy: "Always" - name: xray-rabbitmq - ports: - - containerPort: 4369 - - containerPort: 5672 - - containerPort: 15672 diff --git a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/rabbitmqservice.yaml b/Openshift4/operator/xray-operator/helm-charts/openshift-xray/rabbitmqservice.yaml deleted file mode 100644 index fb51fce..0000000 --- a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/rabbitmqservice.yaml +++ /dev/null @@ -1,26 +0,0 @@ -kind: Service -apiVersion: v1 -metadata: - name: rabbitmq-lb - labels: - app: rabbitmq -spec: - selector: - app: rabbitmq - ports: - - name: epmd - protocol: TCP - port: 4369 - targetPort: 4369 - - name: ampq - protocol: TCP - port: 5672 - targetPort: 5672 - - name: management - protocol: TCP - port: 15672 - targetPort: 25672 - type: ClusterIP - - - diff --git a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/requirements.lock b/Openshift4/operator/xray-operator/helm-charts/openshift-xray/requirements.lock index d53cf7c..de38552 100644 --- a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/requirements.lock +++ b/Openshift4/operator/xray-operator/helm-charts/openshift-xray/requirements.lock @@ -1,6 +1,6 @@ dependencies: - name: xray repository: https://charts.jfrog.io/ - version: 6.0.6 -digest: sha256:339b5ec4e309ce2970ed34ebc700d6fe8f436d6cbe8dd5d352f0b080401752af -generated: "2020-10-01T15:04:29.008985-07:00" + version: 6.2.1 +digest: sha256:7bce8744ad24ebe2d962738cb688412c44c200b0b0015afb4471df479d826fde +generated: "2020-10-23T12:58:46.07336-07:00" diff --git a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/requirements.yaml b/Openshift4/operator/xray-operator/helm-charts/openshift-xray/requirements.yaml index f6311b7..276689d 100644 --- a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/requirements.yaml +++ b/Openshift4/operator/xray-operator/helm-charts/openshift-xray/requirements.yaml @@ -1,4 +1,4 @@ dependencies: - name: xray - version: 6.0.6 + version: 6.2.1 repository: https://charts.jfrog.io/ diff --git a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/values.yaml b/Openshift4/operator/xray-operator/helm-charts/openshift-xray/values.yaml index b242f3d..fcb1656 100755 --- a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/values.yaml +++ b/Openshift4/operator/xray-operator/helm-charts/openshift-xray/values.yaml @@ -13,15 +13,30 @@ xray: url: "OVERRIDE" user: "OVERRIDE" password: "OVERRIDE" + initContainerImage: registry.connect.redhat.com/jfrog/init:1.0.1 common: xrayUserId: "1000721035" xrayGroupId: "1000721035" + xrayVersion: "3.10.3-1" + customInitContainers: | + - name: "prepare-uid-persistent-volume" + image: "{{ .Values.initContainerImage }}" + imagePullPolicy: "{{ .Values.imagePullPolicy }}" + command: + - 'sh' + - '-c' + - > + chown -Rv {{ .Values.common.xrayUserId }}:{{ .Values.common.xrayGroupId }} {{ .Values.xray.persistence.mountPath }} + securityContext: + runAsUser: 0 + volumeMounts: + - mountPath: "{{ .Values.xray.persistence.mountPath }}" + name: data-volume analysis: name: xray-analysis image: registry: registry.connect.redhat.com repository: jfrog/xray-analysis - tag: 3.8.8 updateStrategy: RollingUpdate podManagementPolicy: Parallel preStartCommand: @@ -30,7 +45,6 @@ xray: image: registry: registry.connect.redhat.com repository: jfrog/xray-indexer - tag: 3.8.8 updateStrategy: RollingUpdate podManagementPolicy: Parallel persist: @@ -38,7 +52,6 @@ xray: image: registry: registry.connect.redhat.com repository: jfrog/xray-persist - tag: 3.8.8 updateStrategy: RollingUpdate podManagementPolicy: Parallel persistence: @@ -49,7 +62,6 @@ xray: image: registry: registry.connect.redhat.com repository: jfrog/xray-server - tag: 3.8.8 updateStrategy: RollingUpdate podManagementPolicy: Parallel replicaCount: 1 @@ -58,14 +70,14 @@ xray: image: registry: registry.connect.redhat.com repository: jfrog/xray-router - tag: 1.4.3 imagePullPolicy: IfNotPresent + tag: 3.10.3-1 rabbitmq-ha: enabled: true replicaCount: 1 image: repository: registry.connect.redhat.com/jfrog/xray-rabbitmq - tag: 3.8.9 + tag: 3.10.3-1 rabbitmqEpmdPort: 4369 rabbitmqNodePort: 5672 rabbitmqManagerPort: 15672 diff --git a/Openshift4/operator/xray-operator/watches.yaml b/Openshift4/operator/xray-operator/watches.yaml index 3fc15af..c74dbda 100644 --- a/Openshift4/operator/xray-operator/watches.yaml +++ b/Openshift4/operator/xray-operator/watches.yaml @@ -3,3 +3,11 @@ group: charts.helm.k8s.io kind: OpenshiftXray chart: helm-charts/openshift-xray + overrideValues: + xray.initContainerImage.override: $RELATED_IMAGE_XRAY_INIT_IMAGE_REPOSITORY + xray.server.image.override: $RELATED_IMAGE_XRAY_SERVER_IMAGE_REPOSITORY + xray.analysis.image.override: $RELATED_IMAGE_XRAY_ANALYSIS_IMAGE_REPOSITORY + xray.persist.image.override: $RELATED_IMAGE_XRAY_PERSIST_IMAGE_REPOSITORY + xray.indexer.image.override: $RELATED_IMAGE_XRAY_INDEXER_IMAGE_REPOSITORY + xray.router.image.override: $RELATED_IMAGE_XRAY_ROUTER_IMAGE_REPOSITORY + xray.rabbitmq-ha.image.override: $RELATED_IMAGE_XRAY_RABBITMQ_IMAGE_REPOSITORY \ No newline at end of file From a3f2dbbf79474d86085ae9d537776ed79fd6da85 Mon Sep 17 00:00:00 2001 From: John Peterson Date: Fri, 23 Oct 2020 15:27:07 -0700 Subject: [PATCH 2/5] Fixing changelog versions to be accurate --- Openshift4/helm/openshift-xray/CHANGELOG.md | 3 +++ Openshift4/operator/pipeline-operator/CHANGELOG.md | 4 ++-- Openshift4/operator/xray-operator/CHANGELOG.md | 6 ++++++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Openshift4/helm/openshift-xray/CHANGELOG.md b/Openshift4/helm/openshift-xray/CHANGELOG.md index 09067a3..c2e78ea 100755 --- a/Openshift4/helm/openshift-xray/CHANGELOG.md +++ b/Openshift4/helm/openshift-xray/CHANGELOG.md @@ -1,6 +1,9 @@ # JFrog Openshift Artifactory-Xray Chart Changelog All changes to this chart will be documented in this file. +## [6.2.1] Oct 23rd, 2020 +* Updating to Xray chart version 6.2.1 and Xray app version 3.10.3 + ## [6.1.2] Oct 22nd, 2020 * Updating to Xray chart version 6.1.2 and Xray app version 3.9.1 diff --git a/Openshift4/operator/pipeline-operator/CHANGELOG.md b/Openshift4/operator/pipeline-operator/CHANGELOG.md index 69b3240..4afc510 100755 --- a/Openshift4/operator/pipeline-operator/CHANGELOG.md +++ b/Openshift4/operator/pipeline-operator/CHANGELOG.md @@ -1,5 +1,5 @@ # JFrog Openshift Xray Chart Changelog All changes to this chart will be documented in this file. -## [1.1.1] Oct 9, 2020 -* Operator version 1.1.1 Openshift RT version 7.9.0, Xray version 3.8.8, Pipelines version 1.8.0 +## [1.0.0] Oct 23, 2020 +* Operator version 1.0.0 Pipelines version 1.8.0 diff --git a/Openshift4/operator/xray-operator/CHANGELOG.md b/Openshift4/operator/xray-operator/CHANGELOG.md index 7d1fbfb..8863a3e 100755 --- a/Openshift4/operator/xray-operator/CHANGELOG.md +++ b/Openshift4/operator/xray-operator/CHANGELOG.md @@ -1,6 +1,12 @@ # JFrog Openshift Xray Chart Changelog All changes to this chart will be documented in this file. +## [1.1.2] Oct 23rd, 2020 +* Deploying JFrog Xray 3.10.3 as an Operator into Openshift + +## [1.1.1] Oct 6, 2020 +* Bug Fixes + ## [1.1.0] Oct 1, 2020 * Deploying JFrog Xray 3.8.8 as an Operator into Openshift From 8d03703e9b30e42a7aceb97b324691397364bab5 Mon Sep 17 00:00:00 2001 From: John Peterson Date: Fri, 23 Oct 2020 15:28:16 -0700 Subject: [PATCH 3/5] Updating Chart to requirement yaml subchart version --- Openshift4/helm/openshift-xray/Chart.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Openshift4/helm/openshift-xray/Chart.yaml b/Openshift4/helm/openshift-xray/Chart.yaml index 51784ef..f14e835 100755 --- a/Openshift4/helm/openshift-xray/Chart.yaml +++ b/Openshift4/helm/openshift-xray/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 -appVersion: 3.9.1 +appVersion: 3.10.3 description: Universal component scan for security and license inventory and impact analysis sources: - https://bintray.com/jfrog/product/xray/view @@ -13,4 +13,4 @@ maintainers: - email: johnp@jfrog.com name: John Peterson name: openshift-xray -version: 6.1.2 +version: 6.2.1 From c4ff47cc5e07c724772314b1f462fd0e5a886d50 Mon Sep 17 00:00:00 2001 From: Jeff Fry Date: Sun, 25 Oct 2020 21:21:08 -0700 Subject: [PATCH 4/5] Updated RT and Xray default versions. Removed obsolete pipeline tests. --- .../roles/artifactory/defaults/main.yml | 4 +- .../installers/roles/xray/defaults/main.yml | 4 +- .../test/groovy/steps/SecuritytSteps.groovy | 196 ------ .../src/test/groovy/steps/XraySteps.groovy | 585 ------------------ Ansible/test/tests/src/test/groovy/testng.xml | 15 - .../test/groovy/tests/RepositoryTest.groovy | 302 --------- .../src/test/groovy/tests/SecurityTest.groovy | 153 ----- .../src/test/groovy/tests/XrayTest.groovy | 332 ---------- 8 files changed, 4 insertions(+), 1587 deletions(-) delete mode 100644 Ansible/test/tests/src/test/groovy/steps/SecuritytSteps.groovy delete mode 100644 Ansible/test/tests/src/test/groovy/steps/XraySteps.groovy delete mode 100644 Ansible/test/tests/src/test/groovy/tests/RepositoryTest.groovy delete mode 100644 Ansible/test/tests/src/test/groovy/tests/SecurityTest.groovy delete mode 100644 Ansible/test/tests/src/test/groovy/tests/XrayTest.groovy diff --git a/Ansible/ansible_collections/jfrog/installers/roles/artifactory/defaults/main.yml b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/defaults/main.yml index 5cdaab6..64a426c 100644 --- a/Ansible/ansible_collections/jfrog/installers/roles/artifactory/defaults/main.yml +++ b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/defaults/main.yml @@ -4,7 +4,7 @@ ansible_marketplace: standalone # The version of Artifactory to install -artifactory_version: 7.7.8 +artifactory_version: 7.10.2 # licenses file - specify a licenses file or specify up to 5 licenses artifactory_license1: @@ -49,4 +49,4 @@ service_list: group_name: "{{ artifactory_group }}" # if this is an upgrade -artifactory_upgrade_only: false \ No newline at end of file +artifactory_upgrade_only: false diff --git a/Ansible/ansible_collections/jfrog/installers/roles/xray/defaults/main.yml b/Ansible/ansible_collections/jfrog/installers/roles/xray/defaults/main.yml index 9306290..fd674bf 100644 --- a/Ansible/ansible_collections/jfrog/installers/roles/xray/defaults/main.yml +++ b/Ansible/ansible_collections/jfrog/installers/roles/xray/defaults/main.yml @@ -4,7 +4,7 @@ ansible_marketplace: standalone # The version of xray to install -xray_version: 3.8.6 +xray_version: 3.10.3 # whether to enable HA xray_ha_enabled: true @@ -26,4 +26,4 @@ xray_group: xray # if this is an upgrade xray_upgrade_only: false -xray_system_yaml_template: system.yaml.j2 \ No newline at end of file +xray_system_yaml_template: system.yaml.j2 diff --git a/Ansible/test/tests/src/test/groovy/steps/SecuritytSteps.groovy b/Ansible/test/tests/src/test/groovy/steps/SecuritytSteps.groovy deleted file mode 100644 index 4450b39..0000000 --- a/Ansible/test/tests/src/test/groovy/steps/SecuritytSteps.groovy +++ /dev/null @@ -1,196 +0,0 @@ -package steps - -import org.testng.annotations.DataProvider - -import static io.restassured.RestAssured.given - - -class SecuritytSteps { - - def createUser(usernameRt, emailRt, passwordRt) { - return given() - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .body("{\n" + - " \"email\" : \"${emailRt}\",\n" + - " \"password\": \"${passwordRt}\"\n" + - "}") - .when() - .put("/api/security/users/${usernameRt}") - .then() - .extract().response() - } - - def getUserDetails(usernameRt) { - return given() - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .get("/api/security/users/${usernameRt}") - .then() - .extract().response() - } - - def deleteUser(usernameRt) { - return given() - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .delete("/api/security/users/${usernameRt}") - .then() - .extract().response() - } - - def generateAPIKey(usernameRt, passwordRt) { - return given() - .auth() - .preemptive() - .basic("${usernameRt}", "${passwordRt}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .post("/api/security/apiKey") - .then() - .extract().response() - } - - def getAPIKey(usernameRt, passwordRt) { - return given() - .auth() - .preemptive() - .basic("${usernameRt}", "${passwordRt}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .get("/api/security/apiKey") - .then() - .extract().response() - } - - def regenerateAPIKey(usernameRt, passwordRt) { - return given() - .auth() - .preemptive() - .basic("${usernameRt}", "${passwordRt}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .put("/api/security/apiKey") - .then() - .extract().response() - } - - def createGroup(groupName) { - return given() - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .body("{\"name\": \"${groupName}\"}") - .when() - .put("/api/security/groups/${groupName}") - .then() - .extract().response() - } - - def getGroup(groupName) { - return given() - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .body("{\"name\": \"${groupName}\"}") - .when() - .get("/api/security/groups/${groupName}") - .then() - .extract().response() - } - - def deleteGroup(groupName) { - return given() - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .delete("/api/security/groups/${groupName}") - .then() - .extract().response() - } - - def createPermissions(permissionName, repository, user1, user2, - group1, group2, action1, action2, action3) { - return given() - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .body("{\n" + - " \"name\": \"${permissionName}\",\n" + - " \"repo\": {\n" + - " \"repositories\": [ \"${repository}\" ],\n" + - " \"actions\": {\n" + - " \"users\" : {\n" + - " \"${user1}\": [ \"${action1}\",\"${action2}\",\"${action3}\" ], \n" + - " \"${user2}\" : [ \"${action1}\",\"${action2}\",\"${action3}\" ]\n" + - " },\n" + - " \"groups\" : {\n" + - " \"${group1}\" : [ \"${action1}\",\"${action2}\",\"${action3}\" ],\n" + - " \"${group2}\" : [ \"${action1}\",\"${action2}\" ]\n" + - " }\n" + - " }\n" + - " }\n" + - "}") - .when() - .put("/api/v2/security/permissions/testPermission") - .then() - .extract().response() - } - - def getPermissions( permissionName) { - return given() - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .get("/api/v2/security/permissions/${permissionName}") - .then() - .extract().response() - } - - def deletePermissions(permissionName) { - return given() - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .delete("/api/v2/security/permissions/${permissionName}") - .then() - .extract().response() - } - - - // Data providers - - @DataProvider(name="users") - public Object[][] users() { - return new Object[][]{ - ["testuser0", "email0@jfrog.com", "password123"], - ["testuser1", "email1@jfrog.com", "password123"], - ["testuser2", "email2@jfrog.com", "password123"], - ["testuser3", "email3@jfrog.com", "password123"], - ["testuser4", "email4@jfrog.com", "password123"], - ["testuser5", "email5@jfrog.com", "password123"], - ["testuser6", "email6@jfrog.com", "password123"], - ["testuser7", "email7@jfrog.com", "password123"], - ["testuser8", "email8@jfrog.com", "password123"], - ["testuser9", "email9@jfrog.com", "password123"] - } - } - - @DataProvider(name="groups") - public Object[][] groups() { - return new Object[][]{ - ["test-group-0"], - ["test-group-1"], - ["test-group-2"], - ["test-group-3"], - ["test-group-4"], - ["test-group-5"], - ["test-group-6"], - ["test-group-7"], - ["test-group-8"], - ["test-group-9"] - } - } -} diff --git a/Ansible/test/tests/src/test/groovy/steps/XraySteps.groovy b/Ansible/test/tests/src/test/groovy/steps/XraySteps.groovy deleted file mode 100644 index 552ba93..0000000 --- a/Ansible/test/tests/src/test/groovy/steps/XraySteps.groovy +++ /dev/null @@ -1,585 +0,0 @@ -package steps - -import org.testng.annotations.DataProvider - -import static io.restassured.RestAssured.given - -class XraySteps { - - def createIssueEvent(issueID, cve, summary, description, username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .body("{\n" + - " \"id\": \"${issueID}\",\n" + - " \"type\": \"Security\",\n" + - " \"provider\": \"JFrog\",\n" + - " \"package_type\": \"maven\",\n" + - " \"severity\": \"High\",\n" + - " \"components\": [\n" + - " {\n" + - " \"id\": \"aero:aero\",\n" + - " \"vulnerable_versions\": [\n" + - " \"[0.2.3]\"\n" + - " ]\n" + - " }\n" + - " ],\n" + - " \"cves\": [\n" + - " {\n" + - " \"cve\": \"${cve}\",\n" + - " \"cvss_v2\": \"2.4\"\n" + - " }\n" + - " ],\n" + - " \"summary\": \"${summary}\",\n" + - " \"description\": \"${description}\",\n" + - " \"sources\": [\n" + - " {\n" + - " \"source_id\": \"${cve}\"\n" + - " }\n" + - " ]\n" + - "}") - .when() - .post("/v1/events") - .then() - .extract().response() - } - - def updateIssueEvent(issueID, cve, summary, description, username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .body("{\n" + - " \"type\": \"Security\",\n" + - " \"provider\": \"JFrog\",\n" + - " \"package_type\": \"maven\",\n" + - " \"severity\": \"High\",\n" + - " \"components\": [\n" + - " {\n" + - " \"id\": \"aero:aero\",\n" + - " \"vulnerable_versions\": [\n" + - " \"[0.2.3]\"\n" + - " ]\n" + - " }\n" + - " ],\n" + - " \"cves\": [\n" + - " {\n" + - " \"cve\": \"${cve}\",\n" + - " \"cvss_v2\": \"2.4\"\n" + - " }\n" + - " ],\n" + - " \"summary\": \"${summary}\",\n" + - " \"description\": \"${description}\",\n" + - " \"sources\": [\n" + - " {\n" + - " \"source_id\": \"${cve}\"\n" + - " }\n" + - " ]\n" + - "}") - .when() - .put("/v1/events/${issueID}") - .then() - .extract().response() - } - - def createPolicy(policyName, username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .body("{\n" + - " \"name\": \"${policyName}\",\n" + - " \"type\": \"security\",\n" + - " \"description\": \"some description\",\n" + - " \"rules\": [\n" + - " {\n" + - " \"name\": \"securityRule\",\n" + - " \"priority\": 1,\n" + - " \"criteria\": {\n" + - " \"min_severity\": \"High\"\n" + - " },\n" + - " \"actions\": {\n" + - " \"mails\": [\n" + - " \"mail1@example.com\",\n" + - " \"mail2@example.com\"\n" + - " ],\n" + - " \"fail_build\": true,\n" + - " \"block_download\": {\n" + - " \"unscanned\": true,\n" + - " \"active\": true\n" + - " }\n" + - " }\n" + - " }\n" + - " ]\n" + - "}") - .when() - .post("/v1/policies") - .then() - .extract().response() - } - - def updatePolicy(policyName, description, username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .body("{\n" + - " \"name\": \"${policyName}\",\n" + - " \"type\": \"security\",\n" + - " \"description\": \"${description}\",\n" + - " \"rules\": [\n" + - " {\n" + - " \"name\": \"securityRule\",\n" + - " \"priority\": 1,\n" + - " \"criteria\": {\n" + - " \"min_severity\": \"High\"\n" + - " },\n" + - " \"actions\": {\n" + - " \"mails\": [\n" + - " \"mail1@example.com\",\n" + - " \"mail2@example.com\"\n" + - " ],\n" + - " \"fail_build\": true,\n" + - " \"block_download\": {\n" + - " \"unscanned\": true,\n" + - " \"active\": true\n" + - " }\n" + - " }\n" + - " }\n" + - " ]\n" + - "}") - .when() - .put("/v1/policies/${policyName}") - .then() - .extract().response() - } - - def getPolicy(policyName, username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .get("/v1/policies/${policyName}") - .then() - .extract().response() - } - - def getPolicies(username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .get("/v1/policies") - .then() - .extract().response() - } - - def deletePolicy(policyName, username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .delete("/v1/policies/${policyName}") - .then() - .extract().response() - } - - def getIssueEvent(issueID, username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .get("/v1/events/${issueID}") - .then() - .extract().response() - } - - def createWatchEvent(watchName, policyName, username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .body("{\n" + - " \"general_data\": {\n" + - " \"name\": \"${watchName}\",\n" + - " \"description\": \"This is a new watch created using API V2\",\n" + - " \"active\": true\n" + - " },\n" + - " \"project_resources\": {\n" + - " \"resources\": [\n" + - " {\n" + - " \"type\": \"all-repos\",\n" + - " \"filters\": [\n" + - " {\n" + - " \"type\": \"package-type\",\n" + - " \"value\": \"Docker\"\n" + - " },\n" + - " {\n" + - " \"type\": \"package-type\",\n" + - " \"value\": \"Debian\"\n" + - " }\n" + - " ]\n" + - " }\n" + - " ]\n" + - " },\n" + - " \"assigned_policies\": [\n" + - " {\n" + - " \"name\": \"${policyName}\",\n" + - " \"type\": \"security\"\n" + - " }\n" + - " ]\n" + - "}") - .when() - .post("/v2/watches") - .then() - .extract().response() - } - - def updateWatchEvent(watchName, description, policyName, username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .body("{\n" + - " \"general_data\": {\n" + - " \"name\": \"${watchName}\",\n" + - " \"description\": \"${description}\",\n" + - " \"active\": true\n" + - " },\n" + - " \"project_resources\": {\n" + - " \"resources\": [\n" + - " {\n" + - " \"type\": \"all-repos\",\n" + - " \"filters\": [\n" + - " {\n" + - " \"type\": \"package-type\",\n" + - " \"value\": \"Docker\"\n" + - " },\n" + - " {\n" + - " \"type\": \"package-type\",\n" + - " \"value\": \"Debian\"\n" + - " }\n" + - " ]\n" + - " }\n" + - " ]\n" + - " },\n" + - " \"assigned_policies\": [\n" + - " {\n" + - " \"name\": \"${policyName}\",\n" + - " \"type\": \"security\"\n" + - " }\n" + - " ]\n" + - "}") - .when() - .put("/v2/watches/${watchName}") - .then() - .extract().response() - } - - def getWatchEvent(watchName, username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .get("/v2/watches/${watchName}") - .then() - .extract().response() - } - - def deleteWatchEvent(watchName, username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .delete("/v2/watches/${watchName}") - .then() - .extract().response() - } - - def assignPolicy(watchName, policyName, username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .body("{\n" + - " \"watches\": [\n" + - " \"${watchName}\"\n" + - " ]\n" + - "}") - .when() - .post("/v1/policies/${policyName}/assign") - .then() - .extract().response() - } - - def getIntegrationConfiguration(username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .get("/v1/integration") - .then() - .extract().response() - } - - def addtIntegrationConfiguration(username, password, vendorName) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .body("{\n" + - " \"vendor\": \"${vendorName}\",\n" + - " \"api_key\": \"12345\",\n" + - " \"enabled\": true,\n" + - " \"context\": \"project_id\",\n" + - " \"url\": \"https://saas.whitesourcesoftware.com/xray\",\n" + - " \"description\": \"WhiteSource provides a simple yet powerful open source security and licenses management solution. More details at http://www.whitesourcesoftware.com.\",\n" + - " \"test_url\": \"https://saas.whitesourcesoftware.com/xray/api/checkauth\"\n" + - "}") - .when() - .post("/v1/integration") - .then() - .extract().response() - } - - def postSystemParameters(username, password, body) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .body(body) - .when() - .put("/v1/configuration/systemParameters") - .then() - .extract().response() - } - - def getSystemParameters(username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .get("/v1/configuration/systemParameters") - .then() - .extract().response() - } - - def getBinaryManager(username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .get("/v1/binMgr/default") - .then() - .extract().response() - } - - - def getIndexingConfiguration(username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .when() - .get("/v1/binMgr/default/repos") - .then() - .extract().response() - } - - def updateIndexingConfiguration(username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .body("{\n" + - " \"indexed_repos\": [\n" + - " {\n" + - " \"name\": \"docker-local\",\n" + - " \"type\": \"local\",\n" + - " \"pkg_type\": \"Docker\"\n" + - " },\n" + - " {\n" + - " \"name\": \"generic-dev-local\",\n" + - " \"type\": \"local\",\n" + - " \"pkg_type\": \"Generic\"\n" + - " }\n" + - " ],\n" + - " \"non_indexed_repos\": []\n" + - "}") - .when() - .put("/v1/binMgr/default/repos") - .then() - .extract().response() - } - - - - def startScan(username, password, componentID) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("Content-Type", "application/json") - .body("{\n" + - " \"componentID\": \"${componentID}\"\n" + - "}") - .when() - .post("/v1/scanArtifact") - .then() - .extract().response() - } - - - def artifactSummary(username, password, artifactPath) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("content-Type", "application/json") - .body("{\n" + - " \"checksums\": [\n" + - " \"\"\n" + - " ],\n" + - " \"paths\": [\n" + - " \"${artifactPath}\"\n" + - " ]\n" + - "}") - .when() - .post("/v1/summary/artifact") - .then() - .extract().response() - } - - def createSupportBundle(username, password, name, startDate, endDate) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("Content-Type", "application/json") - .body("{ \n" + - " \"name\":\"${name}\",\n" + - " \"description\":\"desc\",\n" + - " \"parameters\":{ \n" + - " \"configuration\": true,\n" + - " \"system\": true, \n" + - " \"logs\":{ \n" + - " \"include\": true, \n" + - " \"start_date\":\"${startDate}\",\n" + - " \"end_date\":\"${endDate}\"\n" + - " },\n" + - " \"thread_dump\":{ \n" + - " \"count\": 1,\n" + - " \"interval\": 0\n" + - " }\n" + - " }\n" + - "}") - .when() - .post("/v1/system/support/bundle") - .then() - .extract().response() - - } - - def getSystemMonitoringStatus(username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("Content-Type", "application/json") - .when() - .get("/v1/monitor") - .then() - .extract().response() - } - - def xrayPingRequest(username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("Content-Type", "application/json") - .when() - .get("/v1/system/ping") - .then() - .extract().response() - } - - def xrayGetVersion(username, password) { - return given() - .auth() - .preemptive() - .basic("${username}", "${password}") - .header("Cache-Control", "no-cache") - .header("Content-Type", "application/json") - .when() - .get("/v1/system/version") - .then() - .extract().response() - } - - // Data providers - - @DataProvider(name = "issueEvents") - public Object[][] issueEvents() { - return new Object[][]{ - ["XRAY-", "CVE-2017-2000386", "A very important custom issue", "A very important custom issue"] - - } - } - -} \ No newline at end of file diff --git a/Ansible/test/tests/src/test/groovy/testng.xml b/Ansible/test/tests/src/test/groovy/testng.xml index 5342660..cee4eb7 100644 --- a/Ansible/test/tests/src/test/groovy/testng.xml +++ b/Ansible/test/tests/src/test/groovy/testng.xml @@ -7,19 +7,4 @@ - - - - - - - - - - - - - - - diff --git a/Ansible/test/tests/src/test/groovy/tests/RepositoryTest.groovy b/Ansible/test/tests/src/test/groovy/tests/RepositoryTest.groovy deleted file mode 100644 index 3deb72a..0000000 --- a/Ansible/test/tests/src/test/groovy/tests/RepositoryTest.groovy +++ /dev/null @@ -1,302 +0,0 @@ -package tests - -import io.restassured.RestAssured -import io.restassured.path.json.JsonPath -import io.restassured.response.Response -import org.hamcrest.Matchers -import org.testng.Reporter -import org.testng.annotations.BeforeTest -import org.testng.annotations.Test -import org.yaml.snakeyaml.Yaml -import steps.RepositorySteps - -import java.time.LocalDate - -import static org.hamcrest.Matchers.containsString -import static org.hamcrest.Matchers.containsStringIgnoringCase -import static org.hamcrest.Matchers.equalTo -import static org.hamcrest.Matchers.equalToIgnoringCase -import static org.hamcrest.Matchers.greaterThanOrEqualTo - - -class RepositoryTest extends RepositorySteps{ - Yaml yaml = new Yaml() - def configFile = new File("./src/test/resources/testenv.yaml") - def repoListHA = new File("./src/test/resources/repositories/CreateDefault.yaml") - def repoListJCR = new File("./src/test/resources/repositories/CreateJCR.yaml") - def artifact = new File("./src/test/resources/repositories/artifact.zip") - def config = yaml.load(configFile.text) - def artifactoryURL - def username - def password - - @BeforeTest(groups=["jcr", "pro"]) - def setUp() { - artifactoryURL = config.artifactory.external_ip - username = config.artifactory.rt_username - password = config.artifactory.rt_password - RestAssured.baseURI = "http://${artifactoryURL}/artifactory" - RestAssured.authentication = RestAssured.basic(username, password); - RestAssured.useRelaxedHTTPSValidation(); - } - - - @Test(priority=1, groups=["pro"], testName = "Delete sample repositories") - void deleteReposTest(){ - Response getRepoResponse = getRepos() - JsonPath jsonPathEvaluator = getRepoResponse.jsonPath() - List repoNames = jsonPathEvaluator.getList("key", String.class) - for (int i = 0; i < repoNames.size(); i ++){ - Response delete = deleteRepository(repoNames[i], username, password) - delete.then().statusCode(200) - } - - Reporter.log("- Delete sample HA repositories. All repositories were successfully deleted", true) - } - - @Test(priority=1, groups=["jcr",], testName = "Delete sample repositories JCR") - void deleteDefaultJCRReposTest(){ - Response getRepoResponse = getRepos() - JsonPath jsonPathEvaluator = getRepoResponse.jsonPath() - List repoNames = jsonPathEvaluator.getList("key", String.class) - for (int i = 0; i < repoNames.size(); i ++){ - Response delete = deleteRepository(repoNames[i], username, password) - delete.then().statusCode(400).body("errors[0].message", - containsStringIgnoringCase("This REST API is available only in Artifactory Pro")) - } - - Reporter.log("- Delete sample JCR repositories. " + - "Verified - this REST API is available only in Artifactory Pro", true) - } - - @Test(priority=2, groups=["pro"], testName = "Create a list of repositories for HA, specified in YAML file") - void createDefaultHAReposTest(){ - def body - def expectedMessage - body = repoListHA - expectedMessage = "383 changes to config merged successfully" - Response response = createRepositories(body, username, password) - response.then().assertThat().statusCode(200) - .body(Matchers.hasToString(expectedMessage)) - .log().body() - - Reporter.log("- Create repositories for HA distribution. Successfully created", true) - } - - @Test(priority=2, groups=["jcr"], testName = "Create a list of repositories for JCR, specified in YAML file") - void createDefaultJCRReposTest(){ - def body - def expectedMessage - body = repoListJCR - expectedMessage = "82 changes to config merged successfully" - Response response = createRepositories(body, username, password) - response.then().assertThat().statusCode(200) - .body(Matchers.hasToString(expectedMessage)) - .log().body() - - Reporter.log("- Create repositories for JCR. Successfully created", true) - } - - @Test(priority=3, groups=["pro"], testName = "Verify HA repositories were created successfully") - void checkDefaultHAReposTest(){ - Response response = getRepos() - def numberOfRepos = response.then().extract().path("size()") - def expectedReposNumber = 84 - println("Number of created repositories is ${numberOfRepos}") - response.then().assertThat().statusCode(200) - .body("size()", greaterThanOrEqualTo(expectedReposNumber)) - - Reporter.log("- Verify HA repos were created. ${numberOfRepos} repositories were created", true) - } - - @Test(priority=3, groups=["jcr"], testName = "Verify JCR repositories were created successfully") - void checkDefaultJCRReposTest(){ - Response response = getRepos() - def numberOfRepos = response.then().extract().path("size()") - def expectedReposNumber = 17 - response.then().assertThat().statusCode(200) - .body("size()", greaterThanOrEqualTo(expectedReposNumber)) - - Reporter.log("- Verify JCR repos were created. ${numberOfRepos} repositories were created", true) - } - - /*@Test(priority=4, groups=["jcr","pro"], testName = "Create a directory in generic repo") - void createDirectoryTest(){ - def repoName = "generic-dev-local" - def directoryName = "test-directory/" - Response response = createDirectory(repoName, directoryName) - response.then().assertThat().statusCode(201) - .body("repo", equalTo(repoName)) - .body("path", equalTo("/" + directoryName)) - .body("uri", equalTo("http://" + artifactoryURL + ":80/artifactory/" + repoName + "/" + directoryName)) - - Reporter.log("- Create folder. Folder successfully created", true) - } - - @Test(priority=5, groups=["jcr","pro"], testName = "Deploy file to generic repo") - void deployArtifactToGenericTest(){ - def repoName = "generic-dev-local" - def directoryName = "test-directory" - def filename = "artifact.zip" - Response response = deployArtifact(repoName, directoryName, artifact, filename) - response.then().assertThat().statusCode(201) - .body("repo", equalTo(repoName)) - .body("path", equalTo("/" + directoryName + "/" + filename)) - .body("downloadUri", equalTo("http://" + artifactoryURL + ":80/artifactory/" + repoName + "/" - + directoryName + "/" + filename)) - - Reporter.log("- Deploy artifact. Artifact successfully deployed", true) - } - - @Test(priority=6, groups=["jcr", "pro"], testName = "Get the artifact info") - void getArtifactinfoTest(){ - def repoName = "generic-dev-local" - def directoryName = "test-directory" - def filename = "artifact.zip" - Response response = getInfo(repoName, directoryName, artifact, filename) - response.then().assertThat().statusCode(200) - .body("repo", equalTo(repoName)) - .body("path", equalTo("/" + directoryName + "/" + filename)) - .body("downloadUri", equalTo("http://" + artifactoryURL + ":80/artifactory/" + repoName + "/" - + directoryName + "/" + filename)) - - Reporter.log("- Get the artifact info. Artifact info is successfully returned", true) - }*/ - -/* @Test(priority=7, groups=["jcr", "pro"], testName = "Delete item") - void deleteJCRItemTest(){ - def repoName = "generic-dev-local" - def directoryName = "test-directory" - def filename = "artifact.zip" - Response response = deleteItem(repoName, directoryName, artifact, filename) - response.then().assertThat().statusCode(204) - - Response verification = getInfo(repoName, directoryName, artifact, filename) - verification.then().statusCode(404) - .body("errors[0].message", equalToIgnoringCase("Unable to find item")) - - Reporter.log("- Delete item. File has been deleted successfully", true) - }*/ - - /*@Test(priority=8, groups=["pro"], testName = "Create support bundle") - void createSupportBundleHATest(){ - def name = "Support Bundle" - LocalDate startDate = LocalDate.now().minusDays(5) - LocalDate endDate = LocalDate.now() - Response response = createSupportBundle(name, startDate, endDate) - response.then().assertThat().statusCode(200) - .body("artifactory.bundle_url", containsString(artifactoryURL)) - - Reporter.log("- Create support bundle. Successfully created", true) - }*/ - - @Test(priority=8, groups=["jcr"], testName = "Create support bundle") - void createSupportBundleJCATest(){ - def name = "Support Bundle" - LocalDate startDate = LocalDate.now().minusDays(5) - LocalDate endDate = LocalDate.now() - Response response = createSupportBundle(name, startDate, endDate) - response.then().assertThat().statusCode(400) - .body("errors[0].message", - containsStringIgnoringCase("This REST API is available only in Artifactory Pro")) - - Reporter.log("- Create support bundle, JCR. " + - "Call is not supported in JCR version, error message is correct", true) - } - - @Test(priority=9, groups=["pro"], testName = "Delete created repositories") - void deleteDefaultReposTest(){ - Response getRepoResponse = getRepos() - JsonPath jsonPathEvaluator = getRepoResponse.jsonPath() - List repoNames = jsonPathEvaluator.getList("key", String.class) - for (int i = 0; i < repoNames.size(); i ++){ - Response delete = deleteRepository(repoNames[i], username, password) - delete.then().statusCode(200) - } - - Reporter.log("- Delete HA repositories. All repositories were successfully deleted", true) - } - - @Test(priority=9, groups=["jcr",], testName = "Delete sample repositories JCR") - void deleteJCRReposTest(){ - Response getRepoResponse = getRepos() - JsonPath jsonPathEvaluator = getRepoResponse.jsonPath() - List repoNames = jsonPathEvaluator.getList("key", String.class) - for (int i = 0; i < repoNames.size(); i ++){ - Response delete = deleteRepository(repoNames[i], username, password) - delete.then().statusCode(400).body("errors[0].message", - containsStringIgnoringCase("This REST API is available only in Artifactory Pro")) - } - - Reporter.log("- Delete sample JCR repositories. All repositories were successfully deleted", true) - } - - @Test(priority=10, groups=["pro"], testName = "Verify repositories were deleted successfully") - void checkReposAreDeleted(){ - Response response = getRepos() - def numberOfRepos = response.then().extract().path("size()") - def expectedReposNumber = 0 - response.then().assertThat().statusCode(200) - .body("size()", equalTo(expectedReposNumber)) - - Reporter.log("- Verify repo were deleted. ${numberOfRepos} repositories remain", true) - } - - @Test(priority=11, groups=["pro"], testName = "Re-Create a list of repositories, for the next tests") - void reCreateDefaultHAReposTest(){ - def body - def expectedMessage - body = repoListHA - expectedMessage = "383 changes to config merged successfully" - Response response = createRepositories(body, username, password) - response.then().assertThat().statusCode(200) - .body(Matchers.hasToString(expectedMessage)) - .log().body() - - Reporter.log("- Re-create repositories for HA distribution. Successfully created", true) - } - - @Test(priority=12, groups=["jcr"], testName = "Re-Create a list of repositories, for the next tests") - void reCreateDefaultJCRReposTest(){ - def body - def expectedMessage - body = repoListJCR - expectedMessage = "82 changes to config merged successfully" - Response response = createRepositories(body, username, password) - response.then().assertThat().statusCode(200) - .body(Matchers.hasToString(expectedMessage)) - .log().body() - - Reporter.log("- Re-create repositories for JCR distribution. Successfully created", true) - } - -/* @Test(priority=13, groups=["jcr","pro"], testName = "Create a directory in generic repo") - void reCreateDirectoryTest(){ - def repoName = "generic-dev-local" - def directoryName = "test-directory/" - Response response = createDirectory(repoName, directoryName) - response.then().assertThat().statusCode(201) - .body("repo", equalTo(repoName)) - .body("path", equalTo("/" + directoryName)) - .body("uri", equalTo("http://" + artifactoryURL + ":80/artifactory/" + repoName + "/" + directoryName)) - - Reporter.log("- Create folder. Folder successfully created", true) - }*/ - -/* @Test(priority=14, groups=["jcr","pro"], testName = "Deploy file to generic repo") - void reDeployArtifactToGenericTest(){ - def repoName = "generic-dev-local" - def directoryName = "test-directory" - def filename = "artifact.zip" - Response response = deployArtifact(repoName, directoryName, artifact, filename) - response.then().assertThat().statusCode(201) - .body("repo", equalTo(repoName)) - .body("path", equalTo("/" + directoryName + "/" + filename)) - .body("downloadUri", equalTo("http://" + artifactoryURL + ":80/artifactory/" + repoName + "/" - + directoryName + "/" + filename)) - - Reporter.log("- Deploy artifact. Artifact successfully deployed", true) - }*/ - - -} diff --git a/Ansible/test/tests/src/test/groovy/tests/SecurityTest.groovy b/Ansible/test/tests/src/test/groovy/tests/SecurityTest.groovy deleted file mode 100644 index a166cd0..0000000 --- a/Ansible/test/tests/src/test/groovy/tests/SecurityTest.groovy +++ /dev/null @@ -1,153 +0,0 @@ -package tests - -import io.restassured.RestAssured -import io.restassured.response.Response -import org.hamcrest.Matchers -import org.junit.Assert -import org.testng.Reporter -import org.testng.annotations.BeforeSuite -import org.testng.annotations.Test -import org.yaml.snakeyaml.Yaml -import steps.SecuritytSteps - - -class SecurityTest extends SecuritytSteps{ - - Yaml yaml = new Yaml() - def configFile = new File("./src/test/resources/testenv.yaml") - def config = yaml.load(configFile.text) - def artifactoryURL - def distribution - def username - def password - - @BeforeSuite(groups=["jcr","pro"]) - def setUp() { - artifactoryURL = config.artifactory.external_ip - distribution = config.artifactory.distribution - username = config.artifactory.rt_username - password = config.artifactory.rt_password - RestAssured.baseURI = "http://${artifactoryURL}/artifactory" - RestAssured.authentication = RestAssured.basic(username, password); - RestAssured.useRelaxedHTTPSValidation(); - } - - @Test(priority=1, groups=["pro"], dataProvider = "users", testName = "Create users") - void createUsersTest(usernameRt, emailRt, passwordRt){ - Response response = createUser(usernameRt, emailRt, passwordRt) - response.then().statusCode(201) - - Reporter.log("- Create users. User ${usernameRt} created successfully", true) - } - - @Test(priority=2, groups=["pro"], dataProvider = "users", testName = "Verify users were created successfully") - void verifyUsersTest(usernameRt, emailRt, passwordRt){ - Response response = getUserDetails(usernameRt) - response.then().statusCode(200). - body("name", Matchers.equalTo(usernameRt)). - body("email", Matchers.equalTo(emailRt)). - body("admin", Matchers.equalTo(false)). - body("groups[0]", Matchers.equalTo("readers")) - - Reporter.log("- Verify created users. User ${usernameRt} was successfully verified", true) - } - - @Test(priority=3, groups=["pro"], dataProvider = "users", testName = "Generate API keys") - void generateAPIKeysTest(usernameRt, emailRt, passwordRt) { - Response createKey = generateAPIKey(usernameRt, passwordRt) - def errorMessage = createKey.then().extract().path("error") - if (errorMessage == null) { - def key = createKey.then().extract().path("apiKey") - Response getKey = getAPIKey(usernameRt, passwordRt) - def keyVerification = getKey.then().extract().path("apiKey") - Assert.assertTrue(key == keyVerification) - Reporter.log("- Generate API keys. Key for ${usernameRt} created successfully", true) - } else if (errorMessage.toString().contains("Api key already exists for user:")){ - Reporter.log("- Generate API keys. Key for ${usernameRt} already exists, skipped", true) - } - } - - @Test(priority=4, groups=["pro"], dataProvider = "users", testName = "Re-generate API keys") - void regenerateAPIKeysTest(usernameRt, emailRt, passwordRt){ - Response regenerated = regenerateAPIKey(usernameRt, passwordRt) - regenerated.then().statusCode(200) - def key = regenerated.then().extract().path("apiKey") - Response getKey = getAPIKey(usernameRt, passwordRt) - getKey.then().statusCode(200) - def keyVerification = getKey.then().extract().path("apiKey") - Assert.assertTrue(key == keyVerification) - - Reporter.log("- Re-generate API keys. Key for ${usernameRt} re-generated successfully", true) - } - - @Test(priority=5, groups=["pro"], dataProvider = "groups", testName = "Create a group") - void createGroupTest(groupName){ - Response create = createGroup(groupName) - create.then().statusCode(201) - - Response get = getGroup(groupName) - get.then().statusCode(200) - def name = get.then().extract().path("name") - def adminPrivileges = get.then().extract().path("adminPrivileges") - Assert.assertTrue(name == groupName) - Assert.assertTrue(adminPrivileges == false) - - Reporter.log("- Create group. Group ${groupName} was successfully created", true) - } - - @Test(priority=6, groups=["pro"], testName = "Create and verify permissions") - void createPermissionsTest(){ - def permissionName = "testPermission" - def repository = "ANY" - def user1 = "testuser0" - def user2 = "testuser1" - def group1 = "test-group-0" - def group2 = "test-group-1" - def action1 = "read" - def action2 = "write" - def action3 = "manage" - Response create = createPermissions(permissionName, repository, user1, user2, - group1, group2, action1, action2, action3) - create.then().statusCode(200) - - Response get = getPermissions(permissionName) - get.then().statusCode(200) - Assert.assertTrue(permissionName == get.then().extract().path("name")) - Assert.assertTrue(repository == get.then().extract().path("repo.repositories[0]")) - Assert.assertTrue(action1 == get.then().extract().path("repo.actions.users.${user1}[0]")) - Assert.assertTrue(action2 == get.then().extract().path("repo.actions.users.${user1}[1]")) - Assert.assertTrue(action3 == get.then().extract().path("repo.actions.users.${user1}[2]")) - Assert.assertTrue(action1 == get.then().extract().path("repo.actions.users.${user2}[0]")) - Assert.assertTrue(action2 == get.then().extract().path("repo.actions.users.${user2}[1]")) - Assert.assertTrue(action3 == get.then().extract().path("repo.actions.users.${user2}[2]")) - Assert.assertTrue(action1 == get.then().extract().path("repo.actions.groups.${group1}[0]")) - Assert.assertTrue(action2 == get.then().extract().path("repo.actions.groups.${group2}[1]")) - Assert.assertTrue(action1 == get.then().extract().path("repo.actions.groups.${group2}[0]")) - Assert.assertTrue(action2 == get.then().extract().path("repo.actions.groups.${group2}[1]")) - - Reporter.log("- Create permissions. Permissions successfully created and verified", true) - } - - @Test(priority=7, groups=["pro"], testName = "Delete permissions") - void deletePermissionsTest(){ - def permissionName = "testPermission" - Response delete = deletePermissions(permissionName) - delete.then().statusCode(200) - Reporter.log("- Delete permissions. User ${permissionName} has been removed successfully", true) - } - - @Test(priority=8, groups=["pro"], dataProvider = "users", testName = "Delete non-default users") - void deleteUserTest(usernameRt, email, passwordRt){ - Response delete = deleteUser(usernameRt) - delete.then().statusCode(200).body(Matchers.containsString("${usernameRt}")) - Reporter.log("- Delete user. User ${usernameRt} has been removed successfully", true) - } - - @Test(priority=9, groups=["pro"], dataProvider = "groups", testName = "Delete non-default groups") - void deleteGroupTest(groupName){ - Response delete = deleteGroup(groupName) - delete.then().statusCode(200).body(Matchers.containsString("${groupName}")) - Reporter.log("- Delete group. Group ${groupName} has been removed successfully", true) - } - -} diff --git a/Ansible/test/tests/src/test/groovy/tests/XrayTest.groovy b/Ansible/test/tests/src/test/groovy/tests/XrayTest.groovy deleted file mode 100644 index ef6e4c4..0000000 --- a/Ansible/test/tests/src/test/groovy/tests/XrayTest.groovy +++ /dev/null @@ -1,332 +0,0 @@ -package tests - -import io.restassured.RestAssured -import io.restassured.response.Response -import org.testng.Assert -import org.testng.Reporter -import org.testng.annotations.BeforeSuite -import org.testng.annotations.BeforeTest -import org.testng.annotations.Test -import org.yaml.snakeyaml.Yaml -import steps.XraySteps - -import java.time.LocalDate - -import static org.hamcrest.Matchers.containsStringIgnoringCase -import static org.hamcrest.Matchers.emptyArray -import static org.hamcrest.Matchers.equalTo -import static org.hamcrest.Matchers.hasItem -import static org.hamcrest.Matchers.is -import static org.hamcrest.Matchers.isA -import static org.hamcrest.Matchers.not -import static org.hamcrest.Matchers.notNullValue -import static org.hamcrest.Matchers.nullValue - - -class XrayTest extends XraySteps{ - - Yaml yaml = new Yaml() - def configFile = new File("./src/test/resources/testenv.yaml") - def config = yaml.load(configFile.text) - def artifactoryURL - def distribution - def username - def password - def randomIndex - def policyName - def watchName - - @BeforeSuite(groups=["xray"]) - def setUp() { - artifactoryURL = config.artifactory.external_ip - distribution = config.artifactory.distribution - username = config.artifactory.rt_username - password = config.artifactory.rt_password - RestAssured.authentication = RestAssured.basic(username, password) - RestAssured.useRelaxedHTTPSValidation() - Random random = new Random() - randomIndex = random.nextInt(10000000) - policyName = "security_policy_${randomIndex}" - watchName = "all-repositories_${randomIndex}" - } - @BeforeTest(groups=["xray"]) - def testSetUp() { - RestAssured.baseURI = "http://${artifactoryURL}/xray/api" - } - - @Test(priority=1, groups=["xray"], dataProvider = "issueEvents", testName = "Create Issue Event") - void createIssueEventTest(issueID, cve, summary, description){ - Response create = createIssueEvent(issueID+randomIndex, cve, summary, description, username, password) - create.then().statusCode(201) - Response get = getIssueEvent(issueID+randomIndex, username, password) - get.then().statusCode(200) - def issueIDverification = get.then().extract().path("id") - def cveVerification = get.then().extract().path("source_id") - def summaryVerification = get.then().extract().path("summary") - def descriptionVerification = get.then().extract().path("description") - Assert.assertTrue(issueID+randomIndex == issueIDverification) - Assert.assertTrue(cve == cveVerification) - Assert.assertTrue(summary == summaryVerification) - Assert.assertTrue(description == descriptionVerification) - - Reporter.log("- Create issue event. Issue event with ID ${issueID+randomIndex} created and verified successfully", true) - } - - @Test(priority=2, groups=["xray"], dataProvider = "issueEvents", testName = "Update Issue Event", - dependsOnMethods = "createIssueEventTest") - void updateIssueEventTest(issueID, cve, summary, description){ - cve = "CVE-2017-0000000" - summary = "Updated" - description = "Updated" - Response update = updateIssueEvent(issueID+randomIndex, cve, summary, description, username, password) - update.then().statusCode(200) - Response get = getIssueEvent(issueID+randomIndex, username, password) - get.then().statusCode(200) - def cveVerification = get.then().extract().path("source_id") - def summaryVerification = get.then().extract().path("summary") - def descriptionVerification = get.then().extract().path("description") - Assert.assertTrue(cve == cveVerification) - Assert.assertTrue(summary == summaryVerification) - Assert.assertTrue(description == descriptionVerification) - - Reporter.log("- Update issue event. Issue event with ID ${issueID+randomIndex} updated and verified successfully", true) - } - - @Test(priority=3, groups=["xray"], testName = "Create policy") - void createPolicyTest(){ - Response create = createPolicy(policyName, username, password) - create.then().statusCode(201) - - Response get = getPolicy(policyName, username, password) - get.then().statusCode(200) - def policyNameVerification = get.then().extract().path("name") - Assert.assertTrue(policyName == policyNameVerification) - - Reporter.log("- Create policy. Policy with name ${policyName} created and verified successfully", true) - } - - @Test(priority=4, groups=["xray"], testName = "Update policy", dependsOnMethods = "createPolicyTest") - void updatePolicyTest(){ - def description = "Updated description" - Response update = updatePolicy(policyName, description, username, password) - update.then().statusCode(200) - - Response get = getPolicy(policyName, username, password) - get.then().statusCode(200) - def descriptionVerification = get.then().extract().path("description") - Assert.assertTrue(description == descriptionVerification) - - Reporter.log("- Update policy. Policy with name ${policyName} updated and verified successfully", true) - } - - @Test(priority=4, groups=["xray"], testName = "Get policies") - void getPoliciesTest(){ - Response response = getPolicies(username, password) - response.then().statusCode(200) - .body("name", notNullValue()) - .body("type", notNullValue()) - .body("description", notNullValue()) - .body("author", notNullValue()) - .body("rules", notNullValue()) - .body("created", notNullValue()) - .body("modified", notNullValue()) - def policies = response.then().extract().path("name") - Reporter.log("- Get policies. Policies list is returned successfully. " + - "Policies returned: ${policies}", true) - } - - @Test(priority=5, groups=["xray"], testName = "Create watch for the repositories", dependsOnMethods = "createPolicyTest") - void createWatchTest(){ - Response create = createWatchEvent(watchName, policyName, username, password) - create.then().statusCode(201) - .body("info", - equalTo("Watch has been successfully created")) - - Response get = getWatchEvent(watchName, username, password) - get.then().statusCode(200) - .body("general_data.name", equalTo((watchName).toString())) - - Reporter.log("- Create watch. Watch with name ${watchName} has been created and verified successfully", true) - } - - @Test(priority=6, groups=["xray"], testName = "Update watch for the repositories", dependsOnMethods = "createWatchTest") - void updateWatchTest(){ - def description = "Updated watch" - Response create = updateWatchEvent(watchName, description, policyName, username, password) - create.then().statusCode(200) - .body("info", - equalTo("Watch was successfully updated")) - - Response get = getWatchEvent(watchName, username, password) - get.then().statusCode(200) - .body("general_data.description", equalTo(description)) - - Reporter.log("- Update watch. Watch with name ${watchName} has been updated and verified successfully", true) - } - - @Test(priority=7, groups=["xray"], testName = "Assign policy to watches") - void assignPolicyToWatchTest(){ - Response response = assignPolicy(watchName, policyName, username, password) - response.then().statusCode(200) - .body("result.${watchName}", - equalTo("Policy assigned successfully to Watch")) - - Reporter.log("- Assign policy to watch. Policy assigned successfully to Watch", true) - } - - @Test(priority=8, groups=["xray"], testName = "Delete watch") - void deleteWatchTest(){ - Response response = deleteWatchEvent(watchName, username, password) - response.then().statusCode(200) - .body("info", - equalTo("Watch was deleted successfully")) - - Reporter.log("- Delete watch. Watch ${watchName} has been successfully deleted", true) - } - - @Test(priority=9, groups=["xray"], testName = "Delete policy") - void deletePolicyTest(){ - - Response response = deletePolicy(policyName, username, password) - response.then().statusCode(200) - .body("info", - equalTo(("Policy ${policyName} was deleted successfully").toString())) - - Reporter.log("- Delete policy. Policy ${policyName} has been successfully deleted", true) - } - -/* @Test(priority=10, groups=["xray"], testName = "Start scan") - void startScanTest(){ - def artifactPath = "default/generic-dev-local/test-directory/artifact.zip" - Response getSha = artifactSummary(username, password, artifactPath) - def componentID = getSha.then().extract().path("artifacts[0].licenses[0].components[0]") - - Response scan = startScan(username, password, componentID) - scan.then().statusCode(200) - .body("info", - equalTo(("Scan of artifact is in progress").toString())) - - Reporter.log("- Start scan. Scan of ${componentID} has been started successfully", true) - }*/ - - @Test(priority=11, groups=["xray"], testName = "Create and get integration configuration") - void integrationConfigurationTest(){ - def vendorName = "vendor_${randomIndex}" - Response post = addtIntegrationConfiguration(username, password, vendorName) - post.then().statusCode(200) - - Response get = getIntegrationConfiguration(username, password) - int bodySize = get.body().jsonPath().getList(".").size() - get.then().statusCode(200) - .body("[" + (bodySize-1) + "].vendor", equalTo(vendorName.toString())) - - Reporter.log("- Integration configuration. " + - "Configuration for vendor ${vendorName} has been successfully added and verified", true) - } - - @Test(priority=12, groups=["xray"], testName = "Enable TLS for RabbitMQ") - void enableTLSRabbitMQTest(){ - File body = new File("./src/test/resources/enableRabbitMQ.json") - Response post = postSystemParameters(username, password, body) - post.then().statusCode(200) - - Response get = getSystemParameters(username, password) - get.then().statusCode(200).body("enableTlsConnectionToRabbitMQ", equalTo(true)) - - Reporter.log("- Enable TLS for RabbitMQ. TLS for RabbitMQ has been successfully enabled and verified", true) - } - - @Test(priority=13, groups=["xray"], testName = "Get binary manager") - void getBinaryManagerTest(){ - Response response = getBinaryManager(username, password) - response.then().statusCode(200) - .body("binMgrId", equalTo("default")) - .body("license_valid", equalTo(true)) - .body("binMgrId", equalTo("default")) - def version = response.then().extract().path("version") - - Reporter.log("- Get binary manager. Binary manager is verified, connected RT version: ${version}", true) - } - - @Test(priority=14, groups=["xray"], testName = "Get repo indexing configuration") - void getIndexingConfigurationTest(){ - Response response = getIndexingConfiguration(username, password) - response.then().statusCode(200) - .body("bin_mgr_id", equalTo("default")) - .body("indexed_repos.name", hasItem("generic-dev-local")) - - Reporter.log("- Get repo indexing configuration.", true) - } - - @Test(priority=15, groups=["xray"], testName = "Update repo indexing configuration") - void updateIndexingConfigurationTest(){ - Response response = updateIndexingConfiguration(username, password) - response.then().statusCode(200) - .body("info", equalTo("Repositories list has been successfully sent to Artifactory")) - - Reporter.log("- Update repo indexing configuration. Successfully updated", true) - } - - // Force reindex test, add in latest versions of X-ray - -/* @Test(priority=16, groups=["xray"], testName = "Get artifact summary") - void artifactSummaryTest(){ - def artifactPath = "default/generic-dev-local/test-directory/artifact.zip" - Response post = artifactSummary(username, password, artifactPath) - post.then().statusCode(200) - .body("artifacts[0].general.path", equalTo(artifactPath)) - - Reporter.log("- Get artifact summary. Artifact summary has been returned successfully", true) - }*/ - - @Test(priority=17, groups=["xray"], testName = "Create support bundle") - void createSupportBundleTest(){ - def name = "Support Bundle" - LocalDate startDate = LocalDate.now().minusDays(5) - LocalDate endDate = LocalDate.now() - Response response = createSupportBundle(username, password, name, startDate, endDate) - def bundle_url = response.then().extract().path("artifactory.bundle_url") - if ((bundle_url.toString()).contains(artifactoryURL)) { - Reporter.log("- Create support bundle. Successfully created using X-ray API", true) - } else if (((bundle_url.toString()).contains("localhost"))){ - Reporter.log("- Create support bundle. Created with a bug, localhost instead of the hostname", true) - } - } - - @Test(priority=18, groups=["xray"], testName = "Get system monitoring status") - void getSystemMonitoringTest(){ - Response response = getSystemMonitoringStatus(username, password) - response.then().statusCode(200) - - Reporter.log("- Get system monitoring status. Data returned successfully", true) - } - - @Test(priority=19, groups=["xray"], testName = "X-ray ping request") - void xrayPingRequestTest(){ - Response response = xrayPingRequest(username, password) - response.then().statusCode(200) - .body("status", equalTo("pong")) - - Reporter.log("- Get system monitoring status. Data returned successfully", true) - } - - @Test(priority=20, groups=["xray"], testName = "X-ray version") - void xrayGetVersionTest(){ - Response response = xrayGetVersion(username, password) - response.then().statusCode(200) - .body("xray_version", notNullValue()) - .body("xray_revision", notNullValue()) - def version = response.then().extract().path("xray_version") - def revision = response.then().extract().path("xray_revision") - - Reporter.log("- Get X-ray version. Version: ${version}, revision: ${revision}", true) - } - - - - -} - - - - From f19ac8e3d8ce5e2efcce5a6946d7d07f3a89894a Mon Sep 17 00:00:00 2001 From: Jeff Fry Date: Thu, 29 Oct 2020 14:18:07 -0700 Subject: [PATCH 5/5] Updated README, CHANGELOG. Added 1.1.2 package. --- Ansible/CHANGELOG.md | 12 ++++- Ansible/README.md | 2 + .../jfrog/installers/galaxy.yml | 2 +- .../installers/jfrog-installers-1.1.0.tar.gz | Bin 31110 -> 0 bytes .../installers/jfrog-installers-1.1.2.tar.gz | Bin 0 -> 31828 bytes .../installers/roles/artifactory/README.md | 2 + .../roles/artifactory/defaults/main.yml | 4 ++ .../roles/artifactory/tasks/install.yml | 28 ++++++++-- .../artifactory/tasks/legacy_migration.yml | 34 ++++++++++++ .../roles/artifactory/tasks/main.yml | 50 ++++++++++++++--- .../roles/artifactory/tasks/upgrade.yml | 51 ++++++++++++++---- .../artifactory/templates/system.yaml.j2 | 12 +++-- Openshift4/helm/openshift-xray/LICENSE | 0 .../helm-charts/openshift-xray/README.md | 0 14 files changed, 173 insertions(+), 24 deletions(-) delete mode 100644 Ansible/ansible_collections/jfrog/installers/jfrog-installers-1.1.0.tar.gz create mode 100644 Ansible/ansible_collections/jfrog/installers/jfrog-installers-1.1.2.tar.gz create mode 100644 Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/legacy_migration.yml mode change 100755 => 100644 Openshift4/helm/openshift-xray/LICENSE mode change 100755 => 100644 Openshift4/operator/xray-operator/helm-charts/openshift-xray/README.md diff --git a/Ansible/CHANGELOG.md b/Ansible/CHANGELOG.md index 25ace90..ece5411 100644 --- a/Ansible/CHANGELOG.md +++ b/Ansible/CHANGELOG.md @@ -2,10 +2,20 @@ All notable changes to this project will be documented in this file. +## [1.1.2] - 2020-10-29 +- Updated default versions to RT 7.10.2 and Xray 3.10.3. +- Removed obsolete gradle tests. + +## [1.1.1] - 2020-10-15 +- added idempotence to artifactory installer +- added fix for derby deployments +- Migration to reduce changes during playbook runs contains breaking changes. You either must run once before upgrade, or provide playbook with valid credentials to access version information for it to perform properly. +- First time installers need not worry about above + ## [1.1.0] - 2020-09-27 - Validated for Artifactory 7.7.8 and Xray 3.8.6. - Added offline support for Artifactory and Xray. - Added support for configurable Postgres pg_hba.conf. - Misc fixes due to Artifactory 7.7.8. -- Published 1.1.0 to [Ansible Galaxy](https://galaxy.ansible.com/jfrog/installers). \ No newline at end of file +- Published 1.1.0 to [Ansible Galaxy](https://galaxy.ansible.com/jfrog/installers). diff --git a/Ansible/README.md b/Ansible/README.md index f22db8d..aaaf08d 100644 --- a/Ansible/README.md +++ b/Ansible/README.md @@ -12,6 +12,8 @@ This Ansible directory consists of the following directories that support the JF | collection_version | artifactory_version | xray_version | |--------------------|---------------------|--------------| +| 1.1.2 | 7.10.2 | 3.10.3 | +| 1.1.1 | 7.10.2 | 3.9.1 | | 1.1.0 | 7.7.8 | 3.8.6 | | 1.0.9 | 7.7.3 | 3.8.0 | | 1.0.8 | 7.7.3 | 3.8.0 | diff --git a/Ansible/ansible_collections/jfrog/installers/galaxy.yml b/Ansible/ansible_collections/jfrog/installers/galaxy.yml index 64bf9c9..d407f59 100644 --- a/Ansible/ansible_collections/jfrog/installers/galaxy.yml +++ b/Ansible/ansible_collections/jfrog/installers/galaxy.yml @@ -9,7 +9,7 @@ namespace: "jfrog" name: "installers" # The version of the collection. Must be compatible with semantic versioning -version: "1.1.0" +version: "1.1.2" # The path to the Markdown (.md) readme file. This path is relative to the root of the collection readme: "README.md" diff --git a/Ansible/ansible_collections/jfrog/installers/jfrog-installers-1.1.0.tar.gz b/Ansible/ansible_collections/jfrog/installers/jfrog-installers-1.1.0.tar.gz deleted file mode 100644 index 5e8aebb43e15bc5664720581957dbad6f873318c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31110 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 GH}>;{%goKDv+VkE)z?d6$lCnl1}_CL<+Ch0 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 diff --git a/Ansible/ansible_collections/jfrog/installers/jfrog-installers-1.1.2.tar.gz b/Ansible/ansible_collections/jfrog/installers/jfrog-installers-1.1.2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..a9fdeb67f4a74b4a7af2c556480e1e0bcabe915b GIT binary patch literal 31828 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
    AS}r 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 MxTznd79HjP0UTH$`2YX_ literal 0 HcmV?d00001 diff --git a/Ansible/ansible_collections/jfrog/installers/roles/artifactory/README.md b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/README.md index 8847ec0..50ecaf6 100644 --- a/Ansible/ansible_collections/jfrog/installers/roles/artifactory/README.md +++ b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/README.md @@ -1,6 +1,8 @@ # artifactory The artifactory role installs the Artifactory Pro software onto the host. Per the Vars below, it will configure a node as primary or secondary. This role uses secondary roles artifactory_nginx to install nginx. +1.1.1 contains breaking changes. To mitigate this, use the role before doing any upgrades, let it mitigate the path changes, and then run again with your upgrade. + ## Role Variables * _artifactory_version_: The version of Artifactory to install. eg. "7.4.1" * _master_key_: This is the Artifactory [Master Key](https://www.jfrog.com/confluence/display/JFROG/Managing+Keys). See below to [autogenerate this key](#autogenerating-master-and-join-keys). diff --git a/Ansible/ansible_collections/jfrog/installers/roles/artifactory/defaults/main.yml b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/defaults/main.yml index 64a426c..1a8ca54 100644 --- a/Ansible/ansible_collections/jfrog/installers/roles/artifactory/defaults/main.yml +++ b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/defaults/main.yml @@ -50,3 +50,7 @@ service_list: # if this is an upgrade artifactory_upgrade_only: false + +#default username and password +artifactory_app_username: admin +artifactory_app_user_pass: password diff --git a/Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/install.yml b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/install.yml index a0e98ff..9537459 100644 --- a/Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/install.yml +++ b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/install.yml @@ -52,8 +52,30 @@ until: downloadartifactory is succeeded retries: 3 -- name: MV untar directory to artifactory home - command: "mv {{ artifactory_untar_home }} {{ artifactory_home }}" +- name: Create artifactory home folder + file: + state: directory + path: "{{ artifactory_home }}" + owner: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" + become: yes + +- name: Create Symlinks for var folder + file: + state: link + src: "{{ artifactory_untar_home }}/var" + dest: "{{ artifactory_home }}/var" + owner: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" + become: yes + +- name: Create Symlinks for app folder + file: + state: link + src: "{{ artifactory_untar_home }}/app" + dest: "{{ artifactory_home }}/app" + owner: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" become: yes - name: ensure artifactory_file_store_dir exists @@ -180,7 +202,7 @@ - name: Ensure permissions are correct file: - path: "{{ artifactory_home }}" + path: "{{ jfrog_home_directory }}" group: "{{ artifactory_group }}" owner: "{{ artifactory_user }}" recurse: yes diff --git a/Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/legacy_migration.yml b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/legacy_migration.yml new file mode 100644 index 0000000..e3e15d5 --- /dev/null +++ b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/legacy_migration.yml @@ -0,0 +1,34 @@ +--- +- name: MV artifactory home to artifactory untar home + command: "mv {{ artifactory_home }} {{ temp_untar_home }}" + become: yes +- name: Ensure untar home permissions are correct + file: + state: directory + path: "{{ temp_untar_home }}" + owner: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" + become: yes +- name: Create artifactory home folder + file: + state: directory + path: "{{ artifactory_home }}" + owner: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" + become: yes +- name: Create Symlinks for var folder + file: + state: link + src: "{{ temp_untar_home }}/var" + dest: "{{ artifactory_home }}/var" + owner: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" + become: yes +- name: Create Symlinks for app folder + file: + state: link + src: "{{ temp_untar_home }}/app" + dest: "{{ artifactory_home }}/app" + owner: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" + become: yes diff --git a/Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/main.yml b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/main.yml index 3afccb3..65728de 100644 --- a/Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/main.yml +++ b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/main.yml @@ -1,6 +1,44 @@ -- name: perform installation - include_tasks: "install.yml" - when: not artifactory_upgrade_only -- name: perform upgrade - include_tasks: "upgrade.yml" - when: artifactory_upgrade_only \ No newline at end of file +- name: Rectify Legacy Installation Block + block: + - name: Check to see if artifactory has a service and stop it + service: + name: artifactory + state: stopped + become: yes + - name: Check symlink method + stat: + path: /opt/jfrog/artifactory/app + register: newMethod + - name: Check artifactory version + uri: + url: "{{ web_method }}://{{ artifactory_server_url }}:{{ url_port }}/artifactory/api/system/version" + url_username: "{{ artifactory_app_username }}" + url_password: "{{ artifactory_app_user_pass }}" + register: artifactory_installed_version + - name: Debug defunct installation + debug: + var: artifactory_installed_version.json.version + - name: Setup temporary untar home + set_fact: + temp_untar_home: "{{ jfrog_home_directory }}/artifactory-{{ artifactory_flavour }}-{{ artifactory_installed_version }}" + - name: Rectify legacy installation + include_tasks: "legacy_migration.yml" + when: (not newMethod.stat.islnk) and newMethod.stat.exists + rescue: + - name: Check to see if artifactory has a service and stop it + service: + name: artifactory + state: stopped + - name: Setup temporary untar home (assuming version is set var for version) + set_fact: + temp_untar_home: "{{ jfrog_home_directory }}/artifactory-{{ artifactory_flavour }}-{{ artifactory_version }}" + - name: Rectify legacy installation + include_tasks: "legacy_migration.yml" + when: (not newMethod.stat.islnk) and newMethod.stat.exists + always: + - name: perform installation + include_tasks: "install.yml" + when: not artifactory_upgrade_only + - name: perform upgrade + include_tasks: "upgrade.yml" + when: artifactory_upgrade_only \ No newline at end of file diff --git a/Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/upgrade.yml b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/upgrade.yml index a0273dd..5ac0fd8 100644 --- a/Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/upgrade.yml +++ b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/tasks/upgrade.yml @@ -14,6 +14,19 @@ state: directory become: yes +- name: Local Copy artifactory + unarchive: + src: "{{ local_artifactory_tar }}" + dest: "{{ jfrog_home_directory }}" + owner: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" + creates: "{{ artifactory_untar_home }}" + become: yes + when: local_artifactory_tar is defined + register: downloadartifactory + until: downloadartifactory is succeeded + retries: 3 + - name: download artifactory unarchive: src: "{{ artifactory_tar }}" @@ -23,24 +36,42 @@ group: "{{ artifactory_group }}" creates: "{{ artifactory_untar_home }}" become: yes + when: artifactory_tar is defined register: downloadartifactory until: downloadartifactory is succeeded retries: 3 -- name: Delete artifactory app +#- name: Delete artifactory app +# file: +# path: "{{ artifactory_home }}/app" +# state: absent +# become: yes + +#- name: CP new app to artifactory app +# command: "cp -r {{ artifactory_untar_home }}/app {{ artifactory_home }}/app" +# become: yes + +#- name: Delete untar directory +# file: +# path: "{{ artifactory_untar_home }}" +# state: absent +# become: yes + +- name: Create Symlinks for app folder file: - path: "{{ artifactory_home }}/app" - state: absent + state: link + src: "{{ artifactory_untar_home }}/app" + dest: "{{ artifactory_home }}/app" + owner: "{{ artifactory_user }}" + group: "{{ artifactory_group }}" become: yes -- name: CP new app to artifactory app - command: "cp -r {{ artifactory_untar_home }}/app {{ artifactory_home }}/app" - become: yes - -- name: Delete untar directory +- name: Ensure permissions are correct file: - path: "{{ artifactory_untar_home }}" - state: absent + path: "{{ jfrog_home_directory }}" + group: "{{ artifactory_group }}" + owner: "{{ artifactory_user }}" + recurse: yes become: yes - name: start and enable the primary node diff --git a/Ansible/ansible_collections/jfrog/installers/roles/artifactory/templates/system.yaml.j2 b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/templates/system.yaml.j2 index 419a0c3..a7fede0 100644 --- a/Ansible/ansible_collections/jfrog/installers/roles/artifactory/templates/system.yaml.j2 +++ b/Ansible/ansible_collections/jfrog/installers/roles/artifactory/templates/system.yaml.j2 @@ -32,7 +32,13 @@ shared: ## Example for mysql/postgresql type: "{{ db_type }}" - driver: "{{ db_driver }}" - url: "{{ db_url }}" - username: "{{ db_user }}" +{%+ if db_type == 'derby' -%} +# driver: "{{ db_driver }}" +# url: "{{ db_url }}" +# username: "{{ db_user }}" +{%+ else -%} + driver: "{{ db_driver }}" + url: "{{ db_url }}" + username: "{{ db_user }}" +{%+ endif -%} password: "{{ db_password }}" \ No newline at end of file diff --git a/Openshift4/helm/openshift-xray/LICENSE b/Openshift4/helm/openshift-xray/LICENSE old mode 100755 new mode 100644 diff --git a/Openshift4/operator/xray-operator/helm-charts/openshift-xray/README.md b/Openshift4/operator/xray-operator/helm-charts/openshift-xray/README.md old mode 100755 new mode 100644