From c0d17fe3de87ab0ed9fdf4ac8c5090b3d53a5836 Mon Sep 17 00:00:00 2001 From: Gl4di4torRr Date: Mon, 8 Oct 2018 12:06:18 -0400 Subject: [PATCH] add multi cluster example --- .DS_Store | Bin 0 -> 6148 bytes multi-cluster-spring-boot/README.md | 56 ++++++- .../inventory-dev/group_vars/seed-hosts.yml | 30 ++++ .../.applier}/inventory-dev/hosts | 0 .../group_vars/seed-hosts.yml | 11 ++ .../.applier/inventory-pre-dev}/hosts | 0 .../inventory-prod/group_vars/seed-hosts.yml | 15 ++ .../.applier/inventory-prod/hosts | 2 + .../.applier/params/build-dev | 9 ++ .../.applier}/params/deployment-dev | 0 .../.applier/params/deployment-prod | 5 + .../.applier}/params/deployment-stage | 0 .../.applier}/params/jenkins | 0 .../.applier/params/nonprod-credentials | 2 + .../.applier/params/prod-cluster-credentials | 4 + .../.applier/params/prod-credentials | 2 + .../params/registry-sa-nonprod-cluster | 2 + .../.applier/params/registry-sa-prod-cluster | 2 + .../.applier}/projects/projects-prod.yml | 0 .../.applier}/projects/projects.yml | 0 .../.applier/templates/build.yml | 142 +++++++++++++++++ .../.applier}/templates/cluster-secret.yml | 0 .../.applier}/templates/deployment.yml | 0 .../.applier/templates/image-mirror-sa.yml | 33 ++++ .../templates/image-mirror-secret.yml | 29 ++++ .../image-mirror-example/.gitignore | 1 + .../image-mirror-example/Jenkinsfile | 124 +++++++++++++++ .../inventory-dev/group_vars/seed-hosts.yml | 0 .../.applier/inventory-dev/hosts | 2 + .../inventory-prod/group_vars/seed-hosts.yml | 0 .../.applier/inventory-prod/hosts | 2 + .../.applier}/params/build-dev | 2 +- .../.applier}/params/build-slave-dev | 0 .../.applier/params/deployment-dev | 5 + .../.applier}/params/deployment-prod | 0 .../.applier/params/deployment-stage | 6 + .../skopeo-example/.applier/params/jenkins | 1 + .../.applier/projects/projects-prod.yml | 9 ++ .../.applier/projects/projects.yml | 15 ++ .../.applier}/projects/promoter-sa.yml | 0 .../.applier}/templates/build.yml | 0 .../.applier/templates/cluster-secret.yml | 35 +++++ .../.applier/templates/deployment.yml | 145 ++++++++++++++++++ .../{ => skopeo-example}/Jenkinsfile | 0 44 files changed, 686 insertions(+), 5 deletions(-) create mode 100644 .DS_Store create mode 100644 multi-cluster-spring-boot/image-mirror-example/.applier/inventory-dev/group_vars/seed-hosts.yml rename multi-cluster-spring-boot/{applier => image-mirror-example/.applier}/inventory-dev/hosts (100%) create mode 100644 multi-cluster-spring-boot/image-mirror-example/.applier/inventory-pre-dev/group_vars/seed-hosts.yml rename multi-cluster-spring-boot/{applier/inventory-prod => image-mirror-example/.applier/inventory-pre-dev}/hosts (100%) create mode 100644 multi-cluster-spring-boot/image-mirror-example/.applier/inventory-prod/group_vars/seed-hosts.yml create mode 100644 multi-cluster-spring-boot/image-mirror-example/.applier/inventory-prod/hosts create mode 100644 multi-cluster-spring-boot/image-mirror-example/.applier/params/build-dev rename multi-cluster-spring-boot/{applier => image-mirror-example/.applier}/params/deployment-dev (100%) create mode 100644 multi-cluster-spring-boot/image-mirror-example/.applier/params/deployment-prod rename multi-cluster-spring-boot/{applier => image-mirror-example/.applier}/params/deployment-stage (100%) rename multi-cluster-spring-boot/{applier => image-mirror-example/.applier}/params/jenkins (100%) create mode 100644 multi-cluster-spring-boot/image-mirror-example/.applier/params/nonprod-credentials create mode 100644 multi-cluster-spring-boot/image-mirror-example/.applier/params/prod-cluster-credentials create mode 100644 multi-cluster-spring-boot/image-mirror-example/.applier/params/prod-credentials create mode 100644 multi-cluster-spring-boot/image-mirror-example/.applier/params/registry-sa-nonprod-cluster create mode 100644 multi-cluster-spring-boot/image-mirror-example/.applier/params/registry-sa-prod-cluster rename multi-cluster-spring-boot/{applier => image-mirror-example/.applier}/projects/projects-prod.yml (100%) rename multi-cluster-spring-boot/{applier => image-mirror-example/.applier}/projects/projects.yml (100%) create mode 100644 multi-cluster-spring-boot/image-mirror-example/.applier/templates/build.yml rename multi-cluster-spring-boot/{applier => image-mirror-example/.applier}/templates/cluster-secret.yml (100%) rename multi-cluster-spring-boot/{applier => image-mirror-example/.applier}/templates/deployment.yml (100%) create mode 100644 multi-cluster-spring-boot/image-mirror-example/.applier/templates/image-mirror-sa.yml create mode 100644 multi-cluster-spring-boot/image-mirror-example/.applier/templates/image-mirror-secret.yml create mode 100644 multi-cluster-spring-boot/image-mirror-example/.gitignore create mode 100644 multi-cluster-spring-boot/image-mirror-example/Jenkinsfile rename multi-cluster-spring-boot/{applier => skopeo-example/.applier}/inventory-dev/group_vars/seed-hosts.yml (100%) create mode 100644 multi-cluster-spring-boot/skopeo-example/.applier/inventory-dev/hosts rename multi-cluster-spring-boot/{applier => skopeo-example/.applier}/inventory-prod/group_vars/seed-hosts.yml (100%) create mode 100644 multi-cluster-spring-boot/skopeo-example/.applier/inventory-prod/hosts rename multi-cluster-spring-boot/{applier => skopeo-example/.applier}/params/build-dev (72%) rename multi-cluster-spring-boot/{applier => skopeo-example/.applier}/params/build-slave-dev (100%) create mode 100644 multi-cluster-spring-boot/skopeo-example/.applier/params/deployment-dev rename multi-cluster-spring-boot/{applier => skopeo-example/.applier}/params/deployment-prod (100%) create mode 100644 multi-cluster-spring-boot/skopeo-example/.applier/params/deployment-stage create mode 100644 multi-cluster-spring-boot/skopeo-example/.applier/params/jenkins create mode 100644 multi-cluster-spring-boot/skopeo-example/.applier/projects/projects-prod.yml create mode 100644 multi-cluster-spring-boot/skopeo-example/.applier/projects/projects.yml rename multi-cluster-spring-boot/{applier => skopeo-example/.applier}/projects/promoter-sa.yml (100%) rename multi-cluster-spring-boot/{applier => skopeo-example/.applier}/templates/build.yml (100%) create mode 100644 multi-cluster-spring-boot/skopeo-example/.applier/templates/cluster-secret.yml create mode 100644 multi-cluster-spring-boot/skopeo-example/.applier/templates/deployment.yml rename multi-cluster-spring-boot/{ => skopeo-example}/Jenkinsfile (100%) diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..918e82d0800924835f1c2d8931d80152b57a7fe8 GIT binary patch literal 6148 zcmeHKyH3ME5S)b+k!Vtq?tXxRKR89<3-SYqfTBpoL5V}{F29}G2MEiir9ivZ?)cU_ zck&coF92DcUmt-5fH_?e7Y$?6=jtQ7iHs2G++&XiY|-G1)2Mnnq1+|j$!O3G_#NJG zh8PjIGw^@Q%G(oI^y(2R;aVpWN5+jB*(dQ w*B1IS{mWQu ... - $ ansible-playbook -i ./applier/inventory-prod/ galaxy/openshift-applier/playbooks/openshift-cluster-seed.yml + $ ansible-playbook -i image-mirror-example/.applier/inventory-prod/ galaxy/openshift-applier/playbooks/openshift-cluster-seed.yml + ``` +5. One of the things that was created by ansible is a `ServiceAccount` that will be used for promoting your app from _Dev_ to _Prod_. We'll need to extract its credentials so that our pipeline can use that account. + ``` + $ TOKEN=$(oc serviceaccounts get-token docker-registry-prod -n multicluster-spring-boot-prod) + ``` + The Ansible automation for your _Dev_ cluster will expect a parameters file to be created at `./applier/params/prod-credentials`. It should look something like this: + ``` + $ echo "TOKEN=${TOKEN} + SECRET_NAME=prod-credentials" > image-mirror-example/.applier/params/prod-credentials + ``` +6. We need to create the the *prod-api-credentials* param file so our pipeline will be able to verify a successful deployment to production. + ``` + $ echo "TOKEN=${TOKEN} + API_URL= + REGISTRY_URL= + SECRET_NAME=prod-cluster-credentials" > image-mirror-example/.applier/params/prod-cluster-credentials + ``` +6. Now, Log into your _Dev_ cluster, and instantiate the pre-pipeline configuration. + ``` + $ oc login + ... + $ ansible-playbook -i image-mirror-example/.applier/inventory-pre-dev/ galaxy/openshift-applier/playbooks/openshift-cluster-seed.yml + ``` +7. Now the service account for the dev cluster docker registry has been created. We'll need to extract it's credentials so that our pipeline can authenticate to the dev cluster docker registry. + ``` + $ TOKEN=$(oc serviceaccounts get-token docker-registry-dev -n multicluster-spring-boot-stage) + $ echo "TOKEN=${TOKEN} + SECRET_NAME=nonprod-credentials" > image-mirror-example/.applier/params/nonprod-credentials + ``` +8. Now, we will instantiate the pipeline and all configuration in the non-production cluster. + ``` + $ ansible-playbook -i image-mirror-example/.applier/inventory-dev/ galaxy/openshift-applier/playbooks/openshift-cluster-seed.yml + ``` + +At this point you should have 3 projects deployed (`multicluster-spring-boot-dev`, `multicluster-spring-boot-stage`, and `multicluster-spring-boot-prod`) with our [Spring Rest](https://github.com/redhat-cop/spring-rest) demo application deployed to all 3. + +## Automated Quickstart for skopeo + +This quickstart can be deployed quickly using Ansible. Here are the steps. + +1. Clone [this repo](https://github.com/redhat-cop/container-pipelines) +2. `cd container-pipelines/multi-cluster-spring-boot` +3. Run `ansible-galaxy install -r requirements.yml --roles-path=galaxy` +4. Log into your _Prod_ OpenShift cluster, and run the following command. + ``` + $ oc login + ... + $ ansible-playbook -i skopeo-example/.applier/inventory-prod/ galaxy/openshift-applier/playbooks/openshift-cluster-seed.yml ``` 5. One of the things that was created by ansible is a `ServiceAccount` that will be used for promoting your app from _Dev_ to _Prod_. We'll need to extract its credentials so that our pipeline can use that account. ``` @@ -39,13 +87,13 @@ This quickstart can be deployed quickly using Ansible. Here are the steps. $ echo "TOKEN=${TOKEN} API_URL=https://master.example.com REGISTRY_URL=docker-registry-default.apps.example.com - " > ./applier/params/prod-credentials + " > skopeo-example/.applier/params/prod-credentials ``` 6. Now, Log into your _Dev_ cluster, and instantiate the pipeline. ``` $ oc login ... - $ ansible-playbook -i ./applier/inventory-dev/ galaxy/openshift-applier/playbooks/openshift-cluster-seed.yml + $ ansible-playbook -i skopeo-example/.applier/inventory-dev/ galaxy/openshift-applier/playbooks/openshift-cluster-seed.yml ``` At this point you should have 3 projects deployed (`multicluster-spring-boot-dev`, `multicluster-spring-boot-stage`, and `multicluster-spring-boot-prod`) with our [Spring Rest](https://github.com/redhat-cop/spring-rest) demo application deployed to all 3. diff --git a/multi-cluster-spring-boot/image-mirror-example/.applier/inventory-dev/group_vars/seed-hosts.yml b/multi-cluster-spring-boot/image-mirror-example/.applier/inventory-dev/group_vars/seed-hosts.yml new file mode 100644 index 00000000..446fb849 --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/.applier/inventory-dev/group_vars/seed-hosts.yml @@ -0,0 +1,30 @@ +openshift_cluster_content: +- object: deployments + content: + - name: "deploy jenkins" + template: "openshift//jenkins-ephemeral" + params: "{{ inventory_dir }}/../params/jenkins" + namespace: multicluster-spring-boot-dev + - name: "create prod cluster credential" + template: "{{ inventory_dir }}/../templates/cluster-secret.yml" + params: "{{ inventory_dir }}/../params/prod-cluster-credentials" + namespace: multicluster-spring-boot-dev + - name: "create image mirror nonprod secret" + template: "{{ inventory_dir }}/../templates/image-mirror-secret.yml" + params: "{{ inventory_dir }}/../params/nonprod-credentials" + namespace: multicluster-spring-boot-dev + - name: "create image mirror prod secret" + template: "{{ inventory_dir }}/../templates/image-mirror-secret.yml" + params: "{{ inventory_dir }}/../params/prod-credentials" + namespace: multicluster-spring-boot-dev + - name: "deploy dev environment" + template: "{{ inventory_dir }}/../templates/deployment.yml" + params: "{{ inventory_dir }}/../params/deployment-dev" + - name: "deply stage environment" + template: "{{ inventory_dir }}/../templates/deployment.yml" + params: "{{ inventory_dir }}/../params/deployment-stage" +- object: builds + content: + - name: "deploy build pipeline to dev" + template: "{{ inventory_dir }}/../templates/build.yml" + params: "{{ inventory_dir }}/../params/build-dev" diff --git a/multi-cluster-spring-boot/applier/inventory-dev/hosts b/multi-cluster-spring-boot/image-mirror-example/.applier/inventory-dev/hosts similarity index 100% rename from multi-cluster-spring-boot/applier/inventory-dev/hosts rename to multi-cluster-spring-boot/image-mirror-example/.applier/inventory-dev/hosts diff --git a/multi-cluster-spring-boot/image-mirror-example/.applier/inventory-pre-dev/group_vars/seed-hosts.yml b/multi-cluster-spring-boot/image-mirror-example/.applier/inventory-pre-dev/group_vars/seed-hosts.yml new file mode 100644 index 00000000..7ea143c3 --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/.applier/inventory-pre-dev/group_vars/seed-hosts.yml @@ -0,0 +1,11 @@ +openshift_cluster_content: +- object: projects + content: + - name: "create environments" + file: "{{ inventory_dir }}/../projects/projects.yml" + file_action: create +- object: deployments + content: + - name: "create image mirror service account" + template: "{{ inventory_dir }}/../templates/image-mirror-sa.yml" + params: "{{ inventory_dir }}/../params/registry-sa-nonprod-cluster" diff --git a/multi-cluster-spring-boot/applier/inventory-prod/hosts b/multi-cluster-spring-boot/image-mirror-example/.applier/inventory-pre-dev/hosts similarity index 100% rename from multi-cluster-spring-boot/applier/inventory-prod/hosts rename to multi-cluster-spring-boot/image-mirror-example/.applier/inventory-pre-dev/hosts diff --git a/multi-cluster-spring-boot/image-mirror-example/.applier/inventory-prod/group_vars/seed-hosts.yml b/multi-cluster-spring-boot/image-mirror-example/.applier/inventory-prod/group_vars/seed-hosts.yml new file mode 100644 index 00000000..69e0ae48 --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/.applier/inventory-prod/group_vars/seed-hosts.yml @@ -0,0 +1,15 @@ +openshift_cluster_content: +- object: projects + content: + - name: "create environments" + file: "{{ inventory_dir }}/../projects/projects-prod.yml" + file_action: create + - name: "create prod cluster credential" + template: "{{ inventory_dir }}/../templates/image-mirror-sa.yml" + params: "{{ inventory_dir }}/../params/registry-sa-prod-cluster" + namespace: multicluster-spring-boot-prod +- object: deployments + content: + - name: "deply prod environment" + template: "{{ inventory_dir }}/../templates/deployment.yml" + params: "{{ inventory_dir }}/../params/deployment-prod" diff --git a/multi-cluster-spring-boot/image-mirror-example/.applier/inventory-prod/hosts b/multi-cluster-spring-boot/image-mirror-example/.applier/inventory-prod/hosts new file mode 100644 index 00000000..7f325c4b --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/.applier/inventory-prod/hosts @@ -0,0 +1,2 @@ +[seed-hosts] +localhost ansible_connection=local diff --git a/multi-cluster-spring-boot/image-mirror-example/.applier/params/build-dev b/multi-cluster-spring-boot/image-mirror-example/.applier/params/build-dev new file mode 100644 index 00000000..1d4a4ffa --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/.applier/params/build-dev @@ -0,0 +1,9 @@ +APPLICATION_NAME=spring-rest +NAMESPACE=multicluster-spring-boot-dev +PIPELINE_REPOSITORY_URL=https://github.com/Gl4di4torRr/container-pipelines.git +PIPELINE_REPOSITORY_REF=multi-cluster-image-mirror +PIPELINE_REPOSITORY_CONTEXT_DIR=multi-cluster-spring-boot/image-mirror-example +SRC_API_URL= +DEST_API_URL= +SRC_REGISTRY= +DEST_REGISTRY= \ No newline at end of file diff --git a/multi-cluster-spring-boot/applier/params/deployment-dev b/multi-cluster-spring-boot/image-mirror-example/.applier/params/deployment-dev similarity index 100% rename from multi-cluster-spring-boot/applier/params/deployment-dev rename to multi-cluster-spring-boot/image-mirror-example/.applier/params/deployment-dev diff --git a/multi-cluster-spring-boot/image-mirror-example/.applier/params/deployment-prod b/multi-cluster-spring-boot/image-mirror-example/.applier/params/deployment-prod new file mode 100644 index 00000000..24843a28 --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/.applier/params/deployment-prod @@ -0,0 +1,5 @@ +APPLICATION_NAME=spring-rest +NAMESPACE=multicluster-spring-boot-prod +SA_NAMESPACE=multicluster-spring-boot-stage +READINESS_RESPONSE=status.:.UP +READINESS_PATH=/health diff --git a/multi-cluster-spring-boot/applier/params/deployment-stage b/multi-cluster-spring-boot/image-mirror-example/.applier/params/deployment-stage similarity index 100% rename from multi-cluster-spring-boot/applier/params/deployment-stage rename to multi-cluster-spring-boot/image-mirror-example/.applier/params/deployment-stage diff --git a/multi-cluster-spring-boot/applier/params/jenkins b/multi-cluster-spring-boot/image-mirror-example/.applier/params/jenkins similarity index 100% rename from multi-cluster-spring-boot/applier/params/jenkins rename to multi-cluster-spring-boot/image-mirror-example/.applier/params/jenkins diff --git a/multi-cluster-spring-boot/image-mirror-example/.applier/params/nonprod-credentials b/multi-cluster-spring-boot/image-mirror-example/.applier/params/nonprod-credentials new file mode 100644 index 00000000..336de3e0 --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/.applier/params/nonprod-credentials @@ -0,0 +1,2 @@ +TOKEN= +SECRET_NAME=nonprod-credentials diff --git a/multi-cluster-spring-boot/image-mirror-example/.applier/params/prod-cluster-credentials b/multi-cluster-spring-boot/image-mirror-example/.applier/params/prod-cluster-credentials new file mode 100644 index 00000000..5daad752 --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/.applier/params/prod-cluster-credentials @@ -0,0 +1,4 @@ +TOKEN= +API_URL= +REGISTRY_URL= +SECRET_NAME=prod-cluster-credentials diff --git a/multi-cluster-spring-boot/image-mirror-example/.applier/params/prod-credentials b/multi-cluster-spring-boot/image-mirror-example/.applier/params/prod-credentials new file mode 100644 index 00000000..41f160a8 --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/.applier/params/prod-credentials @@ -0,0 +1,2 @@ +TOKEN= +SECRET_NAME=prod-credentials diff --git a/multi-cluster-spring-boot/image-mirror-example/.applier/params/registry-sa-nonprod-cluster b/multi-cluster-spring-boot/image-mirror-example/.applier/params/registry-sa-nonprod-cluster new file mode 100644 index 00000000..6b1ccc94 --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/.applier/params/registry-sa-nonprod-cluster @@ -0,0 +1,2 @@ +NAMESPACE=multicluster-spring-boot-stage +SA_NAME=docker-registry-dev diff --git a/multi-cluster-spring-boot/image-mirror-example/.applier/params/registry-sa-prod-cluster b/multi-cluster-spring-boot/image-mirror-example/.applier/params/registry-sa-prod-cluster new file mode 100644 index 00000000..deb42b7b --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/.applier/params/registry-sa-prod-cluster @@ -0,0 +1,2 @@ +NAMESPACE=multicluster-spring-boot-prod +SA_NAME=docker-registry-prod diff --git a/multi-cluster-spring-boot/applier/projects/projects-prod.yml b/multi-cluster-spring-boot/image-mirror-example/.applier/projects/projects-prod.yml similarity index 100% rename from multi-cluster-spring-boot/applier/projects/projects-prod.yml rename to multi-cluster-spring-boot/image-mirror-example/.applier/projects/projects-prod.yml diff --git a/multi-cluster-spring-boot/applier/projects/projects.yml b/multi-cluster-spring-boot/image-mirror-example/.applier/projects/projects.yml similarity index 100% rename from multi-cluster-spring-boot/applier/projects/projects.yml rename to multi-cluster-spring-boot/image-mirror-example/.applier/projects/projects.yml diff --git a/multi-cluster-spring-boot/image-mirror-example/.applier/templates/build.yml b/multi-cluster-spring-boot/image-mirror-example/.applier/templates/build.yml new file mode 100644 index 00000000..33f04ffc --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/.applier/templates/build.yml @@ -0,0 +1,142 @@ +apiVersion: v1 +kind: Template +labels: + template: generic-java-jenkins-pipeline +metadata: + annotations: + description: Application template for JWS applications built using a Jenkins Pipeline + iconClass: icon-tomcat + tags: tomcat,tomcat8,java,jboss,xpaas,jenkins-ci + version: 1.2.0 + name: generic-java-jenkins-pipeline +objects: +- apiVersion: v1 + kind: BuildConfig + metadata: + labels: + application: ${APPLICATION_NAME} + app: ${APPLICATION_NAME} + build: ${APPLICATION_NAME} + name: "${APPLICATION_NAME}" + namespace: "${NAMESPACE}" + spec: + output: + to: + kind: ImageStreamTag + name: "${APPLICATION_NAME}:latest" + postCommit: {} + resources: {} + runPolicy: Serial + source: + binary: {} + type: Binary + strategy: + sourceStrategy: + from: + kind: ImageStreamTag + name: ${IMAGE_STREAM_TAG_NAME} + namespace: ${IMAGE_STREAM_NAMESPACE} + type: Source +- kind: "BuildConfig" + apiVersion: "v1" + metadata: + labels: + application: ${APPLICATION_NAME} + name: "${APPLICATION_NAME}-pipeline" + namespace: "${NAMESPACE}" + spec: + source: + type: Git + git: + uri: ${PIPELINE_REPOSITORY_URL} + ref: ${PIPELINE_REPOSITORY_REF} + contextDir: ${PIPELINE_REPOSITORY_CONTEXT_DIR} + triggers: + - type: "GitHub" + github: + secret: ${GITHUB_WEBHOOK_SECRET} + - type: "ConfigChange" + strategy: + type: "JenkinsPipeline" + jenkinsPipelineStrategy: + jenkinsfilePath: ${PIPELINE_SCRIPT} + env: + - name: SOURCE_CODE_URL + value: ${SOURCE_CODE_URL} + - name: SOURCE_CODE_BRANCH + value: ${SOURCE_CODE_BRANCH} + - name: SKIP_TLS + value: "true" + - name: SRC_REGISTRY + value: ${SRC_REGISTRY} + - name: DEST_REGISTRY + value: ${DEST_REGISTRY} + - name: SRC_API_URL + value: ${SRC_API_URL} + - name: DEST_API_URL + value: ${DEST_API_URL} +parameters: +- description: The name for the application. + name: APPLICATION_NAME + required: true + value: basic-spring +- description: The namespace to deploy into + name: NAMESPACE + required: true +- description: Git source URI for application + name: PIPELINE_REPOSITORY_URL + required: true + value: https://github.com/redhat-cop/container-pipelines.git +- description: Git branch/tag reference + name: PIPELINE_REPOSITORY_REF + value: "master" +- description: Path within Git project to build; empty for root project directory. + name: PIPELINE_REPOSITORY_CONTEXT_DIR + value: +- description: Path within Git project pointing to the pipeline run script + name: PIPELINE_SCRIPT + value: Jenkinsfile +- description: Git source URI for application + name: SOURCE_CODE_URL + required: true + value: https://github.com/redhat-cop/spring-rest.git +- description: Git branch/tag reference + name: SOURCE_CODE_REF + value: "master" +- description: GitHub trigger secret + from: '[a-zA-Z0-9]{8}' + generate: expression + name: GITHUB_WEBHOOK_SECRET + required: true +- description: Generic build trigger secret + from: '[a-zA-Z0-9]{8}' + generate: expression + name: GENERIC_WEBHOOK_SECRET + required: true +- description: Namespace in which the ImageStreams for Red Hat Middleware images are + installed. These ImageStreams are normally installed in the openshift namespace. + You should only need to modify this if you've installed the ImageStreams in a + different namespace/project. + name: IMAGE_STREAM_NAMESPACE + required: true + value: openshift +- description: Image stream tag for the image you'd like to use to build the application + name: IMAGE_STREAM_TAG_NAME + required: true + value: redhat-openjdk18-openshift:1.1 +- description: The source docker registry used for image mirror + name: SRC_REGISTRY + required: true +- description: The destination docker registry used for image mirror + name: DEST_REGISTRY + required: true +- description: Set source code branch + name: SOURCE_CODE_BRANCH + required: true + value: master +- description: The source docker registry used for the docker registry url + name: SRC_API_URL + required: true +- description: The destination docker registry used for the docker registry url + name: DEST_API_URL + required: true diff --git a/multi-cluster-spring-boot/applier/templates/cluster-secret.yml b/multi-cluster-spring-boot/image-mirror-example/.applier/templates/cluster-secret.yml similarity index 100% rename from multi-cluster-spring-boot/applier/templates/cluster-secret.yml rename to multi-cluster-spring-boot/image-mirror-example/.applier/templates/cluster-secret.yml diff --git a/multi-cluster-spring-boot/applier/templates/deployment.yml b/multi-cluster-spring-boot/image-mirror-example/.applier/templates/deployment.yml similarity index 100% rename from multi-cluster-spring-boot/applier/templates/deployment.yml rename to multi-cluster-spring-boot/image-mirror-example/.applier/templates/deployment.yml diff --git a/multi-cluster-spring-boot/image-mirror-example/.applier/templates/image-mirror-sa.yml b/multi-cluster-spring-boot/image-mirror-example/.applier/templates/image-mirror-sa.yml new file mode 100644 index 00000000..4f4d40f3 --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/.applier/templates/image-mirror-sa.yml @@ -0,0 +1,33 @@ +apiVersion: v1 +kind: Template +metadata: + annotations: + description: template for image mirror service account +objects: +- apiVersion: v1 + kind: ServiceAccount + metadata: + name: ${SA_NAME} + namespace: ${NAMESPACE} +- apiVersion: v1 + groupNames: null + kind: RoleBinding + metadata: + creationTimestamp: null + name: edit + namespace: ${NAMESPACE} + roleRef: + name: edit + subjects: + - kind: ServiceAccount + name: ${SA_NAME} + namespace: ${NAMESPACE} + userNames: + - system:serviceaccount:${NAMESPACE}:${SA_NAME} +parameters: +- description: The namespace to deploy into + name: NAMESPACE + required: true +- description: The service account name + name: SA_NAME + required: true diff --git a/multi-cluster-spring-boot/image-mirror-example/.applier/templates/image-mirror-secret.yml b/multi-cluster-spring-boot/image-mirror-example/.applier/templates/image-mirror-secret.yml new file mode 100644 index 00000000..065af067 --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/.applier/templates/image-mirror-secret.yml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: Template +labels: + template: image-mirror-secret +metadata: + annotations: + description: Cluster Credential Secret + tags: secret + version: 1.0.0 + name: image-mirror-secret +objects: +- apiVersion: v1 + stringData: + username: generic + password: "${TOKEN}" + data: + kind: Secret + metadata: + name: ${SECRET_NAME} + labels: + credential.sync.jenkins.openshift.io: 'true' + type: kubernetes.io/basic-auth +parameters: +- description: The name for the application. + name: SECRET_NAME + required: true +- description: Service Account Token + name: TOKEN + required: true \ No newline at end of file diff --git a/multi-cluster-spring-boot/image-mirror-example/.gitignore b/multi-cluster-spring-boot/image-mirror-example/.gitignore new file mode 100644 index 00000000..0068fe1d --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/.gitignore @@ -0,0 +1 @@ +galaxy/ \ No newline at end of file diff --git a/multi-cluster-spring-boot/image-mirror-example/Jenkinsfile b/multi-cluster-spring-boot/image-mirror-example/Jenkinsfile new file mode 100644 index 00000000..50ef1e18 --- /dev/null +++ b/multi-cluster-spring-boot/image-mirror-example/Jenkinsfile @@ -0,0 +1,124 @@ +openshift.withCluster() { + env.NAMESPACE = openshift.project() + env.APP_NAME = "${env.JOB_NAME}".replaceAll(/-?pipeline-?/, '').replaceAll(/-?${env.NAMESPACE}-?/, '') + echo "Starting Pipeline for ${APP_NAME}..." + def projectBase = "${env.NAMESPACE}".replaceAll(/-dev/, '') + env.STAGE1 = "${projectBase}-dev" + env.STAGE2 = "${projectBase}-stage" + env.STAGE3 = "${projectBase}-prod" +} + + +pipeline { + + agent { label 'maven' } + + stages { + + stage('Code Build') { + steps { + git url: "${SOURCE_CODE_URL}" + sh "mvn clean install -q" + } + } + + stage('Image Build') { + steps { + echo 'Building Image from Jar File' + sh """ + rm -rf oc-build && mkdir -p oc-build/deployments + for t in \$(echo "jar;war;ear" | tr ";" "\\n"); do + cp -rfv ./target/*.\$t oc-build/deployments/ 2> /dev/null || echo "No \$t files" + done + """ + script { + openshift.withCluster() { + openshift.startBuild("${APP_NAME}", "--from-dir=oc-build", "--wait", "--follow") + } + } + } + } + + stage ('Verify Deployment to Dev') { + steps { + script { + openshift.withCluster() { + def dcObj = openshift.selector('dc', env.APP_NAME).object() + def podSelector = openshift.selector('pod', [deployment: "${APP_NAME}-${dcObj.status.latestVersion}"]) + podSelector.untilEach { + echo "pod: ${it.name()}" + return it.object().status.containerStatuses[0].ready + } + } + } + } + } + + stage('Promote to Stage') { + steps { + script { + openshift.withCluster() { + openshift.tag("${env.STAGE1}/${env.APP_NAME}:latest", "${env.STAGE2}/${env.APP_NAME}:latest") + } + } + } + } + + stage ('Verify Deployment to Stage') { + steps { + script { + openshift.withCluster() { + openshift.withProject("${STAGE2}") { + def dcObj = openshift.selector('dc', env.APP_NAME).object() + def podSelector = openshift.selector('pod', [deployment: "${APP_NAME}-${dcObj.status.latestVersion}"]) + podSelector.untilEach { + echo "pod: ${it.name()}" + return it.object().status.containerStatuses[0].ready + } + } + } + } + } + } + + stage('Promote to Prod') { + steps { + withDockerRegistry([credentialsId: "${STAGE1}-nonprod-credentials", url: "${SRC_API_URL}"]) { + + withDockerRegistry([credentialsId: "${STAGE1}-prod-credentials", url: "${DEST_API_URL}"]) { + + sh """ + oc image mirror --insecure=true ${SRC_REGISTRY}/${STAGE2}/${APP_NAME}:latest ${DEST_REGISTRY}/${STAGE3}/${APP_NAME}:latest + """ + + } + } + } + } + + stage ('Verify Deployment to Prod') { + steps { + script { + openshift.withCluster() { + def secretData = openshift.selector('secret/prod-cluster-credentials').object().data + def encodedAPI = secretData.api + def encodedToken = secretData.token + env.API = sh(script:"set +x; echo ${encodedAPI} | base64 --decode", returnStdout: true).replaceAll(/https?/, 'insecure') + env.TOKEN = sh(script:"set +x; echo ${encodedToken} | base64 --decode", returnStdout: true) + } + openshift.withCluster( env.API, env.TOKEN ) { + openshift.withProject("${STAGE3}") { + def dcObj = openshift.selector('dc', env.APP_NAME).object() + def podSelector = openshift.selector('pod', [deployment: "${APP_NAME}-${dcObj.status.latestVersion}"]) + podSelector.untilEach { + echo "pod: ${it.name()}" + return it.object().status.containerStatuses[0].ready + } + } + } + } + } + } + + } +} \ No newline at end of file diff --git a/multi-cluster-spring-boot/applier/inventory-dev/group_vars/seed-hosts.yml b/multi-cluster-spring-boot/skopeo-example/.applier/inventory-dev/group_vars/seed-hosts.yml similarity index 100% rename from multi-cluster-spring-boot/applier/inventory-dev/group_vars/seed-hosts.yml rename to multi-cluster-spring-boot/skopeo-example/.applier/inventory-dev/group_vars/seed-hosts.yml diff --git a/multi-cluster-spring-boot/skopeo-example/.applier/inventory-dev/hosts b/multi-cluster-spring-boot/skopeo-example/.applier/inventory-dev/hosts new file mode 100644 index 00000000..7f325c4b --- /dev/null +++ b/multi-cluster-spring-boot/skopeo-example/.applier/inventory-dev/hosts @@ -0,0 +1,2 @@ +[seed-hosts] +localhost ansible_connection=local diff --git a/multi-cluster-spring-boot/applier/inventory-prod/group_vars/seed-hosts.yml b/multi-cluster-spring-boot/skopeo-example/.applier/inventory-prod/group_vars/seed-hosts.yml similarity index 100% rename from multi-cluster-spring-boot/applier/inventory-prod/group_vars/seed-hosts.yml rename to multi-cluster-spring-boot/skopeo-example/.applier/inventory-prod/group_vars/seed-hosts.yml diff --git a/multi-cluster-spring-boot/skopeo-example/.applier/inventory-prod/hosts b/multi-cluster-spring-boot/skopeo-example/.applier/inventory-prod/hosts new file mode 100644 index 00000000..7f325c4b --- /dev/null +++ b/multi-cluster-spring-boot/skopeo-example/.applier/inventory-prod/hosts @@ -0,0 +1,2 @@ +[seed-hosts] +localhost ansible_connection=local diff --git a/multi-cluster-spring-boot/applier/params/build-dev b/multi-cluster-spring-boot/skopeo-example/.applier/params/build-dev similarity index 72% rename from multi-cluster-spring-boot/applier/params/build-dev rename to multi-cluster-spring-boot/skopeo-example/.applier/params/build-dev index de786644..ae0fd125 100644 --- a/multi-cluster-spring-boot/applier/params/build-dev +++ b/multi-cluster-spring-boot/skopeo-example/.applier/params/build-dev @@ -2,4 +2,4 @@ APPLICATION_NAME=spring-rest NAMESPACE=multicluster-spring-boot-dev PIPELINE_REPOSITORY_URL=https://github.com/etsauer/container-pipelines.git PIPELINE_REPOSITORY_REF=multi-cluster-promotion -PIPELINE_REPOSITORY_CONTEXT_DIR=multi-cluster-spring-boot +PIPELINE_REPOSITORY_CONTEXT_DIR=multi-cluster-spring-boot/skopeo-example diff --git a/multi-cluster-spring-boot/applier/params/build-slave-dev b/multi-cluster-spring-boot/skopeo-example/.applier/params/build-slave-dev similarity index 100% rename from multi-cluster-spring-boot/applier/params/build-slave-dev rename to multi-cluster-spring-boot/skopeo-example/.applier/params/build-slave-dev diff --git a/multi-cluster-spring-boot/skopeo-example/.applier/params/deployment-dev b/multi-cluster-spring-boot/skopeo-example/.applier/params/deployment-dev new file mode 100644 index 00000000..c13fb0f4 --- /dev/null +++ b/multi-cluster-spring-boot/skopeo-example/.applier/params/deployment-dev @@ -0,0 +1,5 @@ +APPLICATION_NAME=spring-rest +NAMESPACE=multicluster-spring-boot-dev +SA_NAMESPACE=multicluster-spring-boot-dev +READINESS_RESPONSE=status.:.UP +READINESS_PATH=/health diff --git a/multi-cluster-spring-boot/applier/params/deployment-prod b/multi-cluster-spring-boot/skopeo-example/.applier/params/deployment-prod similarity index 100% rename from multi-cluster-spring-boot/applier/params/deployment-prod rename to multi-cluster-spring-boot/skopeo-example/.applier/params/deployment-prod diff --git a/multi-cluster-spring-boot/skopeo-example/.applier/params/deployment-stage b/multi-cluster-spring-boot/skopeo-example/.applier/params/deployment-stage new file mode 100644 index 00000000..326a8b1b --- /dev/null +++ b/multi-cluster-spring-boot/skopeo-example/.applier/params/deployment-stage @@ -0,0 +1,6 @@ +APPLICATION_NAME=spring-rest +NAMESPACE=multicluster-spring-boot-stage +SA_NAME=jenkins +SA_NAMESPACE=multicluster-spring-boot-dev +READINESS_RESPONSE=status.:.UP +READINESS_PATH=/health diff --git a/multi-cluster-spring-boot/skopeo-example/.applier/params/jenkins b/multi-cluster-spring-boot/skopeo-example/.applier/params/jenkins new file mode 100644 index 00000000..e29bc258 --- /dev/null +++ b/multi-cluster-spring-boot/skopeo-example/.applier/params/jenkins @@ -0,0 +1 @@ +MEMORY_LIMIT=1.5Gi diff --git a/multi-cluster-spring-boot/skopeo-example/.applier/projects/projects-prod.yml b/multi-cluster-spring-boot/skopeo-example/.applier/projects/projects-prod.yml new file mode 100644 index 00000000..2cd0a889 --- /dev/null +++ b/multi-cluster-spring-boot/skopeo-example/.applier/projects/projects-prod.yml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: List +items: +- kind: ProjectRequest + apiVersion: v1 + metadata: + name: multicluster-spring-boot-prod + creationTimestam: null + displayName: MultiCluster Pipeline - Prod diff --git a/multi-cluster-spring-boot/skopeo-example/.applier/projects/projects.yml b/multi-cluster-spring-boot/skopeo-example/.applier/projects/projects.yml new file mode 100644 index 00000000..9c3b81e8 --- /dev/null +++ b/multi-cluster-spring-boot/skopeo-example/.applier/projects/projects.yml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: List +items: +- kind: ProjectRequest + apiVersion: v1 + metadata: + name: multicluster-spring-boot-dev + creationTimestam: null + displayName: MultiCluster Pipeline - Dev +- kind: ProjectRequest + apiVersion: v1 + metadata: + name: multicluster-spring-boot-stage + creationTimestam: null + displayName: MultiCluster Pipeline - Stage diff --git a/multi-cluster-spring-boot/applier/projects/promoter-sa.yml b/multi-cluster-spring-boot/skopeo-example/.applier/projects/promoter-sa.yml similarity index 100% rename from multi-cluster-spring-boot/applier/projects/promoter-sa.yml rename to multi-cluster-spring-boot/skopeo-example/.applier/projects/promoter-sa.yml diff --git a/multi-cluster-spring-boot/applier/templates/build.yml b/multi-cluster-spring-boot/skopeo-example/.applier/templates/build.yml similarity index 100% rename from multi-cluster-spring-boot/applier/templates/build.yml rename to multi-cluster-spring-boot/skopeo-example/.applier/templates/build.yml diff --git a/multi-cluster-spring-boot/skopeo-example/.applier/templates/cluster-secret.yml b/multi-cluster-spring-boot/skopeo-example/.applier/templates/cluster-secret.yml new file mode 100644 index 00000000..ed9ddbdc --- /dev/null +++ b/multi-cluster-spring-boot/skopeo-example/.applier/templates/cluster-secret.yml @@ -0,0 +1,35 @@ +apiVersion: v1 +kind: Template +labels: + template: cluster-credentials-secret +metadata: + annotations: + description: Cluster Credential Secret + tags: secret + version: 1.0.0 + name: cluster-credentials-secret +objects: +- apiVersion: v1 + stringData: + api: ${API_URL} + registry: ${REGISTRY_URL} + token: "${TOKEN}" + data: + kind: Secret + metadata: + name: ${SECRET_NAME} + type: Opaque +parameters: +- description: The name for the application. + name: SECRET_NAME + required: true + value: prod-credentials +- description: The API URL + name: API_URL + required: true +- description: The Registry Route URL + name: REGISTRY_URL + required: true +- description: Service Account Token + name: TOKEN + required: true diff --git a/multi-cluster-spring-boot/skopeo-example/.applier/templates/deployment.yml b/multi-cluster-spring-boot/skopeo-example/.applier/templates/deployment.yml new file mode 100644 index 00000000..b981ae5c --- /dev/null +++ b/multi-cluster-spring-boot/skopeo-example/.applier/templates/deployment.yml @@ -0,0 +1,145 @@ +apiVersion: v1 +kind: Template +labels: + template: basic-spring-boot +metadata: + annotations: + description: Application template for JWS applications built using a Jenkins Pipeline + iconClass: icon-tomcat + tags: java,spring + version: 1.2.0 + name: basic-sprint-boot +objects: +- apiVersion: v1 + kind: Service + metadata: + annotations: + description: The web server's http port. + labels: + application: ${APPLICATION_NAME} + name: ${APPLICATION_NAME} + namespace: ${NAMESPACE} + spec: + ports: + - port: 8080 + targetPort: 8080 + selector: + deploymentConfig: ${APPLICATION_NAME} +- apiVersion: v1 + id: ${APPLICATION_NAME}-http + kind: Route + metadata: + annotations: + description: Route for application's http service. + labels: + application: ${APPLICATION_NAME} + name: ${APPLICATION_NAME} + namespace: ${NAMESPACE} + spec: + host: ${HOSTNAME_HTTP} + to: + name: ${APPLICATION_NAME} +- apiVersion: v1 + kind: ImageStream + metadata: + labels: + application: ${APPLICATION_NAME} + name: ${APPLICATION_NAME} + namespace: ${NAMESPACE} +- apiVersion: v1 + kind: DeploymentConfig + metadata: + labels: + application: ${APPLICATION_NAME} + name: ${APPLICATION_NAME} + namespace: ${NAMESPACE} + spec: + replicas: 1 + selector: + deploymentConfig: ${APPLICATION_NAME} + strategy: + type: Recreate + template: + metadata: + labels: + application: ${APPLICATION_NAME} + deploymentConfig: ${APPLICATION_NAME} + name: ${APPLICATION_NAME} + spec: + containers: + - env: + - name: JWS_ADMIN_USERNAME + value: ${JWS_ADMIN_USERNAME} + - name: JWS_ADMIN_PASSWORD + value: ${JWS_ADMIN_PASSWORD} + image: ${APPLICATION_NAME} + imagePullPolicy: Always + name: ${APPLICATION_NAME} + ports: + - containerPort: 8778 + name: jolokia + protocol: TCP + - containerPort: 8080 + name: http + protocol: TCP + readinessProbe: + exec: + command: + - /bin/bash + - -c + - curl -s 'http://localhost:8080${READINESS_PATH}' + |grep -iq '${READINESS_RESPONSE}' + terminationGracePeriodSeconds: 60 + triggers: + - imageChangeParams: + automatic: true + containerNames: + - ${APPLICATION_NAME} + from: + kind: ImageStreamTag + name: ${APPLICATION_NAME}:latest + type: ImageChange + - type: ConfigChange +- apiVersion: v1 + groupNames: null + kind: RoleBinding + metadata: + creationTimestamp: null + labels: + template: basic-tomcat-template + name: jenkins_edit + namespace: ${NAMESPACE} + roleRef: + name: edit + subjects: + - kind: ServiceAccount + name: ${SA_NAME} + namespace: ${SA_NAMESPACE} + userNames: + - system:serviceaccount:${SA_NAMESPACE}:${SA_NAME} +parameters: +- description: The name for the application. + name: APPLICATION_NAME + required: true + value: jws-app +- description: The namespace to deploy into + name: NAMESPACE + required: true +- description: Name of a service account that can deploy to this project + name: SA_NAME + required: true + value: jenkins +- description: Namespace of service account that can deploy to this project + name: SA_NAMESPACE + required: true +- description: 'Custom hostname for http service route. Leave blank for default hostname, + e.g.: -.' + name: HOSTNAME_HTTP +- description: 'URI to check for app health' + name: READINESS_PATH + required: true + value: '/' +- description: 'String value expected back from readiness check' + name: READINESS_RESPONSE + required: true + value: 'Hello World!' diff --git a/multi-cluster-spring-boot/Jenkinsfile b/multi-cluster-spring-boot/skopeo-example/Jenkinsfile similarity index 100% rename from multi-cluster-spring-boot/Jenkinsfile rename to multi-cluster-spring-boot/skopeo-example/Jenkinsfile