├── .github ├── CONTRIBUTING.md ├── PULL_REQUEST_TEMPLATE.md ├── stale.yml └── workflows │ └── conftest.yaml ├── .gitignore ├── .project ├── LICENSE ├── OWNERS ├── README.md ├── _test ├── bats-support-clone.bash └── conftest.sh ├── basic-dotnet-core ├── .applier │ ├── group_vars │ │ └── seed-hosts.yml │ └── hosts ├── .gitignore ├── .openshift │ ├── projects │ │ └── projects.yml │ └── templates │ │ ├── build.yml │ │ └── deployment.yml ├── Jenkinsfile ├── README.md └── requirements.yml ├── basic-helm-spring-boot ├── .helm │ ├── jenkins-agent-helm │ │ ├── Chart.yaml │ │ ├── templates │ │ │ ├── buildconfig.yaml │ │ │ └── imagestream.yaml │ │ └── values.yaml │ ├── spring-boot-build │ │ ├── Chart.yaml │ │ ├── templates │ │ │ ├── buildconfig.yaml │ │ │ └── imagestream.yaml │ │ └── values.yaml │ └── spring-boot │ │ ├── Chart.yaml │ │ ├── templates │ │ ├── deployment.yaml │ │ ├── route.yaml │ │ └── service.yaml │ │ └── values.yaml ├── Jenkinsfile └── README.md ├── basic-nginx ├── .applier │ ├── group_vars │ │ └── seed-hosts.yml │ └── hosts ├── .openshift │ ├── builds │ │ ├── params │ │ └── template.yml │ ├── deployment │ │ ├── build │ │ │ └── params │ │ ├── dev │ │ │ └── params │ │ ├── prod │ │ │ └── params │ │ ├── stage │ │ │ └── params │ │ └── template.yml │ └── projects │ │ └── projects.yml ├── Jenkinsfile ├── README.md ├── index.html ├── nginx.conf └── requirements.yml ├── basic-spring-boot-tekton ├── .applier │ ├── group_vars │ │ └── seed-hosts.yml │ └── hosts ├── .gitignore ├── .openshift │ ├── projects │ │ └── projects.yml │ └── templates │ │ ├── build.yml │ │ └── deployment.yml ├── README.md └── requirements.yml ├── basic-spring-boot ├── .applier │ ├── group_vars │ │ └── seed-hosts.yml │ └── hosts ├── .gitignore ├── .openshift │ ├── projects │ │ └── projects.yml │ └── templates │ │ ├── build.yml │ │ └── deployment.yml ├── Jenkinsfile ├── Jenkinsfile.hygieia ├── README.md └── requirements.yml ├── basic-tomcat ├── .applier │ ├── group_vars │ │ └── seed-hosts.yml │ └── hosts ├── .openshift │ ├── builds │ │ ├── params │ │ └── template.yml │ ├── deployment │ │ ├── build │ │ │ └── params │ │ ├── dev │ │ │ └── params │ │ ├── prod │ │ │ └── params │ │ ├── stage │ │ │ └── params │ │ └── template.yml │ └── projects │ │ └── projects.yml ├── Jenkinsfile ├── README.md └── requirements.yml ├── blue-green-spring ├── .applier │ ├── group_vars │ │ └── seed-hosts.yml │ └── hosts ├── .openshift │ ├── builds │ │ ├── params │ │ └── template.yml │ ├── deployment │ │ ├── build │ │ │ └── params │ │ ├── dev │ │ │ └── params │ │ ├── prod │ │ │ └── params │ │ ├── stage │ │ │ └── params │ │ ├── template-bg.yml │ │ └── template.yml │ └── projects │ │ └── projects.yml ├── Jenkinsfile ├── README.md └── requirements.yml ├── cucumber-selenium-grid ├── .gitignore ├── Jenkinsfile ├── README.md ├── angularjs │ ├── .gitignore │ ├── application.js │ ├── index.html │ ├── integration-tests │ │ ├── features │ │ │ ├── step-definitions │ │ │ │ └── todo.js │ │ │ └── todo.feature │ │ ├── page-objects │ │ │ ├── README.md │ │ │ ├── home-page.js │ │ │ └── page-base.js │ │ └── protractor-conf.js │ ├── js │ │ ├── app.js │ │ ├── controllers │ │ │ └── todoCtrl.js │ │ ├── directives │ │ │ ├── todoEscape.js │ │ │ └── todoFocus.js │ │ └── services │ │ │ └── todoStorage.js │ ├── package.json │ ├── readme.md │ └── test │ │ ├── config │ │ └── karma.conf.js │ │ └── unit │ │ ├── directivesSpec.js │ │ └── todoCtrlSpec.js ├── applier │ ├── inventory │ │ ├── group_vars │ │ │ └── seed-hosts.yml │ │ └── hosts │ ├── params │ │ ├── build-dev │ │ ├── deployment-dev │ │ ├── deployment-prod │ │ ├── deployment-stage │ │ ├── jenkins │ │ ├── projects │ │ └── zalenium │ ├── projects │ │ └── projects.yml │ └── templates │ │ ├── build.yml │ │ ├── deployment.yml │ │ ├── jenkins-ephemeral.yml │ │ ├── jenkins-slave-node-8.yaml │ │ └── selenium-grid.yaml ├── media │ └── integrated-tests-architecture.png ├── nodejs-slave │ ├── Dockerfile │ └── contrib │ │ └── bin │ │ ├── configure-agent │ │ └── scl_enable └── requirements.yml ├── jenkins-s2i ├── jenkins-s2i.yml └── plugins.txt ├── multi-cluster-multi-branch-jee ├── .applier │ ├── .gitignore │ ├── apply.yml │ ├── inventory │ │ ├── group_vars │ │ │ └── all.yml │ │ ├── host_vars │ │ │ ├── app-build.yml │ │ │ ├── app-dev.yml │ │ │ ├── app-prod.yml │ │ │ ├── app-qa.yml │ │ │ └── app-test.yml │ │ └── hosts │ └── requirements.yml ├── .gitignore ├── .openshift │ └── app-deploy-jboss-eap.yml ├── Jenkinsfile.example ├── README.md └── pipelineJEE8.groovy ├── multi-cluster-spring-boot ├── README.md ├── image-mirror-example │ ├── .applier │ │ ├── inventory-dev │ │ │ ├── group_vars │ │ │ │ └── seed-hosts.yml │ │ │ └── hosts │ │ ├── inventory-pre-dev │ │ │ ├── group_vars │ │ │ │ └── seed-hosts.yml │ │ │ └── hosts │ │ ├── inventory-prod │ │ │ ├── group_vars │ │ │ │ └── seed-hosts.yml │ │ │ └── hosts │ │ ├── params │ │ │ ├── build-dev │ │ │ ├── deployment-dev │ │ │ ├── deployment-prod │ │ │ ├── deployment-stage │ │ │ ├── jenkins │ │ │ ├── nonprod-credentials │ │ │ ├── prod-cluster-credentials │ │ │ ├── prod-credentials │ │ │ ├── registry-sa-nonprod-cluster │ │ │ └── registry-sa-prod-cluster │ │ ├── projects │ │ │ ├── projects-prod.yml │ │ │ └── projects.yml │ │ └── templates │ │ │ ├── build.yml │ │ │ ├── cluster-secret.yml │ │ │ ├── deployment.yml │ │ │ ├── image-mirror-sa.yml │ │ │ └── image-mirror-secret.yml │ ├── .gitignore │ └── Jenkinsfile ├── requirements.yml └── skopeo-example │ ├── .applier │ ├── inventory-dev │ │ ├── group_vars │ │ │ └── seed-hosts.yml │ │ └── hosts │ ├── inventory-prod │ │ ├── group_vars │ │ │ └── seed-hosts.yml │ │ └── hosts │ ├── params │ │ ├── build-dev │ │ ├── build-slave-dev │ │ ├── deployment-dev │ │ ├── deployment-prod │ │ ├── deployment-stage │ │ └── jenkins │ ├── projects │ │ ├── projects-prod.yml │ │ ├── projects.yml │ │ └── promoter-sa.yml │ └── templates │ │ ├── build.yml │ │ ├── cluster-secret.yml │ │ └── deployment.yml │ └── Jenkinsfile ├── renovate.json └── secure-spring-boot ├── .gitignore ├── .openshift-applier ├── inventory │ ├── group_vars │ │ └── seed-hosts.yml │ └── hosts └── templates │ ├── build.yml │ └── deployment.yml ├── Jenkinsfile ├── README.md ├── ci-cd-tooling.yml ├── project-names.yml ├── requirements.yml └── spring-boot-app.yml /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We welcome contributions from the community. Here are a few ways you can help us improve. 4 | 5 | ## Open an Issue 6 | 7 | If you see something you'd like changed, but aren't sure how to change it, submit an issue describing what you'd like to see. 8 | 9 | ## Submit a Pull Request 10 | 11 | If you feel like getting your hands dirty, feel free to make the change yourself. Here's how: 12 | 13 | 1. Fork the repo on Github, and then clone it locally. 14 | 2. Create a branch named appropriately for the change you are going to make. 15 | 3. Make your code change. 16 | 4. Push your code change up to your forked repo. 17 | 5. Open a Pull Request to merge your changes to this repo. The comment box will be filled in automatically via a template. 18 | 19 | See [Using Pull Requests](https://help.github.com/articles/using-pull-requests/) got more information on how to use GitHub PRs. 20 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | #### What does this PR do? 2 | Brief explanation of the code or documentation change you've made 3 | 4 | #### How should this be tested? 5 | Include commands to run your new feature, and also post-run commands to validate that it worked. (please use code blocks to format code samples) 6 | 7 | #### Is there a relevant Issue open for this? 8 | Provide a link to any open issues that describe the problem you are solving. 9 | 10 | #### Who would you like to review this? 11 | cc: @redhat-cop/containers-approvers 12 | -------------------------------------------------------------------------------- /.github/stale.yml: -------------------------------------------------------------------------------- 1 | ## Configuration for probot-stale - https://github.com/probot/stale 2 | # 3 | ## Number of days of inactivity before an Issue or Pull Request becomes stale 4 | #daysUntilStale: 60 5 | ## Number of days of inactivity before a stale Issue or Pull Request is closed. 6 | ## Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. 7 | #daysUntilClose: 7 8 | ## Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable 9 | #exemptLabels: 10 | # - pinned 11 | # - security 12 | # - "[Status] Maybe Later" 13 | ## Label to use when marking as stale 14 | #staleLabel: wontfix 15 | ## Comment to post when marking as stale. Set to `false` to disable 16 | #markComment: > 17 | # This issue has been automatically marked as stale because it has not had 18 | # recent activity. It will be closed if no further activity occurs. Thank you 19 | # for your contributions. 20 | ## Comment to post when removing the stale label. Set to `false` to disable 21 | #unmarkComment: false 22 | ## Comment to post when closing a stale Issue or Pull Request. Set to `false` to disable 23 | #closeComment: false 24 | ## Limit the number of actions per hour, from 1-30. Default is 30 25 | #limitPerRun: 30 26 | ## Limit to only `issues` or `pulls` 27 | ## only: issues 28 | ## 29 | ## Optionally, specify configuration settings that are specific to just 'issues' or 'pulls': 30 | ## pulls: 31 | ## daysUntilStale: 30 32 | ## markComment: > 33 | ## This pull request has been automatically marked as stale because it has not had 34 | ## recent activity. It will be closed if no further activity occurs. Thank you 35 | ## for your contributions. 36 | ## issues: 37 | ## exemptLabels: 38 | ## - confirmed -------------------------------------------------------------------------------- /.github/workflows/conftest.yaml: -------------------------------------------------------------------------------- 1 | name: Validate 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | conftest: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout 10 | uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 11 | 12 | - name: Conftest 13 | uses: redhat-cop/github-actions/confbatstest@master 14 | with: 15 | tests: _test/conftest.sh -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | */galaxy/* 2 | 3 | ### JetBrains template 4 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 5 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 6 | 7 | # User-specific stuff: 8 | .idea/ 9 | .idea/**/workspace.xml 10 | .idea/**/tasks.xml 11 | .idea/dictionaries 12 | 13 | # Sensitive or high-churn files: 14 | .idea/**/dataSources/ 15 | .idea/**/dataSources.ids 16 | .idea/**/dataSources.xml 17 | .idea/**/dataSources.local.xml 18 | .idea/**/sqlDataSources.xml 19 | .idea/**/dynamic.xml 20 | .idea/**/uiDesigner.xml 21 | 22 | ## File-based project format: 23 | *.iws 24 | *.iml 25 | 26 | ### Maven template 27 | target/ 28 | pom.xml.tag 29 | pom.xml.releaseBackup 30 | pom.xml.versionsBackup 31 | pom.xml.next 32 | release.properties 33 | dependency-reduced-pom.xml 34 | buildNumber.properties 35 | .mvn/timing.properties 36 | 37 | # Rego 38 | policy/ 39 | 40 | # BATS 41 | _test/test_helper/ -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | container-pipelines 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | # See the OWNERS docs at https://go.k8s.io/owners 2 | 3 | reviewers: 4 | - etsauer 5 | - garethahealy 6 | - oybed 7 | - pabrahamsson 8 | - sabre1041 9 | approvers: 10 | - etsauer 11 | - garethahealy 12 | - oybed 13 | - pabrahamsson 14 | - sabre1041 15 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Validate](https://github.com/redhat-cop/container-pipelines/workflows/Validate/badge.svg) 2 | 3 | # Container Pipelines 4 | 5 | Let's get the ball rolling on some Container-driven CI & CD 6 | 7 | ## Catalog 8 | 9 | The following is a list of the pipeline samples available in this repository: 10 | 11 | - [Basic Tomcat](./basic-tomcat) - Builds a Java Application like Ticket Monster and deploys it to Tomcat 12 | - [Basic Spring Boot](./basic-spring-boot) - Builds a Spring Boot application and deploys using an Embedded Servlet jar file 13 | - [Basic Helm Spring Boot](./basic-helm-spring-boot) - Builds and deploys a Spring Boot application using Helm charts 14 | - [Blue Green Spring Boot](./blue-green-spring) - Build a Spring Boot application and deploys it using a blue-green deployment 15 | - [Secure Spring Boot](./secure-spring-boot) - Build a Spring Boot app and deploy with a pipeline that includes code coverage reports, dependency scanning, sonarqube analysis 16 | - [Cross Cluster Promotion Pipeline](./multi-cluster-spring-boot) - A [declarative syntax](https://jenkins.io/doc/book/pipeline/syntax/#declarative-pipeline) pipeline that demonstrates promoting a microservice between clusters (i.e. a Non-Production to a Production cluster) 17 | 18 | ## Makeup of a "Pipeline" 19 | 20 | We understand that everyone's definition of a pipeline is a little (maybe a lot) different. Let's talk about what WE mean. 21 | 22 | In this context, a _pipeline_ is defined as all of the technical collateral required to take application source code and get it deployed through it's relevant lifecycle environments on an OpenShift cluster (or multiple clusters). 23 | 24 | A few guiding principles for a pipeline quickstart in this repo: 25 | - **Everything as code**. A pipeline should require as few commands as possible to deploy (We recommend an [openshift-applier](https://github.com/redhat-cop/openshift-applier) compatible inventory) 26 | - **Use OpenShift Features**. The intention of these quickstarts is to showcase how OpenShift can be used to make pipeline development and management simpler. Use of features like slave pods, webhooks, source to image and the `JenkinsPipelineStrategy` is highly desired where possible. 27 | - **Sharing is Caring**. If there are things that can be common to multiple pipelines (templates, builder images, etc.), let's refactor to make them shared. 28 | 29 | Typically the things required to build a pipeline sample include: 30 | - Project definitions (each representing a lifecycle environment) 31 | - A Jenkins Master 32 | - A jenkinsfile 33 | - A _build template_ that includes all things necessary to get the source code built into a container image. This means: 34 | - A JenkinsPipelineStrategy buildConfig, which is used to inject the pipeline into Jenkins automatically 35 | - A Source strategy binary buildConfig, which is used to build the container image 36 | - A deployment template that includes all the necessary objects to run the application in an environment. At a minimum: 37 | - A DeploymentConfig definition 38 | - A Service definition 39 | - it might also include: 40 | - Routes 41 | - Secrets 42 | - ConfigMaps 43 | - StatefulSets 44 | - etc. 45 | 46 | See our [basic spring boot](./basic-spring-boot) example for a very simple reference architecture. 47 | 48 | ## Automated Deployments 49 | 50 | These pipeline quickstarts include an Ansible inventory through which they can be automatically deployed and managed using the [OpenShift Applier](https://github.com/redhat-cop/openshift-applier) role. 51 | 52 | ## Optional: Use a container that contains ansible 53 | So you don't have to install ansible on your machine. Just type `oc run -i -t tool-box-test --image=quay.io/redhat-cop/tool-box --rm bash`. More into on the toolbox container can be found at https://github.com/redhat-cop/containers-quickstarts/tree/master/tool-box. 54 | -------------------------------------------------------------------------------- /_test/bats-support-clone.bash: -------------------------------------------------------------------------------- 1 | if [[ ! -d "_test/test_helper/bats-support" ]]; then 2 | # Download bats-support dynamically so it doesnt need to be added into source 3 | git clone https://github.com/ztombol/bats-support _test/test_helper/bats-support --depth 1 4 | fi 5 | 6 | if [[ ! -d "_test/test_helper/redhatcop-bats-library" ]]; then 7 | # Download redhat-cop/bats-library dynamically so it doesnt need to be added into source 8 | git clone https://github.com/redhat-cop/bats-library _test/test_helper/redhatcop-bats-library --depth 1 9 | fi -------------------------------------------------------------------------------- /_test/conftest.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bats 2 | 3 | load bats-support-clone 4 | load test_helper/bats-support/load 5 | load test_helper/redhatcop-bats-library/load 6 | 7 | setup_file() { 8 | rm -rf /tmp/rhcop 9 | conftest_pull 10 | } 11 | 12 | @test "basic-dotnet-core/.openshift" { 13 | tmp=$(split_files "basic-dotnet-core/.openshift") 14 | 15 | namespaces=$(get_rego_namespaces "ocp\.deprecated\.*") 16 | cmd="conftest test ${tmp} --output tap ${namespaces}" 17 | run ${cmd} 18 | 19 | print_info "${status}" "${output}" "${cmd}" "${tmp}" 20 | [ "$status" -eq 0 ] 21 | } 22 | 23 | @test "basic-nginx/.openshift" { 24 | tmp=$(split_files "basic-nginx/.openshift") 25 | 26 | namespaces=$(get_rego_namespaces "(?!ocp\.deprecated.ocp4_3\.buildconfig_jenkinspipeline_strategy)ocp\.deprecated\.*") 27 | cmd="conftest test ${tmp} --output tap ${namespaces}" 28 | run ${cmd} 29 | 30 | print_info "${status}" "${output}" "${cmd}" "${tmp}" 31 | [ "$status" -eq 0 ] 32 | } 33 | 34 | @test "basic-spring-boot/.openshift" { 35 | tmp=$(split_files "basic-spring-boot/.openshift") 36 | 37 | namespaces=$(get_rego_namespaces "ocp\.deprecated\.*") 38 | cmd="conftest test ${tmp} --output tap ${namespaces}" 39 | run ${cmd} 40 | 41 | print_info "${status}" "${output}" "${cmd}" "${tmp}" 42 | [ "$status" -eq 0 ] 43 | } 44 | 45 | @test "basic-spring-boot-tekton/.openshift" { 46 | tmp=$(split_files "basic-spring-boot-tekton/.openshift") 47 | 48 | namespaces=$(get_rego_namespaces "ocp\.deprecated\.*") 49 | cmd="conftest test ${tmp} --output tap ${namespaces}" 50 | run ${cmd} 51 | 52 | print_info "${status}" "${output}" "${cmd}" "${tmp}" 53 | [ "$status" -eq 0 ] 54 | } 55 | 56 | @test "basic-tomcat/.openshift" { 57 | tmp=$(split_files "basic-tomcat/.openshift") 58 | 59 | namespaces=$(get_rego_namespaces "(?!ocp\.deprecated.ocp4_3\.buildconfig_jenkinspipeline_strategy)ocp\.deprecated\.*") 60 | cmd="conftest test ${tmp} --output tap ${namespaces}" 61 | run ${cmd} 62 | 63 | print_info "${status}" "${output}" "${cmd}" "${tmp}" 64 | [ "$status" -eq 0 ] 65 | } 66 | 67 | @test "blue-green-spring/.openshift" { 68 | tmp=$(split_files "blue-green-spring/.openshift") 69 | 70 | namespaces=$(get_rego_namespaces "(?!ocp\.deprecated.ocp4_3\.buildconfig_jenkinspipeline_strategy)ocp\.deprecated\.*") 71 | cmd="conftest test ${tmp} --output tap ${namespaces}" 72 | run ${cmd} 73 | 74 | print_info "${status}" "${output}" "${cmd}" "${tmp}" 75 | [ "$status" -eq 0 ] 76 | } 77 | 78 | @test "cucumber-selenium-grid/applier" { 79 | tmp=$(split_files "cucumber-selenium-grid/applier") 80 | 81 | namespaces=$(get_rego_namespaces "(?!ocp\.deprecated.ocp4_3\.buildconfig_jenkinspipeline_strategy)ocp\.deprecated\.*") 82 | cmd="conftest test ${tmp} --output tap ${namespaces}" 83 | run ${cmd} 84 | 85 | print_info "${status}" "${output}" "${cmd}" "${tmp}" 86 | [ "$status" -eq 0 ] 87 | } 88 | 89 | @test "jenkins-s2i" { 90 | tmp=$(split_files "jenkins-s2i") 91 | 92 | namespaces=$(get_rego_namespaces "ocp\.deprecated\.*") 93 | cmd="conftest test ${tmp} --output tap ${namespaces}" 94 | run ${cmd} 95 | 96 | print_info "${status}" "${output}" "${cmd}" "${tmp}" 97 | [ "$status" -eq 0 ] 98 | } 99 | 100 | @test "multi-cluster-multi-branch-jee/.openshift" { 101 | tmp=$(split_files "multi-cluster-multi-branch-jee/.openshift") 102 | 103 | namespaces=$(get_rego_namespaces "ocp\.deprecated\.*") 104 | cmd="conftest test ${tmp} --output tap ${namespaces}" 105 | run ${cmd} 106 | 107 | print_info "${status}" "${output}" "${cmd}" "${tmp}" 108 | [ "$status" -eq 0 ] 109 | } 110 | 111 | @test "multi-cluster-spring-boot/image-mirror-example/.applier" { 112 | tmp=$(split_files "multi-cluster-spring-boot/image-mirror-example/.applier") 113 | 114 | namespaces=$(get_rego_namespaces "(?!ocp\.deprecated.ocp4_3\.buildconfig_jenkinspipeline_strategy)ocp\.deprecated\.*") 115 | cmd="conftest test ${tmp} --output tap ${namespaces}" 116 | run ${cmd} 117 | 118 | print_info "${status}" "${output}" "${cmd}" "${tmp}" 119 | [ "$status" -eq 0 ] 120 | } 121 | 122 | @test "multi-cluster-spring-boot/skopeo-example/.applier" { 123 | tmp=$(split_files "multi-cluster-spring-boot/skopeo-example/.applier") 124 | 125 | namespaces=$(get_rego_namespaces "(?!ocp\.deprecated.ocp4_3\.buildconfig_jenkinspipeline_strategy)ocp\.deprecated\.*") 126 | cmd="conftest test ${tmp} --output tap ${namespaces}" 127 | run ${cmd} 128 | 129 | print_info "${status}" "${output}" "${cmd}" "${tmp}" 130 | [ "$status" -eq 0 ] 131 | } 132 | 133 | @test "secure-spring-boot/.openshift-applier" { 134 | tmp=$(split_files "secure-spring-boot/.openshift-applier") 135 | 136 | namespaces=$(get_rego_namespaces "ocp\.deprecated\.*") 137 | cmd="conftest test ${tmp} --output tap ${namespaces}" 138 | run ${cmd} 139 | 140 | print_info "${status}" "${output}" "${cmd}" "${tmp}" 141 | [ "$status" -eq 0 ] 142 | } -------------------------------------------------------------------------------- /basic-dotnet-core/.applier/group_vars/seed-hosts.yml: -------------------------------------------------------------------------------- 1 | sb_application_name: basic-dotnet-core 2 | sb_build_namespace: basic-dotnet-core-build 3 | sb_dev_namespace: basic-dotnet-core-dev 4 | sb_stage_namespace: basic-dotnet-core-stage 5 | sb_prod_namespace: basic-dotnet-core-prod 6 | sb_application_repository_url: "https://github.com/redhat-developer/s2i-dotnetcore-ex.git" 7 | sb_application_repository_ref: master 8 | sb_application_readiness_response: "html" 9 | sb_application_readiness_path: "/" 10 | sb_sa_name: "jenkins" 11 | sb_source_repository_url: "https://github.com/redhat-cop/container-pipelines.git" 12 | sb_source_repository_ref: master 13 | sb_pipeline_script: "Jenkinsfile" 14 | 15 | openshift_cluster_content: 16 | - object: projects 17 | content: 18 | - name: "create environments" 19 | file: "{{ inventory_dir }}/../.openshift/projects/projects.yml" 20 | action: create 21 | tags: 22 | - project 23 | - object: builds 24 | content: 25 | - name: "deploy build pipeline to dev" 26 | template: "{{ inventory_dir }}/../.openshift/templates/build.yml" 27 | params_from_vars: 28 | APPLICATION_NAME: "{{ sb_application_name }}" 29 | NAMESPACE: "{{ sb_build_namespace }}" 30 | SOURCE_REPOSITORY_URL: "{{ sb_source_repository_url }}" 31 | SOURCE_REPOSITORY_REF: "{{ sb_source_repository_ref }}" 32 | APPLICATION_SOURCE_REPO: "{{ sb_application_repository_url }}" 33 | APPLICATION_SOURCE_REF: "{{ sb_application_repository_ref }}" 34 | PIPELINE_SCRIPT: "{{ sb_pipeline_script }}" 35 | tags: 36 | - build 37 | - object: deployments 38 | content: 39 | - name: "deploy dev environment" 40 | template: "{{ inventory_dir }}/../.openshift/templates/deployment.yml" 41 | params_from_vars: 42 | APPLICATION_NAME: "{{ sb_application_name }}" 43 | NAMESPACE: "{{ sb_dev_namespace }}" 44 | SA_NAMESPACE: "{{ sb_build_namespace }}" 45 | READINESS_RESPONSE: "{{ sb_application_readiness_response }}" 46 | READINESS_PATH: "{{ sb_application_readiness_path }}" 47 | tags: 48 | - deployment 49 | - name: "deply stage environment" 50 | template: "{{ inventory_dir }}/../.openshift/templates/deployment.yml" 51 | params_from_vars: 52 | APPLICATION_NAME: "{{ sb_application_name }}" 53 | NAMESPACE: "{{ sb_stage_namespace }}" 54 | SA_NAME: "{{ sb_sa_name }}" 55 | SA_NAMESPACE: "{{ sb_build_namespace }}" 56 | READINESS_RESPONSE: "{{ sb_application_readiness_response }}" 57 | READINESS_PATH: "{{ sb_application_readiness_path }}" 58 | tags: 59 | - deployment 60 | - name: "deply prod environment" 61 | template: "{{ inventory_dir }}/../.openshift/templates/deployment.yml" 62 | params_from_vars: 63 | APPLICATION_NAME: "{{ sb_application_name }}" 64 | NAMESPACE: "{{ sb_prod_namespace }}" 65 | SA_NAME: "{{ sb_sa_name }}" 66 | SA_NAMESPACE: "{{ sb_build_namespace }}" 67 | READINESS_RESPONSE: "{{ sb_application_readiness_response }}" 68 | READINESS_PATH: "{{ sb_application_readiness_path }}" 69 | tags: 70 | - deployment 71 | -------------------------------------------------------------------------------- /basic-dotnet-core/.applier/hosts: -------------------------------------------------------------------------------- 1 | [seed-hosts] 2 | localhost ansible_connection=local 3 | -------------------------------------------------------------------------------- /basic-dotnet-core/.gitignore: -------------------------------------------------------------------------------- 1 | galaxy 2 | -------------------------------------------------------------------------------- /basic-dotnet-core/.openshift/projects/projects.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: List 3 | items: 4 | - apiVersion: project.openshift.io/v1 5 | kind: ProjectRequest 6 | metadata: 7 | name: basic-dotnet-core-build 8 | creationTimestam: null 9 | displayName: .NET Core App - Build 10 | - apiVersion: project.openshift.io/v1 11 | kind: ProjectRequest 12 | metadata: 13 | name: basic-dotnet-core-dev 14 | creationTimestam: null 15 | displayName: .NET Core App - Dev 16 | - apiVersion: project.openshift.io/v1 17 | kind: ProjectRequest 18 | metadata: 19 | name: basic-dotnet-core-stage 20 | creationTimestam: null 21 | displayName: .NET Core Appp - Stage 22 | - apiVersion: project.openshift.io/v1 23 | kind: ProjectRequest 24 | metadata: 25 | name: basic-dotnet-core-prod 26 | creationTimestam: null 27 | displayName: .NET Core App - Prod 28 | -------------------------------------------------------------------------------- /basic-dotnet-core/.openshift/templates/deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: basic-dotnet-core 5 | metadata: 6 | annotations: 7 | description: Application template for .NET Core applications built using a Jenkins Pipeline 8 | iconClass: icon-tomcat 9 | version: 1.2.0 10 | name: basic-dotnet-core 11 | objects: 12 | - apiVersion: v1 13 | kind: Service 14 | metadata: 15 | annotations: 16 | description: The web server's http port. 17 | labels: 18 | app: ${APPLICATION_NAME} 19 | name: ${APPLICATION_NAME} 20 | namespace: ${NAMESPACE} 21 | spec: 22 | ports: 23 | - port: 8080 24 | targetPort: 8080 25 | selector: 26 | deploymentConfig: ${APPLICATION_NAME} 27 | - apiVersion: route.openshift.io/v1 28 | kind: Route 29 | metadata: 30 | annotations: 31 | description: Route for application's http service. 32 | labels: 33 | app: ${APPLICATION_NAME} 34 | name: ${APPLICATION_NAME} 35 | namespace: ${NAMESPACE} 36 | spec: 37 | host: ${HOSTNAME_HTTP} 38 | to: 39 | name: ${APPLICATION_NAME} 40 | - apiVersion: image.openshift.io/v1 41 | kind: ImageStream 42 | metadata: 43 | labels: 44 | app: ${APPLICATION_NAME} 45 | name: ${APPLICATION_NAME} 46 | namespace: ${NAMESPACE} 47 | - apiVersion: apps.openshift.io/v1 48 | kind: DeploymentConfig 49 | metadata: 50 | labels: 51 | app: ${APPLICATION_NAME} 52 | name: ${APPLICATION_NAME} 53 | namespace: ${NAMESPACE} 54 | spec: 55 | replicas: 1 56 | selector: 57 | deploymentConfig: ${APPLICATION_NAME} 58 | strategy: 59 | type: Recreate 60 | template: 61 | metadata: 62 | labels: 63 | app: ${APPLICATION_NAME} 64 | deploymentConfig: ${APPLICATION_NAME} 65 | name: ${APPLICATION_NAME} 66 | spec: 67 | containers: 68 | - env: 69 | - name: JWS_ADMIN_USERNAME 70 | value: ${JWS_ADMIN_USERNAME} 71 | - name: JWS_ADMIN_PASSWORD 72 | value: ${JWS_ADMIN_PASSWORD} 73 | image: ${APPLICATION_NAME} 74 | imagePullPolicy: Always 75 | name: ${APPLICATION_NAME} 76 | ports: 77 | - containerPort: 8778 78 | name: jolokia 79 | protocol: TCP 80 | - containerPort: 8080 81 | name: http 82 | protocol: TCP 83 | readinessProbe: 84 | exec: 85 | command: 86 | - /bin/bash 87 | - -c 88 | - curl -s 'http://localhost:8080${READINESS_PATH}' 89 | |grep -iq '${READINESS_RESPONSE}' 90 | terminationGracePeriodSeconds: 60 91 | triggers: 92 | - imageChangeParams: 93 | automatic: true 94 | containerNames: 95 | - ${APPLICATION_NAME} 96 | from: 97 | kind: ImageStreamTag 98 | name: ${APPLICATION_NAME}:latest 99 | type: ImageChange 100 | - type: ConfigChange 101 | - apiVersion: rbac.authorization.k8s.io/v1 102 | kind: RoleBinding 103 | metadata: 104 | creationTimestamp: null 105 | labels: 106 | template: basic-tomcat-template 107 | name: jenkins_edit 108 | namespace: ${NAMESPACE} 109 | groupNames: null 110 | roleRef: 111 | apiGroup: rbac.authorization.k8s.io 112 | kind: ClusterRole 113 | name: edit 114 | subjects: 115 | - kind: ServiceAccount 116 | name: ${SA_NAME} 117 | namespace: ${SA_NAMESPACE} 118 | userNames: 119 | - system:serviceaccount:${SA_NAMESPACE}:${SA_NAME} 120 | parameters: 121 | - description: The name for the application. 122 | name: APPLICATION_NAME 123 | required: true 124 | value: basic-dotnet-core 125 | - description: The namespace to deploy into 126 | name: NAMESPACE 127 | required: true 128 | - description: Name of a service account that can deploy to this project 129 | name: SA_NAME 130 | required: true 131 | value: jenkins 132 | - description: Namespace of service account that can deploy to this project 133 | name: SA_NAMESPACE 134 | required: true 135 | - description: 'Custom hostname for http service route. Leave blank for default hostname, 136 | e.g.: -.' 137 | name: HOSTNAME_HTTP 138 | - description: 'URI to check for app health' 139 | name: READINESS_PATH 140 | required: true 141 | value: '/' 142 | - description: 'String value expected back from readiness check' 143 | name: READINESS_RESPONSE 144 | required: true 145 | value: 'Hello World!' 146 | -------------------------------------------------------------------------------- /basic-dotnet-core/Jenkinsfile: -------------------------------------------------------------------------------- 1 | library identifier: "pipeline-library@v1.6", 2 | retriever: modernSCM( 3 | [ 4 | $class: "GitSCMSource", 5 | remote: "https://github.com/redhat-cop/pipeline-library.git" 6 | ] 7 | ) 8 | 9 | openshift.withCluster() { 10 | env.NAMESPACE = openshift.project() 11 | env.APP_NAME = "${JOB_NAME}".replaceAll(/-build.*/, '') 12 | echo "Starting Pipeline for ${APP_NAME}..." 13 | env.BUILD = "${env.NAMESPACE}" 14 | env.DEV = "${APP_NAME}-dev" 15 | env.STAGE = "${APP_NAME}-stage" 16 | env.PROD = "${APP_NAME}-prod" 17 | } 18 | 19 | pipeline { 20 | // Use Jenkins dotnet-22 slave 21 | // Jenkins will dynamically provision this as OpenShift Pod 22 | // All the stages and steps of this Pipeline will be executed on this Pod 23 | // After Pipeline completes the Pod is killed so every run will have clean 24 | // workspace 25 | agent { 26 | label 'dotnet-22' 27 | } 28 | 29 | // Pipeline Stages start here 30 | // Requeres at least one stage 31 | stages { 32 | 33 | // Checkout source code 34 | // This is required as Pipeline code is originally checkedout to 35 | // Jenkins Master but this will also pull this same code to this slave 36 | stage('Git Checkout') { 37 | steps { 38 | // Turn off Git's SSL cert check, uncomment if needed 39 | // sh 'git config --global http.sslVerify false' 40 | git url: "${APPLICATION_SOURCE_REPO}", branch: "${APPLICATION_SOURCE_REF}" 41 | } 42 | } 43 | 44 | // Run Maven build, skipping tests 45 | stage('publish') { 46 | steps { 47 | dir('app') { 48 | sh "dotnet publish -c Release /p:MicrosoftNETPlatformLibrary=Microsoft.NETCore.App" 49 | } 50 | } 51 | } 52 | 53 | // Build Container Image using the artifacts produced in previous stages 54 | stage('Build Container Image'){ 55 | steps { 56 | // Build container image using local Openshift cluster 57 | // Giving all the artifacts to OpenShift Binary Build 58 | // This places your artifacts into right location inside your S2I image 59 | // if the S2I image supports it. 60 | binaryBuild(projectName: env.BUILD, buildConfigName: env.APP_NAME, buildFromPath: "app/bin/Release/netcoreapp2.0/publish") 61 | } 62 | } 63 | 64 | stage('Promote from Build to Dev') { 65 | steps { 66 | tagImage(sourceImageName: env.APP_NAME, sourceImagePath: env.BUILD, toImagePath: env.DEV) 67 | } 68 | } 69 | 70 | stage ('Verify Deployment to Dev') { 71 | steps { 72 | verifyDeployment(projectName: env.DEV, targetApp: env.APP_NAME) 73 | } 74 | } 75 | 76 | stage('Promote from Dev to Stage') { 77 | steps { 78 | tagImage(sourceImageName: env.APP_NAME, sourceImagePath: env.DEV, toImagePath: env.STAGE) 79 | } 80 | } 81 | 82 | stage ('Verify Deployment to Stage') { 83 | steps { 84 | verifyDeployment(projectName: env.STAGE, targetApp: env.APP_NAME) 85 | } 86 | } 87 | 88 | stage('Promotion gate') { 89 | steps { 90 | script { 91 | input message: 'Promote application to Production?' 92 | } 93 | } 94 | } 95 | 96 | stage('Promote from Stage to Prod') { 97 | steps { 98 | tagImage(sourceImageName: env.APP_NAME, sourceImagePath: env.STAGE, toImagePath: env.PROD) 99 | } 100 | } 101 | 102 | stage ('Verify Deployment to Prod') { 103 | steps { 104 | verifyDeployment(projectName: env.PROD, targetApp: env.APP_NAME) 105 | } 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /basic-dotnet-core/requirements.yml: -------------------------------------------------------------------------------- 1 | # This is the Ansible Galaxy requirements file to pull in the correct roles 2 | # to support the operation of CASL provisioning/runs. 3 | 4 | # From 'openshift-applier' 5 | - name: openshift-applier 6 | scm: git 7 | src: https://github.com/redhat-cop/openshift-applier 8 | version: v2.1.2 9 | -------------------------------------------------------------------------------- /basic-helm-spring-boot/.helm/jenkins-agent-helm/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: jenkins-agent-helm 3 | description: A chart for building the jenkins-agent-helm Jenkins agent, containing Helm, ct, and oc 4 | version: 1.0.0 -------------------------------------------------------------------------------- /basic-helm-spring-boot/.helm/jenkins-agent-helm/templates/buildconfig.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: build.openshift.io/v1 2 | kind: BuildConfig 3 | metadata: 4 | labels: 5 | application: {{ .Release.Name }} 6 | name: {{ .Release.Name }} 7 | namespace: {{ .Release.Namespace }} 8 | spec: 9 | output: 10 | to: 11 | kind: ImageStreamTag 12 | name: {{ .Release.Name }}:{{ .Values.destTag }} 13 | source: 14 | type: Git 15 | git: 16 | uri: {{ .Values.uri }} 17 | ref: {{ .Values.ref }} 18 | contextDir: {{ .Values.contextDir }} 19 | strategy: 20 | dockerStrategy: 21 | dockerfilePath: {{ .Values.dockerfilePath }} 22 | type: Docker 23 | triggers: 24 | - type: ConfigChange -------------------------------------------------------------------------------- /basic-helm-spring-boot/.helm/jenkins-agent-helm/templates/imagestream.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: image.openshift.io/v1 2 | kind: ImageStream 3 | metadata: 4 | labels: 5 | application: {{ .Release.Name }} 6 | role: jenkins-slave 7 | name: {{ .Release.Name }} 8 | namespace: {{ .Release.Namespace }} -------------------------------------------------------------------------------- /basic-helm-spring-boot/.helm/jenkins-agent-helm/values.yaml: -------------------------------------------------------------------------------- 1 | destTag: latest 2 | 3 | uri: https://github.com/redhat-cop/containers-quickstarts.git 4 | ref: master 5 | 6 | contextDir: jenkins-agents/jenkins-agent-helm 7 | 8 | dockerfilePath: Dockerfile -------------------------------------------------------------------------------- /basic-helm-spring-boot/.helm/spring-boot-build/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: spring-boot-build 3 | description: A chart for building your Spring Boot app 4 | version: 1.0.0 -------------------------------------------------------------------------------- /basic-helm-spring-boot/.helm/spring-boot-build/templates/buildconfig.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: build.openshift.io/v1 2 | kind: BuildConfig 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: {{ .Values.name }} 6 | app.kubernetes.io/managed-by: {{ .Release.Service }} 7 | name: {{ .Values.name }} 8 | spec: 9 | output: 10 | to: 11 | kind: ImageStreamTag 12 | name: {{ .Values.name }}:{{ required "value 'tag' is required" .Values.tag }} 13 | source: 14 | type: Binary 15 | binary: {} 16 | strategy: 17 | sourceStrategy: 18 | from: 19 | kind: ImageStreamTag 20 | name: {{ .Values.builderImageStreamTag }} 21 | namespace: {{ .Values.builderImageStreamNamespace }} 22 | type: Source 23 | triggers: [] -------------------------------------------------------------------------------- /basic-helm-spring-boot/.helm/spring-boot-build/templates/imagestream.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: image.openshift.io/v1 2 | kind: ImageStream 3 | metadata: 4 | labels: 5 | app.kubernetes.io/name: {{ .Values.name }} 6 | app.kubernetes.io/managed-by: {{ .Release.Service }} 7 | name: {{ .Values.name }} -------------------------------------------------------------------------------- /basic-helm-spring-boot/.helm/spring-boot-build/values.yaml: -------------------------------------------------------------------------------- 1 | ## Required (provided by pipeline) 2 | tag: 3 | 4 | builderImageStreamTag: java:8 5 | builderImageStreamNamespace: openshift -------------------------------------------------------------------------------- /basic-helm-spring-boot/.helm/spring-boot/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: spring-boot 3 | description: A chart for deploying your Spring Boot app 4 | version: 1.0.0 -------------------------------------------------------------------------------- /basic-helm-spring-boot/.helm/spring-boot/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ .Release.Name }} 5 | labels: 6 | app.kubernetes.io/name: {{ .Release.Name }} 7 | app.kubernetes.io/managed-by: {{ .Release.Service }} 8 | annotations: 9 | image.openshift.io/triggers: |- 10 | [ 11 | { 12 | "from":{ 13 | "kind":"ImageStreamTag", 14 | "name":"{{ .Release.Name }}:{{ .Values.tag }}" 15 | }, 16 | "fieldPath":"spec.template.spec.containers[0].image" 17 | } 18 | ] 19 | spec: 20 | replicas: {{ .Values.replicas }} 21 | selector: 22 | matchLabels: 23 | app.kubernetes.io/name: {{ .Release.Name }} 24 | strategy: 25 | type: {{ .Values.strategy }} 26 | template: 27 | metadata: 28 | labels: 29 | app.kubernetes.io/name: {{ .Release.Name }} 30 | spec: 31 | containers: 32 | - name: {{ .Release.Name }} 33 | image: {{ .Release.Name }}:{{ .Values.tag }} 34 | imagePullPolicy: Always 35 | {{- if .Values.enableLiveness }} 36 | readinessProbe: 37 | httpGet: 38 | path: / 39 | port: {{ .Values.port }} 40 | {{- end }} -------------------------------------------------------------------------------- /basic-helm-spring-boot/.helm/spring-boot/templates/route.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: route.openshift.io/v1 2 | kind: Route 3 | metadata: 4 | name: {{ .Release.Name }} 5 | labels: 6 | app.kubernetes.io/name: {{ .Release.Name }} 7 | app.kubernetes.io/managed-by: {{ .Release.Service }} 8 | spec: 9 | to: 10 | kind: Service 11 | name: {{ .Release.Name }} -------------------------------------------------------------------------------- /basic-helm-spring-boot/.helm/spring-boot/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Release.Name }} 5 | labels: 6 | app.kubernetes.io/name: {{ .Release.Name }} 7 | app.kubernetes.io/managed-by: {{ .Release.Service }} 8 | spec: 9 | ports: 10 | - port: {{ .Values.port }} 11 | selector: 12 | app.kubernetes.io/name: {{ .Release.Name }} -------------------------------------------------------------------------------- /basic-helm-spring-boot/.helm/spring-boot/values.yaml: -------------------------------------------------------------------------------- 1 | ## Required (provided by pipeline) 2 | tag: 3 | 4 | replicas: 1 5 | 6 | port: 8080 7 | 8 | enableReadiness: true 9 | 10 | strategy: Recreate -------------------------------------------------------------------------------- /basic-helm-spring-boot/Jenkinsfile: -------------------------------------------------------------------------------- 1 | library identifier: "pipeline-library@v1.6", 2 | retriever: modernSCM( 3 | [ 4 | $class: "GitSCMSource", 5 | remote: "https://github.com/redhat-cop/pipeline-library.git" 6 | ] 7 | ) 8 | 9 | // URL and Ref to the Spring Boot application 10 | appSourceUrl = "https://github.com/redhat-cop/spring-rest.git" 11 | appSourceRef = "master" 12 | 13 | // Folder containing the Spring Boot application 14 | appFolder = "spring-rest" 15 | 16 | // Folder containing the Helm pipeline 17 | helmFolder = "basic-helm-spring-boot" 18 | 19 | // The name you want to give your Spring Boot application 20 | // Each resource related to your app will be given this name 21 | appName = "my-app" 22 | 23 | pipeline { 24 | agent { label "jenkins-agent-helm" } 25 | stages { 26 | stage("Checkout") { 27 | steps { 28 | // This creates a separate folder to clone the Spring Boot app to 29 | sh "mkdir ${appFolder}" 30 | dir(appFolder) { 31 | git url: "${appSourceUrl}", branch: "${appSourceRef}" 32 | } 33 | } 34 | } 35 | stage("Get Version from POM") { 36 | steps { 37 | script { 38 | dir(appFolder) { 39 | tag = readMavenPom().getVersion() 40 | } 41 | } 42 | } 43 | } 44 | stage("S2I Build") { 45 | steps { 46 | // This installs or upgrades the spring-boot-build Helm chart. 47 | // It creates or updates your application's BuildConfig and ImageStream 48 | dir(helmFolder) { 49 | sh "helm upgrade --install ${appName}-build .helm/spring-boot-build --set name=${appName} --set tag=${tag}" 50 | } 51 | 52 | // This uploads your application's source code and performs a binary build in OpenShift 53 | dir(appFolder) { 54 | binaryBuild(buildConfigName: appName, buildFromPath: ".") 55 | } 56 | } 57 | } 58 | stage("Deploy") { 59 | steps { 60 | // This installs or upgrades the spring-boot Helm chart 61 | // It creates or updates your application's Kubernetes resources 62 | // It also waits until the readiness probe returns successfully 63 | dir(helmFolder) { 64 | sh "helm upgrade --install ${appName} .helm/spring-boot --set tag=${tag} --wait" 65 | } 66 | } 67 | } 68 | } 69 | } -------------------------------------------------------------------------------- /basic-helm-spring-boot/README.md: -------------------------------------------------------------------------------- 1 | # A Sample OpenShift Pipeline for a Spring Boot Application Using Helm 2 | 3 | This Jenkins pipeline provides an example of how to build a [basic Spring Boot application](https://github.com/redhat-cop/spring-rest) using Helm. The pipeline runs using the CoP's [jenkins-agent-helm](https://github.com/redhat-cop/containers-quickstarts/tree/master/jenkins-agents/jenkins-agent-helm) agent and contains the following steps: 4 | 5 | 1. `Checkout`: Checks out the spring-rest application 6 | 1. `Get Version From POM`: Gets the version defined in the pom.xml file. This version is used to set your image's tag. 7 | 1. `S2I Build`: Performs an [s2i build](https://docs.openshift.com/container-platform/4.5/builds/understanding-image-builds.html#build-strategy-s2i_understanding-image-builds). This stage runs your unit tests, builds your jar file, and builds your container image. You could split this stage like the [basic-spring-boot](../basic-spring-boot) example if desired, but the jenkins-agent-helm agent doesn't have maven on it, so in this case, it's easier to perform an s2i build instead. 8 | 1. `Deploy`: Deploys your application to OpenShift. 9 | 10 | This pipeline uses two different Helm charts called [spring-boot-build](./spring-boot-build) and [spring-boot](./spring-boot). The `spring-boot-build` chart is used in the `S2I Build` stage to create and update your BuildConfig and ImageStream. The `spring-boot` chart is used in the `Deploy` stage to create and update your application's Kubernetes resources. While you could combine both of these charts into one, splitting into separate charts for building and deploying provides a greater separation of concerns. 11 | 12 | Before you configure this pipeline, you must first build a Jenkins agent containing Helm. Let's look at how you can build the [jenkins-agent-helm](https://github.com/redhat-cop/containers-quickstarts/tree/master/jenkins-agents/jenkins-agent-helm) agent. 13 | 14 | ## Building the jenkins-agent-helm Agent 15 | While the pipeline itself only uses the spring-boot and spring-boot-build Helm charts, a third Helm chart is provided under the `.helm/` folder called `jenkins-agent-helm` that you can use to easily build this Jenkins agent. First, install the jenkins-agent-helm Helm chart, which creates a BuildConfig and ImageStream: 16 | 17 | ```bash 18 | helm install jenkins-agent-helm .helm/jenkins-agent-helm 19 | ``` 20 | 21 | The first build will automatically run. You can follow this build by running: 22 | 23 | ```bash 24 | oc logs bc/jenkins-agent-helm -f 25 | ``` 26 | 27 | This ImageStream created by Helm already has the `role: jenkins-slave` label, so Jenkins will see this and automatically use this image to configure a new Jenkins agent. 28 | 29 | Next, let's configure the Jenkins pipeline. 30 | 31 | ## Configuring This Jenkins Pipeline 32 | 33 | Because the `JenkinsPipeline` build strategy is deprecated in OpenShift 4.x, this doc will describe how you can configure this pipeline manually within the Jenkins console. 34 | 35 | First, deploy a Jenkins instance to OpenShift. You can deploy Jenkins by running this command: 36 | 37 | ```bash 38 | oc new-app jenkins-persistent 39 | ``` 40 | 41 | Once Jenkins is up, find and access your route URL: 42 | 43 | ```bash 44 | oc get route jenkins -o jsonpath='{.spec.host}' 45 | ``` 46 | 47 | Then, follow these steps: 48 | 49 | 1. Click `New Item` on the lefthand side of the screen 50 | 1. Enter a name for this pipeline. The suggested name is `basic-helm-spring-boot`. 51 | 1. Select `Pipeline` and click `Ok` 52 | 1. Scroll down to the bottom of the screen to the `Pipeline` section. Change the "Pipeline script" dropdown to `Pipeline script from SCM`. 53 | 1. For "SCM", select `Git` and enter the Repository URL `https://github.com/redhat-cop/container-pipelines.git` 54 | 1. For "Script Path", enter `basic-helm-spring-boot/Jenkinsfile` 55 | 1. Click `Save` 56 | 57 | Once you configure your pipeline, you can click `Build Now` on the lefthand side of your screen to start the pipeline. 58 | 59 | ## Validating Your Deployment 60 | You can validate your deployment was successful with the following commands: 61 | 62 | ```bash 63 | ROUTE=$(oc get route my-app -o jsonpath='{.spec.host}') 64 | curl $ROUTE/v1/greeting 65 | ``` -------------------------------------------------------------------------------- /basic-nginx/.applier/group_vars/seed-hosts.yml: -------------------------------------------------------------------------------- 1 | source_code_url: https://github.com/redhat-cop/container-pipelines.git 2 | source_code_ref: master 3 | skip_manual_promotion: false 4 | 5 | openshift_cluster_content: 6 | - object: projectrequest 7 | content: 8 | - name: basic-nginx-spaces 9 | file: "{{ inventory_dir }}/../.openshift/projects/projects.yml" 10 | action: create 11 | - object: deployments 12 | content: 13 | - name: jenkins 14 | namespace: basic-nginx-build 15 | template: openshift//jenkins-ephemeral 16 | - name: basic-nginx-dev 17 | template: "{{ inventory_dir }}/../.openshift/deployment/template.yml" 18 | params: "{{ inventory_dir }}/../.openshift/deployment/dev/params" 19 | - name: basic-nginx-stage 20 | template: "{{ inventory_dir }}/../.openshift/deployment/template.yml" 21 | params: "{{ inventory_dir }}/../.openshift/deployment/stage/params" 22 | - name: basic-nginx-prod 23 | template: "{{ inventory_dir }}/../.openshift/deployment/template.yml" 24 | params: "{{ inventory_dir }}/../.openshift/deployment/prod/params" 25 | - object: builds 26 | content: 27 | - name: jenkins 28 | template: "{{ inventory_dir }}/../.openshift/builds/template.yml" 29 | params: "{{ inventory_dir }}/../.openshift/builds/params" 30 | params_from_vars: 31 | SOURCE_REPOSITORY_URL: "{{ source_code_url }}" 32 | SOURCE_REPOSITORY_REF: "{{ source_code_ref }}" 33 | SKIP_MANUAL_PROMOTION: "{{ skip_manual_promotion }}" 34 | -------------------------------------------------------------------------------- /basic-nginx/.applier/hosts: -------------------------------------------------------------------------------- 1 | [seed-hosts] 2 | localhost ansible_connection=local -------------------------------------------------------------------------------- /basic-nginx/.openshift/builds/params: -------------------------------------------------------------------------------- 1 | NAMESPACE=basic-nginx-build -------------------------------------------------------------------------------- /basic-nginx/.openshift/builds/template.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: generic-nginx-jenkins-pipeline 5 | metadata: 6 | annotations: 7 | description: Application template for nginx applications built using a Jenkins Pipeline 8 | iconClass: icon-nginx 9 | tags: nginx,xpaas,jenkins-ci 10 | version: 1.2.0 11 | name: generic-nginx-jenkins-pipeline 12 | objects: 13 | - apiVersion: build.openshift.io/v1 14 | kind: BuildConfig 15 | metadata: 16 | labels: 17 | app.kubernetes.io/name: ${APPLICATION_NAME} 18 | app.kubernetes.io/instance: ${APPLICATION_NAME}-build 19 | app.kubernetes.io/component: api 20 | app.kubernetes.io/part-of: ${APPLICATION_NAME} 21 | app.kubernetes.io/managed-by: applier 22 | name: "${APPLICATION_NAME}-pipeline" 23 | namespace: "${NAMESPACE}" 24 | spec: 25 | source: 26 | type: Git 27 | git: 28 | uri: ${SOURCE_REPOSITORY_URL} 29 | ref: ${SOURCE_REPOSITORY_REF} 30 | contextDir: ${CONTEXT_DIR} 31 | triggers: 32 | - type: "GitHub" 33 | github: 34 | secret: ${GITHUB_WEBHOOK_SECRET} 35 | - type: "ConfigChange" 36 | strategy: 37 | type: "JenkinsPipeline" 38 | jenkinsPipelineStrategy: 39 | jenkinsfilePath: ${PIPELINE_SCRIPT} 40 | env: 41 | - name: "SOURCE_REPOSITORY_URL" 42 | value: "${SOURCE_REPOSITORY_URL}" 43 | - name: "SOURCE_REPOSITORY_REF" 44 | value: "${SOURCE_REPOSITORY_REF}" 45 | - name: "CONTEXT_DIR" 46 | value: "${CONTEXT_DIR}" 47 | - name: "SKIP_MANUAL_PROMOTION" 48 | value: "${SKIP_MANUAL_PROMOTION}" 49 | - apiVersion: build.openshift.io/v1 50 | kind: BuildConfig 51 | metadata: 52 | labels: 53 | app.kubernetes.io/name: ${APPLICATION_NAME} 54 | app.kubernetes.io/instance: ${APPLICATION_NAME}-build 55 | app.kubernetes.io/component: api 56 | app.kubernetes.io/part-of: ${APPLICATION_NAME} 57 | app.kubernetes.io/managed-by: applier 58 | name: ${APPLICATION_NAME} 59 | namespace: "${NAMESPACE}" 60 | spec: 61 | failedBuildHistoryLimit: 3 62 | output: 63 | to: 64 | kind: ImageStreamTag 65 | name: ${APPLICATION_NAME}:latest 66 | source: 67 | binary: {} 68 | type: Binary 69 | strategy: 70 | sourceStrategy: 71 | from: 72 | kind: ImageStreamTag 73 | name: ${IMAGE_STREAM_TAG_NAME} 74 | namespace: ${IMAGE_STREAM_NAMESPACE} 75 | type: Source 76 | successfulBuildHistoryLimit: 3 77 | - apiVersion: image.openshift.io/v1 78 | kind: ImageStream 79 | metadata: 80 | labels: 81 | app.kubernetes.io/name: ${APPLICATION_NAME} 82 | app.kubernetes.io/instance: ${APPLICATION_NAME}-build 83 | app.kubernetes.io/component: api 84 | app.kubernetes.io/part-of: ${APPLICATION_NAME} 85 | app.kubernetes.io/managed-by: applier 86 | name: ${APPLICATION_NAME} 87 | namespace: ${NAMESPACE} 88 | parameters: 89 | - description: The name for the application. 90 | name: APPLICATION_NAME 91 | required: true 92 | value: basic-nginx 93 | - description: The namespace to deploy into 94 | name: NAMESPACE 95 | required: true 96 | - description: Git source URI for application 97 | name: SOURCE_REPOSITORY_URL 98 | required: true 99 | - description: Git branch/tag reference 100 | name: SOURCE_REPOSITORY_REF 101 | - description: skip promotion flag so manual process is waived 102 | name: SKIP_MANUAL_PROMOTION 103 | - description: Path within Git project to build; empty for root project directory. 104 | name: CONTEXT_DIR 105 | value: "basic-nginx" 106 | - description: Path within Git project pointing to the pipeline run script 107 | name: PIPELINE_SCRIPT 108 | value: Jenkinsfile 109 | - description: GitHub trigger secret 110 | from: '[a-zA-Z0-9]{8}' 111 | generate: expression 112 | name: GITHUB_WEBHOOK_SECRET 113 | required: true 114 | - description: Generic build trigger secret 115 | from: '[a-zA-Z0-9]{8}' 116 | generate: expression 117 | name: GENERIC_WEBHOOK_SECRET 118 | required: true 119 | - description: Namespace in which the ImageStreams for Red Hat Middleware images are 120 | installed. These ImageStreams are normally installed in the openshift namespace. 121 | You should only need to modify this if you've installed the ImageStreams in a 122 | different namespace/project. 123 | name: IMAGE_STREAM_NAMESPACE 124 | required: true 125 | value: openshift 126 | - description: Image stream tag for the image you'd like to use to build the application 127 | name: IMAGE_STREAM_TAG_NAME 128 | required: true 129 | value: nginx:1.16-el8 130 | -------------------------------------------------------------------------------- /basic-nginx/.openshift/deployment/build/params: -------------------------------------------------------------------------------- 1 | MEMORY_LIMIT=512Mi -------------------------------------------------------------------------------- /basic-nginx/.openshift/deployment/dev/params: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=basic-nginx 2 | ENV=-dev -------------------------------------------------------------------------------- /basic-nginx/.openshift/deployment/prod/params: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=basic-nginx 2 | ENV=-prod -------------------------------------------------------------------------------- /basic-nginx/.openshift/deployment/stage/params: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=basic-nginx 2 | ENV=-stage -------------------------------------------------------------------------------- /basic-nginx/.openshift/projects/projects.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: List 3 | items: 4 | - apiVersion: project.openshift.io/v1 5 | kind: ProjectRequest 6 | metadata: 7 | name: basic-nginx-dev 8 | creationTimestam: null 9 | displayName: Basic Nginx App - Dev 10 | - apiVersion: project.openshift.io/v1 11 | kind: ProjectRequest 12 | metadata: 13 | name: basic-nginx-stage 14 | creationTimestam: null 15 | displayName: Basic Nginx App - Stage 16 | - apiVersion: project.openshift.io/v1 17 | kind: ProjectRequest 18 | metadata: 19 | name: basic-nginx-prod 20 | creationTimestam: null 21 | displayName: Basic Tomcat App - Prod 22 | - apiVersion: project.openshift.io/v1 23 | kind: ProjectRequest 24 | metadata: 25 | name: basic-nginx-build 26 | creationTimestam: null 27 | displayName: Basic Nginx App - Build -------------------------------------------------------------------------------- /basic-nginx/Jenkinsfile: -------------------------------------------------------------------------------- 1 | library identifier: "pipeline-library@v1.6", 2 | retriever: modernSCM( 3 | [ 4 | $class: "GitSCMSource", 5 | remote: "https://github.com/redhat-cop/pipeline-library.git" 6 | ] 7 | ) 8 | 9 | 10 | openshift.withCluster() { 11 | env.APP_NAME = "${JOB_NAME}".replaceAll(/-build.*/, '') 12 | env.ARTIFACT_DIRECTORY = "basic-nginx/build" 13 | env.BUILD = openshift.project() 14 | env.DEV = "${APP_NAME}-dev" 15 | env.STAGE = "${APP_NAME}-stage" 16 | env.PROD = "${APP_NAME}-prod" 17 | echo "Starting Pipeline for ${APP_NAME}..." 18 | } 19 | 20 | pipeline { 21 | agent { 22 | label 'maven' 23 | } 24 | 25 | stages { 26 | 27 | stage('Git Checkout') { 28 | steps { 29 | git url: "${SOURCE_REPOSITORY_URL}", branch: "${SOURCE_REPOSITORY_REF}" 30 | } 31 | } 32 | 33 | stage('Build') { 34 | steps { 35 | script { 36 | sh """ 37 | cd basic-nginx 38 | mkdir build 39 | cp index.html build/index.html 40 | cp nginx.conf build/nginx.conf 41 | """ 42 | } 43 | } 44 | } 45 | 46 | stage('Image Build') { 47 | steps { 48 | binaryBuild(projectName: "${BUILD}", buildConfigName: "${APP_NAME}", buildFromPath: "${ARTIFACT_DIRECTORY}") 49 | } 50 | } 51 | 52 | stage('Promote from Build to Dev') { 53 | steps { 54 | tagImage(sourceImageName: env.APP_NAME, sourceImagePath: env.BUILD, toImagePath: env.DEV) 55 | } 56 | } 57 | 58 | stage('Verify Deployment to Dev') { 59 | steps { 60 | verifyDeployment(projectName: env.DEV, targetApp: env.APP_NAME) 61 | } 62 | } 63 | 64 | stage('Promotion gate (Stage)') { 65 | steps { 66 | script { 67 | if(!("${SKIP_MANUAL_PROMOTION}").toBoolean()) { 68 | input message: 'Promote Application to Stage?' 69 | } 70 | } 71 | } 72 | } 73 | 74 | stage('Promote from Dev to Stage') { 75 | steps { 76 | tagImage(sourceImageName: env.APP_NAME, sourceImagePath: env.DEV, toImagePath: env.STAGE) 77 | } 78 | } 79 | 80 | stage('Verify Deployment to Stage') { 81 | steps { 82 | verifyDeployment(projectName: env.STAGE, targetApp: env.APP_NAME) 83 | } 84 | } 85 | 86 | stage('Promotion gate (Prod)') { 87 | steps { 88 | script { 89 | if(!("${SKIP_MANUAL_PROMOTION}").toBoolean()) { 90 | input message: 'Promote Application to Prod?' 91 | } 92 | } 93 | } 94 | } 95 | 96 | stage('Promote from Stage to Prod') { 97 | steps { 98 | tagImage(sourceImageName: env.APP_NAME, sourceImagePath: env.STAGE, toImagePath: env.PROD) 99 | } 100 | } 101 | 102 | stage('Verify Deployment to Prod') { 103 | steps { 104 | verifyDeployment(projectName: env.PROD, targetApp: env.APP_NAME) 105 | } 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /basic-nginx/nginx.conf: -------------------------------------------------------------------------------- 1 | # For more information on configuration, see: 2 | # * Official English Documentation: http://nginx.org/en/docs/ 3 | # * Official Russian Documentation: http://nginx.org/ru/docs/ 4 | 5 | 6 | worker_processes auto; 7 | error_log stderr; 8 | pid /run/nginx.pid; 9 | 10 | # Load dynamic modules. See /usr/share/doc/nginx/README.dynamic. 11 | include /usr/share/nginx/modules/*.conf; 12 | 13 | events { 14 | worker_connections 1024; 15 | } 16 | 17 | http { 18 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 19 | '$status $body_bytes_sent "$http_referer" ' 20 | '"$http_user_agent" "$http_x_forwarded_for"'; 21 | 22 | sendfile on; 23 | tcp_nopush on; 24 | tcp_nodelay on; 25 | keepalive_timeout 65; 26 | types_hash_max_size 2048; 27 | 28 | include /etc/nginx/mime.types; 29 | default_type application/octet-stream; 30 | 31 | # Load modular configuration files from the /etc/nginx/conf.d directory. 32 | # See http://nginx.org/en/docs/ngx_core_module.html#include 33 | # for more information. 34 | include /opt/app-root/etc/nginx.d/*.conf; 35 | 36 | server { 37 | listen 8080 default_server; 38 | listen [::]:8080 default_server; 39 | server_name _; 40 | root /opt/app-root/src; 41 | 42 | # Load configuration files for the default server block. 43 | include /opt/app-root/etc/nginx.default.d/*.conf; 44 | 45 | index index.html; 46 | 47 | location / { 48 | expires 1h; 49 | add_header Cache-Control "public, no-transform"; 50 | try_files $uri $uri/ /index.html; 51 | } 52 | 53 | location ~* \.(html|js|css)$ { 54 | expires -1; 55 | add_header Pragma "no-cache"; 56 | add_header Cache-Control "no-store, no-cache, must-revalidate, post-check=0, pre-check=0"; 57 | } 58 | 59 | location ~* \.(eot|otf|ttf|woff|woff2)$ { 60 | try_files $uri 61 | add_header Access-Control-Allow-Origin *; 62 | } 63 | 64 | error_page 404 /404.html; 65 | location = /40x.html { 66 | } 67 | 68 | error_page 500 502 503 504 /50x.html; 69 | location = /50x.html { 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /basic-nginx/requirements.yml: -------------------------------------------------------------------------------- 1 | # This is the Ansible Galaxy requirements file to pull in the correct roles 2 | # to support the operation of CASL provisioning/runs. 3 | 4 | # From 'openshift-applier' 5 | - name: openshift-applier 6 | scm: git 7 | src: https://github.com/redhat-cop/openshift-applier 8 | version: v2.1.1 -------------------------------------------------------------------------------- /basic-spring-boot-tekton/.applier/group_vars/seed-hosts.yml: -------------------------------------------------------------------------------- 1 | sb_application_name: basic-spring-boot 2 | sb_build_namespace: basic-spring-boot-build 3 | sb_dev_namespace: basic-spring-boot-dev 4 | sb_stage_namespace: basic-spring-boot-stage 5 | sb_prod_namespace: basic-spring-boot-prod 6 | sb_application_repository_url: "https://github.com/redhat-cop/spring-rest.git" 7 | sb_application_repository_ref: master 8 | sb_application_readiness_response: "status.:.UP" 9 | sb_application_readiness_path: "/health" 10 | sb_sa_name: "pipeline" 11 | sb_source_repository_url: "https://github.com/redhat-cop/container-pipelines.git" 12 | sb_source_repository_ref: master 13 | sb_pipeline_script: "Jenkinsfile" 14 | 15 | openshift_cluster_content: 16 | - object: projects 17 | content: 18 | - name: "create environments" 19 | file: "{{ inventory_dir }}/../.openshift/projects/projects.yml" 20 | action: create 21 | tags: 22 | - project 23 | - object: builds 24 | content: 25 | - name: "deploy build pipeline to dev" 26 | template: "{{ inventory_dir }}/../.openshift/templates/build.yml" 27 | params_from_vars: 28 | APPLICATION_NAME: "{{ sb_application_name }}" 29 | SA_NAME: "{{ sb_sa_name }}" 30 | NAMESPACE: "{{ sb_build_namespace }}" 31 | SOURCE_REPOSITORY_URL: "{{ sb_source_repository_url }}" 32 | SOURCE_REPOSITORY_REF: "{{ sb_source_repository_ref }}" 33 | APPLICATION_SOURCE_REPO: "{{ sb_application_repository_url }}" 34 | APPLICATION_SOURCE_REF: "{{ sb_application_repository_ref }}" 35 | PIPELINE_SCRIPT: "{{ sb_pipeline_script }}" 36 | tags: 37 | - build 38 | - object: deployments 39 | content: 40 | - name: "deploy dev environment" 41 | template: "{{ inventory_dir }}/../.openshift/templates/deployment.yml" 42 | params_from_vars: 43 | APPLICATION_NAME: "{{ sb_application_name }}" 44 | NAMESPACE: "{{ sb_dev_namespace }}" 45 | SA_NAME: "{{ sb_sa_name }}" 46 | SA_NAMESPACE: "{{ sb_build_namespace }}" 47 | READINESS_RESPONSE: "{{ sb_application_readiness_response }}" 48 | READINESS_PATH: "{{ sb_application_readiness_path }}" 49 | tags: 50 | - deployment 51 | - name: "deply stage environment" 52 | template: "{{ inventory_dir }}/../.openshift/templates/deployment.yml" 53 | params_from_vars: 54 | APPLICATION_NAME: "{{ sb_application_name }}" 55 | NAMESPACE: "{{ sb_stage_namespace }}" 56 | SA_NAME: "{{ sb_sa_name }}" 57 | SA_NAMESPACE: "{{ sb_build_namespace }}" 58 | READINESS_RESPONSE: "{{ sb_application_readiness_response }}" 59 | READINESS_PATH: "{{ sb_application_readiness_path }}" 60 | tags: 61 | - deployment 62 | - name: "deply prod environment" 63 | template: "{{ inventory_dir }}/../.openshift/templates/deployment.yml" 64 | params_from_vars: 65 | APPLICATION_NAME: "{{ sb_application_name }}" 66 | NAMESPACE: "{{ sb_prod_namespace }}" 67 | SA_NAME: "{{ sb_sa_name }}" 68 | SA_NAMESPACE: "{{ sb_build_namespace }}" 69 | READINESS_RESPONSE: "{{ sb_application_readiness_response }}" 70 | READINESS_PATH: "{{ sb_application_readiness_path }}" 71 | tags: 72 | - deployment 73 | -------------------------------------------------------------------------------- /basic-spring-boot-tekton/.applier/hosts: -------------------------------------------------------------------------------- 1 | [seed-hosts] 2 | localhost ansible_connection=local 3 | -------------------------------------------------------------------------------- /basic-spring-boot-tekton/.gitignore: -------------------------------------------------------------------------------- 1 | galaxy 2 | -------------------------------------------------------------------------------- /basic-spring-boot-tekton/.openshift/projects/projects.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: List 3 | items: 4 | - apiVersion: project.openshift.io/v1 5 | kind: ProjectRequest 6 | metadata: 7 | name: basic-spring-boot-build 8 | creationTimestam: null 9 | displayName: Spring Rest App - Build 10 | - apiVersion: project.openshift.io/v1 11 | kind: ProjectRequest 12 | metadata: 13 | name: basic-spring-boot-dev 14 | creationTimestam: null 15 | displayName: Spring Rest App - Dev 16 | - apiVersion: project.openshift.io/v1 17 | kind: ProjectRequest 18 | metadata: 19 | name: basic-spring-boot-stage 20 | creationTimestam: null 21 | displayName: Spring Rest App - Stage 22 | - apiVersion: project.openshift.io/v1 23 | kind: ProjectRequest 24 | metadata: 25 | name: basic-spring-boot-prod 26 | creationTimestam: null 27 | displayName: Spring Rest App - Prod 28 | -------------------------------------------------------------------------------- /basic-spring-boot-tekton/requirements.yml: -------------------------------------------------------------------------------- 1 | # This is the Ansible Galaxy requirements file to pull in the correct roles 2 | # to support the operation of CASL provisioning/runs. 3 | 4 | # From 'openshift-applier' 5 | - name: openshift-applier 6 | scm: git 7 | src: https://github.com/redhat-cop/openshift-applier 8 | version: v2.1.1 -------------------------------------------------------------------------------- /basic-spring-boot/.applier/group_vars/seed-hosts.yml: -------------------------------------------------------------------------------- 1 | sb_application_name: basic-spring-boot 2 | sb_build_namespace: basic-spring-boot-build 3 | sb_dev_namespace: basic-spring-boot-dev 4 | sb_stage_namespace: basic-spring-boot-stage 5 | sb_prod_namespace: basic-spring-boot-prod 6 | sb_application_repository_url: "https://github.com/redhat-cop/spring-rest.git" 7 | sb_application_repository_ref: master 8 | sb_application_readiness_response: "status.:.UP" 9 | sb_application_readiness_path: "/health" 10 | sb_sa_name: "jenkins" 11 | sb_source_repository_url: "https://github.com/redhat-cop/container-pipelines.git" 12 | sb_source_repository_ref: master 13 | sb_pipeline_script: "Jenkinsfile" 14 | 15 | openshift_cluster_content: 16 | - object: projects 17 | content: 18 | - name: "create environments" 19 | file: "{{ inventory_dir }}/../.openshift/projects/projects.yml" 20 | action: create 21 | tags: 22 | - project 23 | - object: builds 24 | content: 25 | - name: "deploy build pipeline to dev" 26 | template: "{{ inventory_dir }}/../.openshift/templates/build.yml" 27 | params_from_vars: 28 | APPLICATION_NAME: "{{ sb_application_name }}" 29 | NAMESPACE: "{{ sb_build_namespace }}" 30 | NAMESPACE_DEV: "{{ sb_dev_namespace }}" 31 | NAMESPACE_STAGE: "{{ sb_stage_namespace }}" 32 | NAMESPACE_PROD: "{{ sb_prod_namespace }}" 33 | SOURCE_REPOSITORY_URL: "{{ sb_source_repository_url }}" 34 | SOURCE_REPOSITORY_REF: "{{ sb_source_repository_ref }}" 35 | APPLICATION_SOURCE_REPO: "{{ sb_application_repository_url }}" 36 | APPLICATION_SOURCE_REF: "{{ sb_application_repository_ref }}" 37 | PIPELINE_SCRIPT: "{{ sb_pipeline_script }}" 38 | tags: 39 | - build 40 | - object: deployments 41 | content: 42 | - name: "deploy dev environment" 43 | template: "{{ inventory_dir }}/../.openshift/templates/deployment.yml" 44 | params_from_vars: 45 | APPLICATION_NAME: "{{ sb_application_name }}" 46 | NAMESPACE: "{{ sb_dev_namespace }}" 47 | SA_NAMESPACE: "{{ sb_build_namespace }}" 48 | READINESS_RESPONSE: "{{ sb_application_readiness_response }}" 49 | READINESS_PATH: "{{ sb_application_readiness_path }}" 50 | tags: 51 | - deployment 52 | - name: "deploy stage environment" 53 | template: "{{ inventory_dir }}/../.openshift/templates/deployment.yml" 54 | params_from_vars: 55 | APPLICATION_NAME: "{{ sb_application_name }}" 56 | NAMESPACE: "{{ sb_stage_namespace }}" 57 | SA_NAME: "{{ sb_sa_name }}" 58 | SA_NAMESPACE: "{{ sb_build_namespace }}" 59 | READINESS_RESPONSE: "{{ sb_application_readiness_response }}" 60 | READINESS_PATH: "{{ sb_application_readiness_path }}" 61 | tags: 62 | - deployment 63 | - name: "deply prod environment" 64 | template: "{{ inventory_dir }}/../.openshift/templates/deployment.yml" 65 | params_from_vars: 66 | APPLICATION_NAME: "{{ sb_application_name }}" 67 | NAMESPACE: "{{ sb_prod_namespace }}" 68 | SA_NAME: "{{ sb_sa_name }}" 69 | SA_NAMESPACE: "{{ sb_build_namespace }}" 70 | READINESS_RESPONSE: "{{ sb_application_readiness_response }}" 71 | READINESS_PATH: "{{ sb_application_readiness_path }}" 72 | tags: 73 | - deployment 74 | - name: "deploy jenkins to build environment" 75 | template: "openshift//jenkins-ephemeral" 76 | namespace: "{{ sb_build_namespace }}" 77 | tags: 78 | - build 79 | -------------------------------------------------------------------------------- /basic-spring-boot/.applier/hosts: -------------------------------------------------------------------------------- 1 | [seed-hosts] 2 | localhost ansible_connection=local 3 | -------------------------------------------------------------------------------- /basic-spring-boot/.gitignore: -------------------------------------------------------------------------------- 1 | galaxy 2 | -------------------------------------------------------------------------------- /basic-spring-boot/.openshift/projects/projects.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: List 3 | items: 4 | - apiVersion: project.openshift.io/v1 5 | kind: ProjectRequest 6 | metadata: 7 | name: basic-spring-boot-build 8 | creationTimestam: null 9 | displayName: Spring Rest App - Build 10 | - apiVersion: project.openshift.io/v1 11 | kind: ProjectRequest 12 | metadata: 13 | name: basic-spring-boot-dev 14 | creationTimestam: null 15 | displayName: Spring Rest App - Dev 16 | - apiVersion: project.openshift.io/v1 17 | kind: ProjectRequest 18 | metadata: 19 | name: basic-spring-boot-stage 20 | creationTimestam: null 21 | displayName: Spring Rest App - Stage 22 | - apiVersion: project.openshift.io/v1 23 | kind: ProjectRequest 24 | metadata: 25 | name: basic-spring-boot-prod 26 | labels: 27 | environment: production 28 | creationTimestam: null 29 | displayName: Spring Rest App - Prod 30 | -------------------------------------------------------------------------------- /basic-spring-boot/Jenkinsfile: -------------------------------------------------------------------------------- 1 | library identifier: "pipeline-library@v1.6", 2 | retriever: modernSCM( 3 | [ 4 | $class: "GitSCMSource", 5 | remote: "https://github.com/redhat-cop/pipeline-library.git" 6 | ] 7 | ) 8 | 9 | openshift.withCluster() { 10 | env.NAMESPACE = openshift.project() 11 | env.POM_FILE = env.BUILD_CONTEXT_DIR ? "${env.BUILD_CONTEXT_DIR}/pom.xml" : "pom.xml" 12 | echo "Starting Pipeline for ${env.APP_NAME}..." 13 | env.BUILD = "${env.NAMESPACE_BUILD}" 14 | env.DEV = "${env.NAMESPACE_DEV}" 15 | env.STAGE = "${env.NAMESPACE_STAGE}" 16 | env.PROD = "${env.NAMESPACE_PROD}" 17 | } 18 | 19 | pipeline { 20 | // Use Jenkins Maven slave 21 | // Jenkins will dynamically provision this as OpenShift Pod 22 | // All the stages and steps of this Pipeline will be executed on this Pod 23 | // After Pipeline completes the Pod is killed so every run will have clean 24 | // workspace 25 | agent { 26 | label 'maven' 27 | } 28 | 29 | // Pipeline Stages start here 30 | // Requeres at least one stage 31 | stages { 32 | 33 | // Checkout source code 34 | // This is required as Pipeline code is originally checkedout to 35 | // Jenkins Master but this will also pull this same code to this slave 36 | stage('Git Checkout') { 37 | steps { 38 | // Turn off Git's SSL cert check, uncomment if needed 39 | // sh 'git config --global http.sslVerify false' 40 | git url: "${APPLICATION_SOURCE_REPO}", branch: "${APPLICATION_SOURCE_REF}" 41 | } 42 | } 43 | 44 | // Run Maven build, skipping tests 45 | stage('Build'){ 46 | steps { 47 | sh "mvn -B clean install -DskipTests=true -f ${POM_FILE}" 48 | } 49 | } 50 | 51 | // Run Maven unit tests 52 | stage('Unit Test'){ 53 | steps { 54 | sh "mvn -B test -f ${POM_FILE}" 55 | } 56 | } 57 | 58 | // Build Container Image using the artifacts produced in previous stages 59 | stage('Build Container Image'){ 60 | steps { 61 | // Copy the resulting artifacts into common directory 62 | sh """ 63 | ls target/* 64 | rm -rf oc-build && mkdir -p oc-build/deployments 65 | for t in \$(echo "jar;war;ear" | tr ";" "\\n"); do 66 | cp -rfv ./target/*.\$t oc-build/deployments/ 2> /dev/null || echo "No \$t files" 67 | done 68 | """ 69 | 70 | // Build container image using local Openshift cluster 71 | // Giving all the artifacts to OpenShift Binary Build 72 | // This places your artifacts into right location inside your S2I image 73 | // if the S2I image supports it. 74 | binaryBuild(projectName: env.BUILD, buildConfigName: env.APP_NAME, buildFromPath: "oc-build") 75 | } 76 | } 77 | 78 | stage('Promote from Build to Dev') { 79 | steps { 80 | tagImage(sourceImageName: env.APP_NAME, sourceImagePath: env.BUILD, toImagePath: env.DEV) 81 | } 82 | } 83 | 84 | stage ('Verify Deployment to Dev') { 85 | steps { 86 | verifyDeployment(projectName: env.DEV, targetApp: env.APP_NAME) 87 | } 88 | } 89 | 90 | stage('Promote from Dev to Stage') { 91 | steps { 92 | tagImage(sourceImageName: env.APP_NAME, sourceImagePath: env.DEV, toImagePath: env.STAGE) 93 | } 94 | } 95 | 96 | stage ('Verify Deployment to Stage') { 97 | steps { 98 | verifyDeployment(projectName: env.STAGE, targetApp: env.APP_NAME) 99 | } 100 | } 101 | 102 | stage('Promotion gate') { 103 | steps { 104 | script { 105 | input message: 'Promote application to Production?' 106 | } 107 | } 108 | } 109 | 110 | stage('Promote from Stage to Prod') { 111 | steps { 112 | tagImage(sourceImageName: env.APP_NAME, sourceImagePath: env.STAGE, toImagePath: env.PROD) 113 | } 114 | } 115 | 116 | stage ('Verify Deployment to Prod') { 117 | steps { 118 | verifyDeployment(projectName: env.PROD, targetApp: env.APP_NAME) 119 | } 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /basic-spring-boot/requirements.yml: -------------------------------------------------------------------------------- 1 | # This is the Ansible Galaxy requirements file to pull in the correct roles 2 | # to support the operation of CASL provisioning/runs. 3 | 4 | # From 'openshift-applier' 5 | - name: openshift-applier 6 | scm: git 7 | src: https://github.com/redhat-cop/openshift-applier 8 | version: v2.1.1 9 | -------------------------------------------------------------------------------- /basic-tomcat/.applier/group_vars/seed-hosts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | openshift_cluster_content: 3 | - object: projectrequest 4 | content: 5 | - name: basic-tomcat-spaces 6 | file: "{{ inventory_dir }}/../.openshift/projects/projects.yml" 7 | action: create 8 | - object: deployments 9 | content: 10 | - name: jenkins 11 | namespace: basic-tomcat-build 12 | template: openshift//jenkins-ephemeral 13 | params: "{{ inventory_dir }}/../.openshift/deployment/build/params" 14 | - name: basic-tomcat-dev 15 | template: "{{ inventory_dir }}/../.openshift/deployment/template.yml" 16 | params: "{{ inventory_dir }}/../.openshift/deployment/dev/params" 17 | - name: basic-tomcat-stage 18 | template: "{{ inventory_dir }}/../.openshift/deployment/template.yml" 19 | params: "{{ inventory_dir }}/../.openshift/deployment/stage/params" 20 | - name: basic-tomcat-prod 21 | template: "{{ inventory_dir }}/../.openshift/deployment/template.yml" 22 | params: "{{ inventory_dir }}/../.openshift/deployment/prod/params" 23 | - object: builds 24 | content: 25 | - name: jenkins 26 | template: "{{ inventory_dir }}/../.openshift/builds/template.yml" 27 | params: "{{ inventory_dir }}/../.openshift/builds/params" 28 | -------------------------------------------------------------------------------- /basic-tomcat/.applier/hosts: -------------------------------------------------------------------------------- 1 | [seed-hosts] 2 | localhost ansible_connection=local 3 | -------------------------------------------------------------------------------- /basic-tomcat/.openshift/builds/params: -------------------------------------------------------------------------------- 1 | NAMESPACE=basic-tomcat-build 2 | -------------------------------------------------------------------------------- /basic-tomcat/.openshift/builds/template.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: generic-java-jenkins-pipeline 5 | metadata: 6 | annotations: 7 | description: Application template for JWS applications built using a Jenkins Pipeline 8 | iconClass: icon-tomcat 9 | tags: tomcat,tomcat8,java,jboss,xpaas,jenkins-ci 10 | version: 1.2.0 11 | name: generic-java-jenkins-pipeline 12 | objects: 13 | - apiVersion: build.openshift.io/v1 14 | kind: BuildConfig 15 | metadata: 16 | labels: 17 | application: ${APPLICATION_NAME} 18 | name: "${APPLICATION_NAME}-pipeline" 19 | namespace: "${NAMESPACE}" 20 | spec: 21 | source: 22 | type: Git 23 | git: 24 | uri: ${SOURCE_REPOSITORY_URL} 25 | ref: ${SOURCE_REPOSITORY_REF} 26 | contextDir: ${CONTEXT_DIR} 27 | triggers: 28 | - type: "GitHub" 29 | github: 30 | secret: ${GITHUB_WEBHOOK_SECRET} 31 | - type: "ConfigChange" 32 | strategy: 33 | type: "JenkinsPipeline" 34 | jenkinsPipelineStrategy: 35 | jenkinsfilePath: ${PIPELINE_SCRIPT} 36 | env: 37 | - name: "APPLICATION_SOURCE_REPO" 38 | value: "${APPLICATION_SOURCE_REPO}" 39 | - name: "APPLICATION_SOURCE_REF" 40 | value: "${APPLICATION_SOURCE_REF}" 41 | - name: "BUILD_CONTEXT_DIR" 42 | value: "${APPLICATION_CONTEXT_DIR}" 43 | - apiVersion: build.openshift.io/v1 44 | kind: BuildConfig 45 | metadata: 46 | labels: 47 | application: ${APPLICATION_NAME} 48 | name: ${APPLICATION_NAME} 49 | namespace: "${NAMESPACE}" 50 | spec: 51 | failedBuildHistoryLimit: 3 52 | output: 53 | to: 54 | kind: ImageStreamTag 55 | name: ${APPLICATION_NAME}:latest 56 | source: 57 | binary: {} 58 | type: Binary 59 | strategy: 60 | sourceStrategy: 61 | from: 62 | kind: ImageStreamTag 63 | name: ${IMAGE_STREAM_TAG_NAME} 64 | namespace: ${IMAGE_STREAM_NAMESPACE} 65 | type: Source 66 | successfulBuildHistoryLimit: 3 67 | - apiVersion: image.openshift.io/v1 68 | kind: ImageStream 69 | metadata: 70 | labels: 71 | application: ${APPLICATION_NAME} 72 | name: ${APPLICATION_NAME} 73 | namespace: ${NAMESPACE} 74 | parameters: 75 | - description: The name for the application. 76 | name: APPLICATION_NAME 77 | required: true 78 | value: basic-tomcat 79 | - description: The namespace to deploy into 80 | name: NAMESPACE 81 | required: true 82 | - description: Git source URI for application 83 | name: SOURCE_REPOSITORY_URL 84 | required: true 85 | value: https://github.com/redhat-cop/container-pipelines.git 86 | - description: Git branch/tag reference 87 | name: SOURCE_REPOSITORY_REF 88 | value: "master" 89 | - description: Path within Git project to build; empty for root project directory. 90 | name: CONTEXT_DIR 91 | value: "basic-tomcat" 92 | - description: Path within Git project pointing to the pipeline run script 93 | name: PIPELINE_SCRIPT 94 | value: Jenkinsfile 95 | - description: Source code repo for demo app 96 | name: APPLICATION_SOURCE_REPO 97 | required: true 98 | value: https://github.com/jboss-developer/ticket-monster.git 99 | - description: Source code branch/tag 100 | name: APPLICATION_SOURCE_REF 101 | required: true 102 | value: 2.7.0.Final-with-tutorials 103 | - description: Directory where POM file will be 104 | name: APPLICATION_CONTEXT_DIR 105 | required: true 106 | value: demo 107 | - description: GitHub trigger secret 108 | from: '[a-zA-Z0-9]{8}' 109 | generate: expression 110 | name: GITHUB_WEBHOOK_SECRET 111 | required: true 112 | - description: Generic build trigger secret 113 | from: '[a-zA-Z0-9]{8}' 114 | generate: expression 115 | name: GENERIC_WEBHOOK_SECRET 116 | required: true 117 | - description: Namespace in which the ImageStreams for Red Hat Middleware images are 118 | installed. These ImageStreams are normally installed in the openshift namespace. 119 | You should only need to modify this if you've installed the ImageStreams in a 120 | different namespace/project. 121 | name: IMAGE_STREAM_NAMESPACE 122 | required: true 123 | value: openshift 124 | - description: Image stream tag for the image you'd like to use to build the application 125 | name: IMAGE_STREAM_TAG_NAME 126 | required: true 127 | value: jboss-webserver31-tomcat8-openshift:1.0 128 | -------------------------------------------------------------------------------- /basic-tomcat/.openshift/deployment/build/params: -------------------------------------------------------------------------------- 1 | MEMORY_LIMIT=512Mi 2 | -------------------------------------------------------------------------------- /basic-tomcat/.openshift/deployment/dev/params: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=basic-tomcat 2 | ENV=-dev 3 | -------------------------------------------------------------------------------- /basic-tomcat/.openshift/deployment/prod/params: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=basic-tomcat 2 | ENV=-prod 3 | -------------------------------------------------------------------------------- /basic-tomcat/.openshift/deployment/stage/params: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=basic-tomcat 2 | ENV=-stage 3 | -------------------------------------------------------------------------------- /basic-tomcat/.openshift/projects/projects.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: List 3 | items: 4 | - apiVersion: project.openshift.io/v1 5 | kind: ProjectRequest 6 | metadata: 7 | name: basic-tomcat-dev 8 | creationTimestam: null 9 | displayName: Basic Tomcat App - Dev 10 | - apiVersion: project.openshift.io/v1 11 | kind: ProjectRequest 12 | metadata: 13 | name: basic-tomcat-stage 14 | creationTimestam: null 15 | displayName: Basic Tomcat App - Stage 16 | - apiVersion: project.openshift.io/v1 17 | kind: ProjectRequest 18 | metadata: 19 | name: basic-tomcat-prod 20 | creationTimestam: null 21 | displayName: Basic Tomcat App - Prod 22 | - apiVersion: project.openshift.io/v1 23 | kind: ProjectRequest 24 | metadata: 25 | name: basic-tomcat-build 26 | creationTimestam: null 27 | displayName: Basic Tomcat App - Build 28 | -------------------------------------------------------------------------------- /basic-tomcat/Jenkinsfile: -------------------------------------------------------------------------------- 1 | library identifier: "pipeline-library@v1.6", 2 | retriever: modernSCM( 3 | [ 4 | $class: "GitSCMSource", 5 | remote: "https://github.com/redhat-cop/pipeline-library.git" 6 | ] 7 | ) 8 | 9 | openshift.withCluster() { 10 | env.POM_FILE = env.BUILD_CONTEXT_DIR ? "${env.BUILD_CONTEXT_DIR}/pom.xml" : "pom.xml" 11 | env.TARGET = env.BUILD_CONTEXT_DIR ? "${env.BUILD_CONTEXT_DIR}/target" : "target" 12 | env.APP_NAME = "${JOB_NAME}".replaceAll(/-build.*/, '') 13 | env.BUILD = openshift.project() 14 | env.DEV = "${APP_NAME}-dev" 15 | env.STAGE = "${APP_NAME}-stage" 16 | env.PROD = "${APP_NAME}-prod" 17 | echo "Starting Pipeline for ${APP_NAME}..." 18 | } 19 | 20 | pipeline { 21 | agent { 22 | label 'maven' 23 | } 24 | 25 | stages { 26 | stage('Git Checkout') { 27 | steps { 28 | git url: "${APPLICATION_SOURCE_REPO}", branch: "${APPLICATION_SOURCE_REF}" 29 | } 30 | } 31 | 32 | stage('Build') { 33 | steps { 34 | sh "mvn -B clean install -DskipTests=true -f ${POM_FILE}" 35 | } 36 | } 37 | 38 | stage('Unit Test') { 39 | steps { 40 | sh "mvn -B test -f ${POM_FILE}" 41 | } 42 | } 43 | 44 | stage('Build Container Image') { 45 | steps { 46 | sh """ 47 | ls ${TARGET}/* 48 | rm -rf oc-build && mkdir -p oc-build/deployments 49 | for t in \$(echo "jar;war;ear" | tr ";" "\\n"); do 50 | cp -rfv ./${TARGET}/*.\$t oc-build/deployments/ 2> /dev/null || echo "No \$t files" 51 | done 52 | """ 53 | binaryBuild(projectName: env.BUILD, buildConfigName: env.APP_NAME, buildFromPath: "oc-build") 54 | } 55 | } 56 | 57 | stage('Promote from Build to Dev') { 58 | steps { 59 | tagImage(sourceImageName: env.APP_NAME, sourceImagePath: env.BUILD, toImagePath: env.DEV) 60 | } 61 | } 62 | 63 | stage('Verify Deployment to Dev') { 64 | steps { 65 | verifyDeployment(projectName: env.DEV, targetApp: env.APP_NAME) 66 | } 67 | } 68 | 69 | stage('Promotion gate (Stage)') { 70 | steps { 71 | script { 72 | input message: 'Promote Application to Stage?' 73 | } 74 | } 75 | } 76 | 77 | stage('Promote from Dev to Stage') { 78 | steps { 79 | tagImage(sourceImageName: env.APP_NAME, sourceImagePath: env.DEV, toImagePath: env.STAGE) 80 | } 81 | } 82 | 83 | stage('Verify Deployment to Stage') { 84 | steps { 85 | verifyDeployment(projectName: env.STAGE, targetApp: env.APP_NAME) 86 | } 87 | } 88 | 89 | stage('Promotion gate (Prod)') { 90 | steps { 91 | script { 92 | input message: 'Promote Application to Prod?' 93 | } 94 | } 95 | } 96 | 97 | stage('Promote from Stage to Prod') { 98 | steps { 99 | tagImage(sourceImageName: env.APP_NAME, sourceImagePath: env.STAGE, toImagePath: env.PROD) 100 | } 101 | } 102 | 103 | stage('Verify Deployment to Prod') { 104 | steps { 105 | verifyDeployment(projectName: env.PROD, targetApp: env.APP_NAME) 106 | } 107 | } 108 | } 109 | } 110 | 111 | println "Application ${env.APP_NAME} is now in Production!" 112 | -------------------------------------------------------------------------------- /basic-tomcat/requirements.yml: -------------------------------------------------------------------------------- 1 | # This is the Ansible Galaxy requirements file to pull in the correct roles 2 | # to support the operation of CASL provisioning/runs. 3 | 4 | # From 'openshift-applier' 5 | - name: openshift-applier 6 | scm: git 7 | src: https://github.com/redhat-cop/openshift-applier 8 | version: v2.1.1 9 | -------------------------------------------------------------------------------- /blue-green-spring/.applier/group_vars/seed-hosts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | openshift_cluster_content: 3 | - object: projectrequest 4 | content: 5 | - name: simple-spring-boot-spaces 6 | file: "{{ inventory_dir }}/../.openshift/projects/projects.yml" 7 | action: create 8 | - object: deployments 9 | content: 10 | - name: jenkins 11 | namespace: spring-boot-web-build 12 | template: openshift//jenkins-ephemeral 13 | params: "{{ inventory_dir }}/../.openshift/deployment/build/params" 14 | - name: basic-tomcat-dev 15 | template: "{{ inventory_dir }}/../.openshift/deployment/template.yml" 16 | params: "{{ inventory_dir }}/../.openshift/deployment/dev/params" 17 | - name: basic-tomcat-stage 18 | template: "{{ inventory_dir }}/../.openshift/deployment/template.yml" 19 | params: "{{ inventory_dir }}/../.openshift/deployment/stage/params" 20 | - name: basic-tomcat-prod 21 | template: "{{ inventory_dir }}/../.openshift/deployment/template-bg.yml" 22 | params: "{{ inventory_dir }}/../.openshift/deployment/prod/params" 23 | - object: builds 24 | content: 25 | - name: jenkins 26 | template: "{{ inventory_dir }}/../.openshift/builds/template.yml" 27 | params: "{{ inventory_dir }}/../.openshift/builds/params" 28 | -------------------------------------------------------------------------------- /blue-green-spring/.applier/hosts: -------------------------------------------------------------------------------- 1 | [seed-hosts] 2 | localhost ansible_connection=local 3 | -------------------------------------------------------------------------------- /blue-green-spring/.openshift/builds/params: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=spring-boot-web 2 | NAMESPACE=spring-boot-web-build 3 | IMAGE_STREAM_TAG_NAME=redhat-openjdk18-openshift:1.1 4 | -------------------------------------------------------------------------------- /blue-green-spring/.openshift/builds/template.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: generic-java-jenkins-pipeline 5 | metadata: 6 | annotations: 7 | description: Application template for JWS applications built using a Jenkins Pipeline 8 | iconClass: icon-tomcat 9 | tags: tomcat,tomcat8,java,jboss,xpaas,jenkins-ci 10 | version: 1.2.0 11 | name: generic-java-jenkins-pipeline 12 | objects: 13 | - apiVersion: build.openshift.io/v1 14 | kind: BuildConfig 15 | metadata: 16 | labels: 17 | application: ${APPLICATION_NAME} 18 | name: "${APPLICATION_NAME}-pipeline" 19 | namespace: "${NAMESPACE}" 20 | spec: 21 | source: 22 | type: Git 23 | git: 24 | uri: ${SOURCE_REPOSITORY_URL} 25 | ref: ${SOURCE_REPOSITORY_REF} 26 | contextDir: ${CONTEXT_DIR} 27 | triggers: 28 | - type: "GitHub" 29 | github: 30 | secret: ${GITHUB_WEBHOOK_SECRET} 31 | - type: "ConfigChange" 32 | strategy: 33 | type: "JenkinsPipeline" 34 | jenkinsPipelineStrategy: 35 | jenkinsfilePath: ${PIPELINE_SCRIPT} 36 | env: 37 | - name: "APPLICATION_SOURCE_REPO" 38 | value: "${APPLICATION_SOURCE_REPO}" 39 | - name: "APPLICATION_SOURCE_REF" 40 | value: "${APPLICATION_SOURCE_REF}" 41 | - apiVersion: build.openshift.io/v1 42 | kind: BuildConfig 43 | metadata: 44 | labels: 45 | application: ${APPLICATION_NAME} 46 | name: ${APPLICATION_NAME} 47 | namespace: "${NAMESPACE}" 48 | spec: 49 | output: 50 | to: 51 | kind: ImageStreamTag 52 | name: ${APPLICATION_NAME}:latest 53 | source: 54 | binary: {} 55 | type: Binary 56 | strategy: 57 | sourceStrategy: 58 | from: 59 | kind: ImageStreamTag 60 | name: ${IMAGE_STREAM_TAG_NAME} 61 | namespace: ${IMAGE_STREAM_NAMESPACE} 62 | type: Source 63 | - apiVersion: image.openshift.io/v1 64 | kind: ImageStream 65 | metadata: 66 | labels: 67 | application: ${APPLICATION_NAME} 68 | name: ${APPLICATION_NAME} 69 | namespace: ${NAMESPACE} 70 | parameters: 71 | - description: The name for the application. 72 | name: APPLICATION_NAME 73 | required: true 74 | value: simple-spring-boot 75 | - description: The namespace to deploy into 76 | name: NAMESPACE 77 | required: true 78 | - description: Git source URI for application 79 | name: SOURCE_REPOSITORY_URL 80 | required: true 81 | value: https://github.com/redhat-cop/container-pipelines.git 82 | - description: Git branch/tag reference 83 | name: SOURCE_REPOSITORY_REF 84 | value: "master" 85 | - description: Path within Git project to build; empty for root project directory. 86 | name: CONTEXT_DIR 87 | value: "blue-green-spring" 88 | - description: Path within Git project pointing to the pipeline run script 89 | name: PIPELINE_SCRIPT 90 | value: Jenkinsfile 91 | - description: Source code repo for demo app 92 | name: APPLICATION_SOURCE_REPO 93 | required: true 94 | value: https://github.com/redhat-cop/spring-rest.git 95 | - description: Source code ref for demo app 96 | name: APPLICATION_SOURCE_REF 97 | required: true 98 | value: master 99 | - description: GitHub trigger secret 100 | from: '[a-zA-Z0-9]{8}' 101 | generate: expression 102 | name: GITHUB_WEBHOOK_SECRET 103 | required: true 104 | - description: Generic build trigger secret 105 | from: '[a-zA-Z0-9]{8}' 106 | generate: expression 107 | name: GENERIC_WEBHOOK_SECRET 108 | required: true 109 | - description: Namespace in which the ImageStreams for Red Hat Middleware images are 110 | installed. These ImageStreams are normally installed in the openshift namespace. 111 | You should only need to modify this if you've installed the ImageStreams in a 112 | different namespace/project. 113 | name: IMAGE_STREAM_NAMESPACE 114 | required: true 115 | value: openshift 116 | - description: Image stream tag for the image you'd like to use to build the application 117 | name: IMAGE_STREAM_TAG_NAME 118 | required: true 119 | value: redhat-openjdk18-openshift:1.1 120 | -------------------------------------------------------------------------------- /blue-green-spring/.openshift/deployment/build/params: -------------------------------------------------------------------------------- 1 | MEMORY_LIMIT=512Mi 2 | APPLICATION_SOURCE_REF=1.5.8.Final-redhat-1.1 -------------------------------------------------------------------------------- /blue-green-spring/.openshift/deployment/dev/params: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=spring-boot-web 2 | NAMESPACE=spring-boot-web-dev 3 | -------------------------------------------------------------------------------- /blue-green-spring/.openshift/deployment/prod/params: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=spring-boot-web 2 | NAMESPACE=spring-boot-web-prod 3 | -------------------------------------------------------------------------------- /blue-green-spring/.openshift/deployment/stage/params: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=spring-boot-web 2 | NAMESPACE=spring-boot-web-stage 3 | -------------------------------------------------------------------------------- /blue-green-spring/.openshift/deployment/template.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: openjdk-deployment 5 | metadata: 6 | annotations: 7 | description: Application template for spring boot built using a Jenkins Pipeline 8 | iconClass: icon-java 9 | tags: openjdk8,java,xpaas 10 | version: 1.2.0 11 | name: openjdk8-deployment 12 | objects: 13 | - apiVersion: v1 14 | kind: Service 15 | metadata: 16 | annotations: 17 | description: The web server's http port. 18 | labels: 19 | app: ${APPLICATION_NAME} 20 | name: ${APPLICATION_NAME} 21 | namespace: ${NAMESPACE} 22 | spec: 23 | ports: 24 | - port: 8080 25 | targetPort: 8080 26 | selector: 27 | deploymentConfig: ${APPLICATION_NAME} 28 | - apiVersion: route.openshift.io/v1 29 | kind: Route 30 | metadata: 31 | annotations: 32 | description: Route for application's http service. 33 | labels: 34 | app: ${APPLICATION_NAME} 35 | name: ${APPLICATION_NAME} 36 | namespace: ${NAMESPACE} 37 | spec: 38 | host: ${HOSTNAME_HTTP} 39 | to: 40 | name: ${APPLICATION_NAME} 41 | - apiVersion: image.openshift.io/v1 42 | kind: ImageStream 43 | metadata: 44 | labels: 45 | app: ${APPLICATION_NAME} 46 | name: ${APPLICATION_NAME} 47 | namespace: ${NAMESPACE} 48 | - apiVersion: apps.openshift.io/v1 49 | kind: DeploymentConfig 50 | metadata: 51 | labels: 52 | app: ${APPLICATION_NAME} 53 | name: ${APPLICATION_NAME} 54 | namespace: ${NAMESPACE} 55 | spec: 56 | replicas: 1 57 | selector: 58 | deploymentConfig: ${APPLICATION_NAME} 59 | strategy: 60 | type: Recreate 61 | template: 62 | metadata: 63 | labels: 64 | app: ${APPLICATION_NAME} 65 | deploymentConfig: ${APPLICATION_NAME} 66 | name: ${APPLICATION_NAME} 67 | spec: 68 | containers: 69 | - image: ${APPLICATION_NAME} 70 | imagePullPolicy: Always 71 | name: ${APPLICATION_NAME} 72 | ports: 73 | - containerPort: 8080 74 | name: http 75 | protocol: TCP 76 | readinessProbe: 77 | exec: 78 | command: 79 | - /bin/bash 80 | - -c 81 | - curl -s 'http://localhost:8080${READINESS_PATH}' 82 | |grep -iq '${READINESS_RESPONSE}' 83 | terminationGracePeriodSeconds: 60 84 | triggers: 85 | - imageChangeParams: 86 | automatic: true 87 | containerNames: 88 | - ${APPLICATION_NAME} 89 | from: 90 | kind: ImageStreamTag 91 | name: ${APPLICATION_NAME}:latest 92 | type: ImageChange 93 | - type: ConfigChange 94 | - apiVersion: rbac.authorization.k8s.io/v1 95 | kind: RoleBinding 96 | metadata: 97 | creationTimestamp: null 98 | labels: 99 | template: simple-spring-boot-template 100 | name: jenkins_edit 101 | namespace: ${NAMESPACE} 102 | groupNames: null 103 | roleRef: 104 | apiGroup: rbac.authorization.k8s.io 105 | kind: ClusterRole 106 | name: edit 107 | subjects: 108 | - kind: ServiceAccount 109 | name: ${SA_NAME} 110 | namespace: ${SA_NAMESPACE} 111 | userNames: 112 | - system:serviceaccount:${SA_NAMESPACE}:${SA_NAME} 113 | parameters: 114 | - description: The name for the application. 115 | name: APPLICATION_NAME 116 | required: true 117 | value: openjdk8-app 118 | - description: The namespace to deploy into 119 | name: NAMESPACE 120 | required: true 121 | - descriptiondd: Name of a service account that can deploy to this project 122 | name: SA_NAME 123 | required: true 124 | value: jenkins 125 | - description: Namespace of service account that can deploy to this project 126 | name: SA_NAMESPACE 127 | required: true 128 | value: spring-boot-web-build 129 | - description: 'Custom hostname for http service route. Leave blank for default hostname, 130 | e.g.: -.' 131 | name: HOSTNAME_HTTP 132 | - description: 'URI to check for app health' 133 | name: READINESS_PATH 134 | required: true 135 | value: '/health' 136 | - description: 'String value expected back from readiness check' 137 | name: READINESS_RESPONSE 138 | required: true 139 | value: 'UP' 140 | -------------------------------------------------------------------------------- /blue-green-spring/.openshift/projects/projects.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: List 3 | items: 4 | - apiVersion: project.openshift.io/v1 5 | kind: ProjectRequest 6 | metadata: 7 | name: spring-boot-web-dev 8 | creationTimestam: null 9 | displayName: Spring Boot Blue Green - Dev 10 | - apiVersion: project.openshift.io/v1 11 | kind: ProjectRequest 12 | metadata: 13 | name: spring-boot-web-stage 14 | creationTimestam: null 15 | displayName: Spring Boot Blue Green - Staging 16 | - apiVersion: project.openshift.io/v1 17 | kind: ProjectRequest 18 | metadata: 19 | name: spring-boot-web-prod 20 | creationTimestam: null 21 | displayName: Spring Boot Blue Green - Prod 22 | - apiVersion: project.openshift.io/v1 23 | kind: ProjectRequest 24 | metadata: 25 | name: spring-boot-web-build 26 | creationTimestam: null 27 | displayName: Spring Boot Blue Green - Build 28 | -------------------------------------------------------------------------------- /blue-green-spring/requirements.yml: -------------------------------------------------------------------------------- 1 | # This is the Ansible Galaxy requirements file to pull in the correct roles 2 | # to support the operation of CASL provisioning/runs. 3 | 4 | # From 'openshift-applier' 5 | - name: openshift-applier 6 | scm: git 7 | src: https://github.com/redhat-cop/openshift-applier 8 | version: v2.1.1 9 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/.gitignore: -------------------------------------------------------------------------------- 1 | /npm-debug.log 2 | /tldr.md 3 | /galaxy/ 4 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | /tmp/ 3 | /cucumber/ 4 | /npm-debug.log 5 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/application.js: -------------------------------------------------------------------------------- 1 | var express = require("express"); 2 | 3 | var app = express(); 4 | app.use('/', express.static(__dirname + '/')); 5 | 6 | app.listen(8080, function(){ 7 | console.log('Running app on port 8080'); 8 | }); 9 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | AngularJS • TodoMVC 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/integration-tests/features/todo.feature: -------------------------------------------------------------------------------- 1 | # Example feature, the description is using feature injection syntax. 2 | Feature: Todo list 3 | As a user of the todo list 4 | I want to be able to add and read todos 5 | So that I can remember what I am supposed to do later 6 | 7 | 8 | @home @smoke 9 | Scenario: Adding a todo 10 | Given I am on the app home page. 11 | When I add a todo called "hello world". 12 | Then I should see it added to the todo list. 13 | 14 | 15 | # NB if you are comparing blocks of text beware of the file encoding 16 | # UTF-8 and Unix line-endings are recommended. 17 | @home @block-string 18 | Scenario: Adding multiple todos in a block string 19 | Given I am on the app home page. 20 | When I add the todos 21 | """ 22 | First todo 23 | Second todo 24 | Third todo 25 | """ 26 | Then I should see them added to the todo list. 27 | 28 | 29 | # Data table. 30 | # Data tables: https://www.relishapp.com/cucumber/cucumber-js/docs/cucumber-tck/data-tables 31 | @home @regression @data-table 32 | Scenario: Adding multiple todos in a data table 33 | Given I am on the app home page. 34 | When I add multiple todos: 35 | | First todo | 36 | | Second todo | 37 | Then there should be that number of todos in the list. 38 | 39 | 40 | 41 | # Scenario outline. 42 | # Scenario outlines: supported https://github.com/cucumber/cucumber-js/commit/c2a9916810a224d77c6b7e94260c39bb867aee5b 43 | @home @outline 44 | Scenario Outline: Edge case todos 45 | Given I am on the app home page. 46 | When I add a todo called "". 47 | Then it should in the list. 48 | 49 | Examples: 50 | | todo text | appear or not | 51 | | howdy | appear | 52 | | | not appear | 53 | 54 | 55 | # Senario with a pending step. 56 | @home @somePendingTest 57 | Scenario: Anther great scenario 58 | Given I am on the app home page. 59 | When Something is done. 60 | Then there should be a measurable result. 61 | 62 | # Senario with a failing step. 63 | @home @someFailingTest 64 | Scenario: Yet anther great scenario 65 | Given I am on the app home page. 66 | When I add a todo called "expected to fail". 67 | Then I should see a todo called "something totally different". -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/integration-tests/page-objects/README.md: -------------------------------------------------------------------------------- 1 | Note: this directory is not in the features directory in order to avoid it being parsed by Cucumber as it looks for step definitions and hooks etc. -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/integration-tests/page-objects/home-page.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A page object for the example app home page. 3 | * 4 | * Note that browser, element and by are globals defined by Potractor. 5 | * @module page-objects/home-page 6 | */ 7 | /* global element, by */ 8 | 'use strict'; 9 | 10 | 11 | var _ = require('underscore'); 12 | var basePageObject = require('./page-base'); 13 | 14 | 15 | /** 16 | * Elements on the page. 17 | * 18 | * Unlike a WebElement the ElementFinder object understands the Angular digest loop. 19 | * http://angular.github.io/protractor/#/api?view=ElementFinder 20 | */ 21 | var newTodoEl = element(by.model('newTodo')); 22 | var firstTodo = element(by.repeater('todo in todos').row(0)); 23 | 24 | // Multiple elements are found with the 'all' method which 25 | // like most (all?) methods on element objects returns a 26 | // promise. 27 | var toDoEls = element.all(by.repeater('todo in todos')); 28 | 29 | 30 | var homePage = { 31 | url: browser.baseUrl, 32 | 33 | 34 | /** 35 | * Create a new todo item. 36 | * @param {string} todoText 37 | * @return {undefined} 38 | */ 39 | createTodo: function createTodo(todoText) { 40 | newTodoEl.sendKeys(todoText); 41 | newTodoEl.sendKeys('\n'); 42 | }, 43 | 44 | 45 | /** 46 | * Get a promise for the text content of the first todo item. 47 | * @return {promise} 48 | */ 49 | getFirstTodoText: function getFirstTodoText() { 50 | return firstTodo.element(by.tagName('label')).getText(); 51 | }, 52 | 53 | 54 | /** 55 | * Get a promise for the text content of all todo items. 56 | * @return {promise} 57 | */ 58 | getAllTodoText: function getAllTodoText() { 59 | 60 | // Map over an array of promises for ElementFinders 61 | // Map https://github.com/angular/protractor/issues/392#issuecomment-33237672 62 | // ElementFinder object https://github.com/angular/protractor/blob/master/docs/locators.md#finding-multiple-elements 63 | return toDoEls.map(function (todo) { 64 | return todo.element(by.tagName('label')).getText(); 65 | }); 66 | }, 67 | 68 | 69 | /** 70 | * Get a promise for the number of todo elements on the page. 71 | * @return {promise} 72 | */ 73 | getNumberOfTodos: function getNumberOfTodos() { 74 | return toDoEls.count(); 75 | } 76 | }; 77 | 78 | 79 | // Mix in default page object properties and methods. 80 | // Properties on the base page object will be copied 81 | // over if they are undefined on the current page object. 82 | _.defaults(homePage, basePageObject); 83 | 84 | 85 | // Export the home page object. 86 | module.exports = homePage; 87 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/integration-tests/page-objects/page-base.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /* global browser */ 3 | 4 | module.exports = { 5 | url: '', 6 | get: get, 7 | getPageTitle: getPageTitle, 8 | clearLocalStorage: clearLocalStorage, 9 | goToHomePage: goToHomePage 10 | }; 11 | 12 | 13 | /** 14 | * Navigate to the home page. 15 | * @return {undefined} 16 | */ 17 | function get() { 18 | /*jshint validthis:true */ 19 | var url = this.url; 20 | if (!url) { 21 | throw new TypeError('A page object must have a URL defined in order to call \'get\''); 22 | } 23 | browser.get(url); 24 | } 25 | 26 | 27 | 28 | /** 29 | * Clear Local Storage 30 | * @return {string} page title. 31 | */ 32 | function clearLocalStorage(done) { 33 | setTimeout(() => { 34 | browser.executeScript('window.localStorage.clear();'); 35 | //browser.get('javascript://localStorage.clear();') 36 | done(); 37 | }, 1000) 38 | 39 | 40 | 41 | } 42 | 43 | 44 | 45 | /** 46 | * Navigate to home. 47 | * @return {string} page title. 48 | */ 49 | function goToHomePage(done) { 50 | browser.get(browser.baseUrl); 51 | setTimeout(() => { 52 | 53 | //browser.get('javascript://localStorage.clear();') 54 | done(); 55 | }, 1000) 56 | } 57 | 58 | /** 59 | * Get the page title. 60 | * @return {string} page title. 61 | */ 62 | function getPageTitle() { 63 | return browser.getTitle(); 64 | 65 | } -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/integration-tests/protractor-conf.js: -------------------------------------------------------------------------------- 1 | exports.config = { 2 | framework: 'custom', 3 | frameworkPath: require.resolve('protractor-cucumber-framework'), 4 | rootElement: 'body', // location of ng-app directive 5 | // capabilities: { 6 | // 'browserName': 'chrome' 7 | // }, 8 | multiCapabilities: [{ 9 | 'browserName': 'firefox' 10 | }, { 11 | 'browserName': 'chrome' 12 | }], 13 | specs: ['features/*.feature'], 14 | coloredLogs: false, 15 | verbose: true, 16 | // See cucumberOpts in https://github.com/angular/protractor/blob/master/docs/referenceConf.js 17 | // A list of tags to run can be specified here e.g. 18 | // tags: '@smoke' 19 | // tags: ['@smoke', '@otherTag, @thirdTag'] 20 | // The Cucumber require path can be set with the 'require' property. 21 | cucumberOpts: { 22 | format: 'json:./cucumber/results.json', 23 | require: 'features/*.js', 24 | 'no-colors': true, 25 | verbose: true 26 | }, 27 | plugins: [{ 28 | package: 'protractor-multiple-cucumber-html-reporter-plugin', 29 | options:{ 30 | // read the options part 31 | automaticallyGenerateReport: true 32 | } 33 | }] 34 | }; 35 | 36 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/js/app.js: -------------------------------------------------------------------------------- 1 | /*global angular */ 2 | 3 | /** 4 | * The main TodoMVC app module 5 | * 6 | * @type {angular.Module} 7 | */ 8 | angular.module('todomvc', ['ngRoute', 'ngResource']) 9 | .config(function ($routeProvider) { 10 | 'use strict'; 11 | 12 | var routeConfig = { 13 | controller: 'TodoCtrl', 14 | templateUrl: 'todomvc-index.html', 15 | resolve: { 16 | store: function (todoStorage) { 17 | // Get the correct module (API or localStorage). 18 | return todoStorage.then(function (module) { 19 | module.get(); // Fetch the todo records in the background. 20 | return module; 21 | }); 22 | } 23 | } 24 | }; 25 | 26 | $routeProvider 27 | .when('/', routeConfig) 28 | .when('/:status', routeConfig) 29 | .otherwise({ 30 | redirectTo: '/' 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/js/controllers/todoCtrl.js: -------------------------------------------------------------------------------- 1 | /*global angular */ 2 | 3 | /** 4 | * The main controller for the app. The controller: 5 | * - retrieves and persists the model via the todoStorage service 6 | * - exposes the model to the template and provides event handlers 7 | */ 8 | angular.module('todomvc') 9 | .controller('TodoCtrl', function TodoCtrl($scope, $routeParams, $filter, store) { 10 | 'use strict'; 11 | 12 | var todos = $scope.todos = store.todos; 13 | 14 | $scope.newTodo = ''; 15 | $scope.editedTodo = null; 16 | 17 | $scope.$watch('todos', function () { 18 | $scope.remainingCount = $filter('filter')(todos, { completed: false }).length; 19 | $scope.completedCount = todos.length - $scope.remainingCount; 20 | $scope.allChecked = !$scope.remainingCount; 21 | }, true); 22 | 23 | // Monitor the current route for changes and adjust the filter accordingly. 24 | $scope.$on('$routeChangeSuccess', function () { 25 | var status = $scope.status = $routeParams.status || ''; 26 | $scope.statusFilter = (status === 'active') ? 27 | { completed: false } : (status === 'completed') ? 28 | { completed: true } : {}; 29 | }); 30 | 31 | $scope.addTodo = function () { 32 | var newTodo = { 33 | title: $scope.newTodo.trim(), 34 | completed: false 35 | }; 36 | 37 | if (!newTodo.title) { 38 | return; 39 | } 40 | 41 | $scope.saving = true; 42 | store.insert(newTodo) 43 | .then(function success() { 44 | $scope.newTodo = ''; 45 | }) 46 | .finally(function () { 47 | $scope.saving = false; 48 | }); 49 | }; 50 | 51 | $scope.editTodo = function (todo) { 52 | $scope.editedTodo = todo; 53 | // Clone the original todo to restore it on demand. 54 | $scope.originalTodo = angular.extend({}, todo); 55 | }; 56 | 57 | $scope.saveEdits = function (todo, event) { 58 | // Blur events are automatically triggered after the form submit event. 59 | // This does some unfortunate logic handling to prevent saving twice. 60 | if (event === 'blur' && $scope.saveEvent === 'submit') { 61 | $scope.saveEvent = null; 62 | return; 63 | } 64 | 65 | $scope.saveEvent = event; 66 | 67 | if ($scope.reverted) { 68 | // Todo edits were reverted-- don't save. 69 | $scope.reverted = null; 70 | return; 71 | } 72 | 73 | todo.title = todo.title.trim(); 74 | 75 | if (todo.title === $scope.originalTodo.title) { 76 | $scope.editedTodo = null; 77 | return; 78 | } 79 | 80 | store[todo.title ? 'put' : 'delete'](todo) 81 | .then(function success() {}, function error() { 82 | todo.title = $scope.originalTodo.title; 83 | }) 84 | .finally(function () { 85 | $scope.editedTodo = null; 86 | }); 87 | }; 88 | 89 | $scope.revertEdits = function (todo) { 90 | todos[todos.indexOf(todo)] = $scope.originalTodo; 91 | $scope.editedTodo = null; 92 | $scope.originalTodo = null; 93 | $scope.reverted = true; 94 | }; 95 | 96 | $scope.removeTodo = function (todo) { 97 | store.delete(todo); 98 | }; 99 | 100 | $scope.saveTodo = function (todo) { 101 | store.put(todo); 102 | }; 103 | 104 | $scope.toggleCompleted = function (todo, completed) { 105 | if (angular.isDefined(completed)) { 106 | todo.completed = completed; 107 | } 108 | store.put(todo, todos.indexOf(todo)) 109 | .then(function success() {}, function error() { 110 | todo.completed = !todo.completed; 111 | }); 112 | }; 113 | 114 | $scope.clearCompletedTodos = function () { 115 | store.clearCompleted(); 116 | }; 117 | 118 | $scope.markAll = function (completed) { 119 | todos.forEach(function (todo) { 120 | if (todo.completed !== completed) { 121 | $scope.toggleCompleted(todo, completed); 122 | } 123 | }); 124 | }; 125 | }); 126 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/js/directives/todoEscape.js: -------------------------------------------------------------------------------- 1 | /*global angular */ 2 | 3 | /** 4 | * Directive that executes an expression when the element it is applied to gets 5 | * an `escape` keydown event. 6 | */ 7 | angular.module('todomvc') 8 | .directive('todoEscape', function () { 9 | 'use strict'; 10 | 11 | var ESCAPE_KEY = 27; 12 | 13 | return function (scope, elem, attrs) { 14 | elem.bind('keydown', function (event) { 15 | if (event.keyCode === ESCAPE_KEY) { 16 | scope.$apply(attrs.todoEscape); 17 | } 18 | }); 19 | 20 | scope.$on('$destroy', function () { 21 | elem.unbind('keydown'); 22 | }); 23 | }; 24 | }); 25 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/js/directives/todoFocus.js: -------------------------------------------------------------------------------- 1 | /*global angular */ 2 | 3 | /** 4 | * Directive that places focus on the element it is applied to when the 5 | * expression it binds to evaluates to true 6 | */ 7 | angular.module('todomvc') 8 | .directive('todoFocus', function todoFocus($timeout) { 9 | 'use strict'; 10 | 11 | return function (scope, elem, attrs) { 12 | scope.$watch(attrs.todoFocus, function (newVal) { 13 | if (newVal) { 14 | $timeout(function () { 15 | elem[0].focus(); 16 | }, 0, false); 17 | } 18 | }); 19 | }; 20 | }); 21 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/js/services/todoStorage.js: -------------------------------------------------------------------------------- 1 | /*global angular */ 2 | 3 | /** 4 | * Services that persists and retrieves todos from localStorage or a backend API 5 | * if available. 6 | * 7 | * They both follow the same API, returning promises for all changes to the 8 | * model. 9 | */ 10 | angular.module('todomvc') 11 | .factory('todoStorage', function ($http, $injector) { 12 | 'use strict'; 13 | 14 | // Detect if an API backend is present. If so, return the API module, else 15 | // hand off the localStorage adapter 16 | return $http.get('/api') 17 | .then(function () { 18 | return $injector.get('api'); 19 | }, function () { 20 | return $injector.get('localStorage'); 21 | }); 22 | }) 23 | 24 | .factory('api', function ($resource) { 25 | 'use strict'; 26 | 27 | var store = { 28 | todos: [], 29 | 30 | api: $resource('/api/todos/:id', null, 31 | { 32 | update: { method:'PUT' } 33 | } 34 | ), 35 | 36 | clearCompleted: function () { 37 | var originalTodos = store.todos.slice(0); 38 | 39 | var incompleteTodos = store.todos.filter(function (todo) { 40 | return !todo.completed; 41 | }); 42 | 43 | angular.copy(incompleteTodos, store.todos); 44 | 45 | return store.api.delete(function () { 46 | }, function error() { 47 | angular.copy(originalTodos, store.todos); 48 | }); 49 | }, 50 | 51 | delete: function (todo) { 52 | var originalTodos = store.todos.slice(0); 53 | 54 | store.todos.splice(store.todos.indexOf(todo), 1); 55 | return store.api.delete({ id: todo.id }, 56 | function () { 57 | }, function error() { 58 | angular.copy(originalTodos, store.todos); 59 | }); 60 | }, 61 | 62 | get: function () { 63 | return store.api.query(function (resp) { 64 | angular.copy(resp, store.todos); 65 | }); 66 | }, 67 | 68 | insert: function (todo) { 69 | var originalTodos = store.todos.slice(0); 70 | 71 | return store.api.save(todo, 72 | function success(resp) { 73 | todo.id = resp.id; 74 | store.todos.push(todo); 75 | }, function error() { 76 | angular.copy(originalTodos, store.todos); 77 | }) 78 | .$promise; 79 | }, 80 | 81 | put: function (todo) { 82 | return store.api.update({ id: todo.id }, todo) 83 | .$promise; 84 | } 85 | }; 86 | 87 | return store; 88 | }) 89 | 90 | .factory('localStorage', function ($q) { 91 | 'use strict'; 92 | 93 | var STORAGE_ID = 'todos-angularjs'; 94 | 95 | var store = { 96 | todos: [], 97 | 98 | _getFromLocalStorage: function () { 99 | return JSON.parse(localStorage.getItem(STORAGE_ID) || '[]'); 100 | }, 101 | 102 | _saveToLocalStorage: function (todos) { 103 | localStorage.setItem(STORAGE_ID, JSON.stringify(todos)); 104 | }, 105 | 106 | clearCompleted: function () { 107 | var deferred = $q.defer(); 108 | 109 | var incompleteTodos = store.todos.filter(function (todo) { 110 | return !todo.completed; 111 | }); 112 | 113 | angular.copy(incompleteTodos, store.todos); 114 | 115 | store._saveToLocalStorage(store.todos); 116 | deferred.resolve(store.todos); 117 | 118 | return deferred.promise; 119 | }, 120 | 121 | delete: function (todo) { 122 | var deferred = $q.defer(); 123 | 124 | store.todos.splice(store.todos.indexOf(todo), 1); 125 | 126 | store._saveToLocalStorage(store.todos); 127 | deferred.resolve(store.todos); 128 | 129 | return deferred.promise; 130 | }, 131 | 132 | get: function () { 133 | var deferred = $q.defer(); 134 | 135 | angular.copy(store._getFromLocalStorage(), store.todos); 136 | deferred.resolve(store.todos); 137 | 138 | return deferred.promise; 139 | }, 140 | 141 | insert: function (todo) { 142 | var deferred = $q.defer(); 143 | 144 | store.todos.push(todo); 145 | 146 | store._saveToLocalStorage(store.todos); 147 | deferred.resolve(store.todos); 148 | 149 | return deferred.promise; 150 | }, 151 | 152 | put: function (todo, index) { 153 | var deferred = $q.defer(); 154 | 155 | store.todos[index] = todo; 156 | 157 | store._saveToLocalStorage(store.todos); 158 | deferred.resolve(store.todos); 159 | 160 | return deferred.promise; 161 | } 162 | }; 163 | 164 | return store; 165 | }); 166 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "test": "karma start test/config/karma.conf.js", 5 | "start": "node application.js", 6 | "integration-test": "node ./node_modules/protractor/bin/protractor ./integration-tests/protractor-conf.js" 7 | }, 8 | "dependencies": { 9 | "angular": "^1.4.3", 10 | "angular-resource": "^1.4.3", 11 | "angular-route": "^ 1.4.3", 12 | "express": "^4.16.3", 13 | "todomvc-app-css": "^2.1.0", 14 | "todomvc-common": "^1.0.0" 15 | }, 16 | "devDependencies": { 17 | "angular-mocks": "^1.4.3", 18 | "jasmine-core": "^2.2.0", 19 | "karma": "^0.13.0", 20 | "karma-chrome-launcher": "^0.2.2", 21 | "karma-firefox-launcher": "^0.1.7", 22 | "karma-jasmine": "^0.3.5", 23 | "chai": "^4.1.2", 24 | "chai-as-promised": "^7.1.1", 25 | "cucumber": "^4.2.0", 26 | "express": "^4.16.3", 27 | "protractor": "^5.3.2", 28 | "protractor-cucumber-framework": "^5.0.0", 29 | "protractor-multiple-cucumber-html-reporter-plugin": "^1.7.0", 30 | "underscore": "^1.9.1" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/readme.md: -------------------------------------------------------------------------------- 1 | # AngularJS TodoMVC Example 2 | 3 | > HTML is great for declaring static documents, but it falters when we try to use it for declaring dynamic views in web-applications. AngularJS lets you extend HTML vocabulary for your application. The resulting environment is extraordinarily expressive, readable, and quick to develop. 4 | 5 | > _[AngularJS - angularjs.org](http://angularjs.org)_ 6 | 7 | 8 | ## Learning AngularJS 9 | The [AngularJS website](http://angularjs.org) is a great resource for getting started. 10 | 11 | Here are some links you may find helpful: 12 | 13 | * [Tutorial](http://docs.angularjs.org/tutorial) 14 | * [API Reference](http://docs.angularjs.org/api) 15 | * [Developer Guide](http://docs.angularjs.org/guide) 16 | * [Applications built with AngularJS](https://www.madewithangular.com/) 17 | * [Blog](http://blog.angularjs.org) 18 | * [FAQ](http://docs.angularjs.org/misc/faq) 19 | * [AngularJS Meetups](http://www.youtube.com/angularjs) 20 | 21 | Articles and guides from the community: 22 | 23 | * [Code School AngularJS course](https://www.codeschool.com/courses/shaping-up-with-angular-js) 24 | * [5 Awesome AngularJS Features](http://net.tutsplus.com/tutorials/javascript-ajax/5-awesome-angularjs-features) 25 | * [me&ngular - an introduction to MVW](http://stephenplusplus.github.io/meangular) 26 | 27 | Get help from other AngularJS users: 28 | 29 | * [Walkthroughs and Tutorials on YouTube](http://www.youtube.com/playlist?list=PL1w1q3fL4pmgqpzb-XhG7Clgi67d_OHXz) 30 | * [Google Groups mailing list](https://groups.google.com/forum/?fromgroups#!forum/angular) 31 | * [angularjs on Stack Overflow](http://stackoverflow.com/questions/tagged/angularjs) 32 | * [AngularJS on Twitter](https://twitter.com/angularjs) 33 | * [AngularjS on Google +](https://plus.google.com/+AngularJS/posts) 34 | 35 | _If you have other helpful links to share, or find any of the links above no longer work, please [let us know](https://github.com/tastejs/todomvc/issues)._ 36 | 37 | ## Testsuite 38 | 39 | The app uses [Karma](http://karma-runner.github.io/0.12/index.html) to run the tests located in the `test/` folder. To run the tests: 40 | 41 | ``` 42 | $ npm install 43 | $ npm test 44 | ``` 45 | 46 | ## Running locally 47 | 48 | To Run the application locally use: 49 | 50 | ``` 51 | $ npm start 52 | ``` 53 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/test/config/karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function (config) { 2 | 'use strict'; 3 | 4 | config.set({ 5 | basePath: '../../', 6 | frameworks: ['jasmine'], 7 | files: [ 8 | 'node_modules/angular/angular.js', 9 | 'node_modules/angular-route/angular-route.js', 10 | 'node_modules/angular-resource/angular-resource.js', 11 | 'node_modules/angular-mocks/angular-mocks.js', 12 | 'js/**/*.js', 13 | 'test/unit/**/*.js' 14 | ], 15 | autoWatch: true, 16 | singleRun: false, 17 | browsers: ['Chrome', 'Firefox'] 18 | }); 19 | }; 20 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/angularjs/test/unit/directivesSpec.js: -------------------------------------------------------------------------------- 1 | /*global describe, it, beforeEach, inject, expect, angular*/ 2 | (function () { 3 | 'use strict'; 4 | 5 | beforeEach(module('todomvc')); 6 | 7 | describe('todoFocus directive', function () { 8 | var scope, compile, browser; 9 | 10 | beforeEach(inject(function ($rootScope, $compile, $browser) { 11 | scope = $rootScope.$new(); 12 | compile = $compile; 13 | browser = $browser; 14 | })); 15 | 16 | it('should focus on truthy expression', function () { 17 | var el = angular.element(''); 18 | scope.focus = false; 19 | 20 | compile(el)(scope); 21 | expect(browser.deferredFns.length).toBe(0); 22 | 23 | scope.$apply(function () { 24 | scope.focus = true; 25 | }); 26 | 27 | expect(browser.deferredFns.length).toBe(1); 28 | }); 29 | }); 30 | }()); 31 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/applier/inventory/group_vars/seed-hosts.yml: -------------------------------------------------------------------------------- 1 | openshift_cluster_content: 2 | - object: projects 3 | content: 4 | - name: "create environments" 5 | template: "{{ inventory_dir }}/../projects/projects.yml" 6 | params: "{{ inventory_dir }}/../params/projects" 7 | - object: deployments 8 | content: 9 | - name: "deploy dev environment" 10 | template: "{{ inventory_dir }}/../templates/deployment.yml" 11 | params: "{{ inventory_dir }}/../params/deployment-dev" 12 | - name: "deploy jenkins slave image" 13 | template: "{{ inventory_dir }}/../templates/jenkins-slave-node-8.yaml" 14 | params: "{{ inventory_dir }}/../params/jenkins" 15 | - name: "deploy jenkins" 16 | template: "{{ inventory_dir }}/../templates/jenkins-ephemeral.yml" 17 | params: "{{ inventory_dir }}/../params/jenkins" 18 | - name: "deply stage environment" 19 | template: "{{ inventory_dir }}/../templates/deployment.yml" 20 | params: "{{ inventory_dir }}/../params/deployment-stage" 21 | - name: "deply zalenium" 22 | template: "{{ inventory_dir }}/../templates/selenium-grid.yaml" 23 | params: "{{ inventory_dir }}/../params/zalenium" 24 | - name: "deply prod environment" 25 | template: "{{ inventory_dir }}/../templates/deployment.yml" 26 | params: "{{ inventory_dir }}/../params/deployment-prod" 27 | - object: builds 28 | content: 29 | - name: "deploy build pipeline to dev" 30 | template: "{{ inventory_dir }}/../templates/build.yml" 31 | params: "{{ inventory_dir }}/../params/build-dev" 32 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/applier/inventory/hosts: -------------------------------------------------------------------------------- 1 | [seed-hosts] 2 | localhost ansible_connection=local 3 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/applier/params/build-dev: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=todomvc 2 | NAMESPACE=todomvc-build 3 | SOURCE_REPOSITORY_URL=https://github.com/raffaelespazzoli/container-pipelines 4 | SOURCE_REPOSITORY_REF=selenium 5 | APPLICATION_SOURCE_REPO=https://github.com/raffaelespazzoli/container-pipelines 6 | APPLICATION_REF=selenium 7 | APPLICATION_CONTEXT_DIR=cucumber-selenium-grid/angularjs 8 | BASE_APP_DOMAIN=apps.raffa1.casl-contrib.osp.rht-labs.com 9 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/applier/params/deployment-dev: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=todomvc 2 | NAMESPACE=todomvc-dev 3 | SA_NAMESPACE=todomvc-build 4 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/applier/params/deployment-prod: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=todomvc 2 | NAMESPACE=todomvc-prod 3 | SA_NAMESPACE=todomvc-build 4 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/applier/params/deployment-stage: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=todomvc 2 | NAMESPACE=todomvc-stage 3 | SA_NAME=jenkins 4 | SA_NAMESPACE=todomvc-build 5 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/applier/params/jenkins: -------------------------------------------------------------------------------- 1 | NAMESPACE=todomvc-build -------------------------------------------------------------------------------- /cucumber-selenium-grid/applier/params/projects: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=todomvc -------------------------------------------------------------------------------- /cucumber-selenium-grid/applier/params/zalenium: -------------------------------------------------------------------------------- 1 | NAMESPACE=todomvc-stage -------------------------------------------------------------------------------- /cucumber-selenium-grid/applier/projects/projects.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: todomvc-projects 5 | metadata: 6 | annotations: 7 | description: Template for creating todomvc projects 8 | name: todomvc-projects 9 | objects: 10 | - apiVersion: project.openshift.io/v1 11 | kind: ProjectRequest 12 | metadata: 13 | name: ${APPLICATION_NAME}-build 14 | creationTimestam: null 15 | displayName: "${APPLICATION_NAME} - Build" 16 | - apiVersion: project.openshift.io/v1 17 | kind: ProjectRequest 18 | metadata: 19 | name: "${APPLICATION_NAME}-dev" 20 | creationTimestam: null 21 | displayName: "${APPLICATION_NAME} - Dev" 22 | - apiVersion: project.openshift.io/v1 23 | kind: ProjectRequest 24 | metadata: 25 | name: "${APPLICATION_NAME}-stage" 26 | creationTimestam: null 27 | displayName: "${APPLICATION_NAME} - Stage" 28 | - apiVersion: project.openshift.io/v1 29 | kind: ProjectRequest 30 | metadata: 31 | name: "${APPLICATION_NAME}-prod" 32 | creationTimestam: null 33 | displayName: "${APPLICATION_NAME} - Prod" 34 | parameters: 35 | - description: The name for the application. 36 | name: APPLICATION_NAME 37 | required: true 38 | value: todomvc 39 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/applier/templates/build.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: generic-java-jenkins-pipeline 5 | metadata: 6 | annotations: 7 | description: Application template for node applications built using a Jenkins Pipeline 8 | iconClass: icon-nodejs 9 | tags: nodejs,xpaas,jenkins-ci 10 | version: 1.2.0 11 | name: seleium-grid-nodejs-jenkins-pipeline 12 | objects: 13 | - apiVersion: image.openshift.io/v1 14 | kind: ImageStream 15 | metadata: 16 | labels: 17 | application: ${APPLICATION_NAME} 18 | name: ${APPLICATION_NAME} 19 | namespace: ${NAMESPACE} 20 | - apiVersion: build.openshift.io/v1 21 | kind: BuildConfig 22 | metadata: 23 | labels: 24 | application: ${APPLICATION_NAME} 25 | name: "${APPLICATION_NAME}-pipeline" 26 | namespace: "${NAMESPACE}" 27 | spec: 28 | source: 29 | type: Git 30 | git: 31 | uri: ${SOURCE_REPOSITORY_URL} 32 | ref: ${SOURCE_REPOSITORY_REF} 33 | contextDir: ${CONTEXT_DIR} 34 | triggers: 35 | - type: "GitHub" 36 | github: 37 | secret: ${GITHUB_WEBHOOK_SECRET} 38 | - type: "ConfigChange" 39 | strategy: 40 | type: "JenkinsPipeline" 41 | jenkinsPipelineStrategy: 42 | jenkinsfilePath: ${PIPELINE_SCRIPT} 43 | env: 44 | - name: "APPLICATION_SOURCE_REPO" 45 | value: "${APPLICATION_SOURCE_REPO}" 46 | - name: "CONTEXT_DIR" 47 | value: "${APPLICATION_CONTEXT_DIR}" 48 | - name: "BASE_APP_DOMAIN" 49 | value: "${BASE_APP_DOMAIN}" 50 | - name: "APPLICATION_REF" 51 | value: "${APPLICATION_REF}" 52 | - apiVersion: build.openshift.io/v1 53 | kind: BuildConfig 54 | metadata: 55 | labels: 56 | application: ${APPLICATION_NAME} 57 | name: ${APPLICATION_NAME} 58 | namespace: "${NAMESPACE}" 59 | spec: 60 | output: 61 | to: 62 | kind: ImageStreamTag 63 | name: ${APPLICATION_NAME}:latest 64 | source: 65 | binary: {} 66 | type: Binary 67 | strategy: 68 | sourceStrategy: 69 | from: 70 | kind: ImageStreamTag 71 | name: ${IMAGE_STREAM_TAG_NAME} 72 | namespace: ${IMAGE_STREAM_NAMESPACE} 73 | type: Source 74 | parameters: 75 | - description: The name for the application. 76 | name: APPLICATION_NAME 77 | required: true 78 | value: todomvc 79 | - description: The namespace to deploy into 80 | name: NAMESPACE 81 | required: true 82 | - description: Git source URI for application 83 | name: SOURCE_REPOSITORY_URL 84 | required: true 85 | value: https://github.com/raffaelespazzoli/container-pipelines 86 | - description: Git branch/tag reference 87 | name: SOURCE_REPOSITORY_REF 88 | value: "master" 89 | - description: Path within Git project to build; empty for root project directory. 90 | name: CONTEXT_DIR 91 | value: cucumber-selenium-grid 92 | - description: Source code repo for demo app 93 | name: APPLICATION_SOURCE_REPO 94 | required: true 95 | value: https://github.com/raffaelespazzoli/container-pipelines 96 | - description: Application context dir 97 | name: APPLICATION_CONTEXT_DIR 98 | required: true 99 | value: '.' 100 | - description: git branch where the app resides 101 | name: APPLICATION_REF 102 | required: false 103 | - description: Path within Git project pointing to the pipeline run script 104 | name: PIPELINE_SCRIPT 105 | value: Jenkinsfile 106 | - description: GitHub trigger secret 107 | from: '[a-zA-Z0-9]{8}' 108 | generate: expression 109 | name: GITHUB_WEBHOOK_SECRET 110 | required: true 111 | - description: Generic build trigger secret 112 | from: '[a-zA-Z0-9]{8}' 113 | generate: expression 114 | name: GENERIC_WEBHOOK_SECRET 115 | required: true 116 | - description: Namespace in which the ImageStreams for Red Hat Middleware images are 117 | installed. These ImageStreams are normally installed in the openshift namespace. 118 | You should only need to modify this if you've installed the ImageStreams in a 119 | different namespace/project. 120 | name: IMAGE_STREAM_NAMESPACE 121 | required: true 122 | value: openshift 123 | - description: Image stream tag for the image you'd like to use to build the application 124 | name: IMAGE_STREAM_TAG_NAME 125 | required: true 126 | value: nodejs:8 127 | - description: the base domain that this app will have when accessed from outside OCP 128 | name: BASE_APP_DOMAIN 129 | required: true 130 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/applier/templates/deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: basic-nodejs 5 | metadata: 6 | annotations: 7 | description: Application template for nodejs built using a Jenkins Pipeline 8 | iconClass: icon-nodejs 9 | tags: javascript,nodejs 10 | version: 1.2.0 11 | name: basic-nodejs 12 | objects: 13 | - apiVersion: v1 14 | kind: Service 15 | metadata: 16 | annotations: 17 | description: The web server's http port. 18 | labels: 19 | app: ${APPLICATION_NAME} 20 | name: ${APPLICATION_NAME} 21 | namespace: ${NAMESPACE} 22 | spec: 23 | ports: 24 | - port: 8080 25 | targetPort: 8080 26 | selector: 27 | deploymentConfig: ${APPLICATION_NAME} 28 | - apiVersion: route.openshift.io/v1 29 | kind: Route 30 | metadata: 31 | annotations: 32 | description: Route for application's http service. 33 | labels: 34 | app: ${APPLICATION_NAME} 35 | name: ${APPLICATION_NAME} 36 | namespace: ${NAMESPACE} 37 | spec: 38 | host: ${HOSTNAME_HTTP} 39 | to: 40 | name: ${APPLICATION_NAME} 41 | - apiVersion: image.openshift.io/v1 42 | kind: ImageStream 43 | metadata: 44 | labels: 45 | app: ${APPLICATION_NAME} 46 | name: ${APPLICATION_NAME} 47 | namespace: ${NAMESPACE} 48 | - apiVersion: apps.openshift.io/v1 49 | kind: DeploymentConfig 50 | metadata: 51 | labels: 52 | app: ${APPLICATION_NAME} 53 | name: ${APPLICATION_NAME} 54 | namespace: ${NAMESPACE} 55 | spec: 56 | replicas: 1 57 | selector: 58 | deploymentConfig: ${APPLICATION_NAME} 59 | strategy: 60 | type: Recreate 61 | template: 62 | metadata: 63 | labels: 64 | app: ${APPLICATION_NAME} 65 | deploymentConfig: ${APPLICATION_NAME} 66 | name: ${APPLICATION_NAME} 67 | spec: 68 | containers: 69 | - image: ${APPLICATION_NAME} 70 | imagePullPolicy: Always 71 | name: ${APPLICATION_NAME} 72 | ports: 73 | - containerPort: 8080 74 | name: http 75 | protocol: TCP 76 | terminationGracePeriodSeconds: 60 77 | triggers: 78 | - imageChangeParams: 79 | automatic: true 80 | containerNames: 81 | - ${APPLICATION_NAME} 82 | from: 83 | kind: ImageStreamTag 84 | name: ${APPLICATION_NAME}:latest 85 | type: ImageChange 86 | - type: ConfigChange 87 | - apiVersion: rbac.authorization.k8s.io/v1 88 | kind: RoleBinding 89 | metadata: 90 | creationTimestamp: null 91 | labels: 92 | template: basic-nodejs 93 | name: jenkins_edit 94 | namespace: ${NAMESPACE} 95 | groupNames: null 96 | roleRef: 97 | apiGroup: rbac.authorization.k8s.io 98 | kind: ClusterRole 99 | name: edit 100 | subjects: 101 | - kind: ServiceAccount 102 | name: ${SA_NAME} 103 | namespace: ${SA_NAMESPACE} 104 | userNames: 105 | - system:serviceaccount:${SA_NAMESPACE}:${SA_NAME} 106 | parameters: 107 | - description: The name for the application. 108 | name: APPLICATION_NAME 109 | required: true 110 | value: nodejs 111 | - description: The namespace to deploy into 112 | name: NAMESPACE 113 | required: true 114 | - description: Name of a service account that can deploy to this project 115 | name: SA_NAME 116 | required: true 117 | value: jenkins 118 | - description: Namespace of service account that can deploy to this project 119 | name: SA_NAMESPACE 120 | required: true 121 | - description: 'Custom hostname for http service route. Leave blank for default hostname, 122 | e.g.: -.' 123 | name: HOSTNAME_HTTP 124 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/applier/templates/jenkins-slave-node-8.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: jenkins-slave-node-8 5 | metadata: 6 | annotations: 7 | description: jenkins-slave-node-8 8 | tags: jenkins, node 9 | name: jenkins-slave-node-8 10 | objects: 11 | - apiVersion: image.openshift.io/v1 12 | kind: ImageStream 13 | metadata: 14 | labels: 15 | build: jenkins-slave-nodejs8 16 | name: jenkins-slave-base-rhel7 17 | namespace: ${NAMESPACE} 18 | spec: 19 | lookupPolicy: 20 | local: false 21 | tags: 22 | - annotations: 23 | openshift.io/imported-from: registry.access.redhat.com/openshift3/jenkins-slave-base-rhel7 24 | from: 25 | kind: DockerImage 26 | name: registry.access.redhat.com/openshift3/jenkins-slave-base-rhel7 27 | generation: 2 28 | importPolicy: {} 29 | name: latest 30 | referencePolicy: 31 | type: Source 32 | status: 33 | dockerImageRepository: "" 34 | - apiVersion: image.openshift.io/v1 35 | kind: ImageStream 36 | metadata: 37 | labels: 38 | build: jenkins-slave-nodejs8 39 | name: jenkins-slave-nodejs8 40 | namespace: ${NAMESPACE} 41 | spec: 42 | lookupPolicy: 43 | local: false 44 | status: 45 | dockerImageRepository: "" 46 | - apiVersion: build.openshift.io/v1 47 | kind: BuildConfig 48 | metadata: 49 | labels: 50 | build: jenkins-slave-nodejs8 51 | name: jenkins-slave-nodejs8 52 | namespace: ${NAMESPACE} 53 | spec: 54 | failedBuildsHistoryLimit: 5 55 | nodeSelector: null 56 | output: 57 | to: 58 | kind: ImageStreamTag 59 | name: jenkins-slave-nodejs8:latest 60 | postCommit: {} 61 | resources: {} 62 | runPolicy: Serial 63 | source: 64 | contextDir: cucumber-selenium-grid/nodejs-slave 65 | git: 66 | ref: selenium 67 | uri: https://github.com/raffaelespazzoli/container-pipelines 68 | type: Git 69 | strategy: 70 | dockerStrategy: 71 | from: 72 | kind: ImageStreamTag 73 | name: jenkins-slave-base-rhel7:latest 74 | type: Docker 75 | successfulBuildsHistoryLimit: 5 76 | triggers: 77 | - github: 78 | secret: amfuEOy_4bMoTyw2oM8Y 79 | type: GitHub 80 | - generic: 81 | secret: kS_2uiAQf47DQqFyj1YC 82 | type: Generic 83 | - type: ConfigChange 84 | - imageChange: {} 85 | type: ImageChange 86 | status: 87 | lastVersion: 0 88 | parameters: 89 | - description: The namespace to deploy into 90 | name: NAMESPACE 91 | required: true 92 | 93 | -------------------------------------------------------------------------------- /cucumber-selenium-grid/media/integrated-tests-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-cop/container-pipelines/a01be2e6532cc543a781d3b679bad8e3d738efa8/cucumber-selenium-grid/media/integrated-tests-architecture.png -------------------------------------------------------------------------------- /cucumber-selenium-grid/nodejs-slave/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM registry.access.redhat.com/openshift3/jenkins-slave-base-rhel7 2 | 3 | MAINTAINER Gabe Montero 4 | 5 | # Labels consumed by Red Hat build service 6 | LABEL com.redhat.component="jenkins-agent-nodejs-8-rhel7-docker" \ 7 | name="openshift3/jenkins-agent-nodejs-8-rhel7" \ 8 | version="3.6" \ 9 | architecture="x86_64" \ 10 | release="4" \ 11 | io.k8s.display-name="Jenkins Agent Nodejs" \ 12 | io.k8s.description="The jenkins agent nodejs image has the nodejs tools on top of the jenkins slave base image." \ 13 | io.openshift.tags="openshift,jenkins,agent,nodejs" 14 | 15 | ENV NODEJS_VERSION=8 \ 16 | NPM_CONFIG_PREFIX=$HOME/.npm-global \ 17 | PATH=$HOME/node_modules/.bin/:$HOME/.npm-global/bin/:$PATH \ 18 | BASH_ENV=/usr/local/bin/scl_enable \ 19 | ENV=/usr/local/bin/scl_enable \ 20 | PROMPT_COMMAND=". /usr/local/bin/scl_enable" 21 | 22 | COPY contrib/bin/scl_enable /usr/local/bin/scl_enable 23 | 24 | # Install NodeJS 25 | RUN yum-config-manager --enable rhel-server-rhscl-7-rpms && \ 26 | yum-config-manager --enable rhel-7-server-optional-rpms && \ 27 | yum-config-manager --enable rhel-server-rhscl-8-rpms && \ 28 | yum-config-manager --enable rhel-8-server-optional-rpms && \ 29 | yum-config-manager --disable epel >/dev/null || : && \ 30 | INSTALL_PKGS="rh-nodejs${NODEJS_VERSION} rh-nodejs${NODEJS_VERSION}-nodejs-nodemon make gcc-c++ bzip2 autoconf" && \ 31 | ln -s /usr/lib/node_modules/nodemon/bin/nodemon.js /usr/bin/nodemon && \ 32 | yum install -y --setopt=tsflags=nodocs $INSTALL_PKGS && \ 33 | rpm -V $INSTALL_PKGS && \ 34 | yum clean all -y 35 | 36 | RUN chown -R 1001:0 $HOME && \ 37 | chmod -R g+rw $HOME 38 | 39 | USER 1001 -------------------------------------------------------------------------------- /cucumber-selenium-grid/nodejs-slave/contrib/bin/configure-agent: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ -n "$NPM_MIRROR_URL" ]; then 4 | npm -g config set registry "$NPM_MIRROR_URL" 5 | fi -------------------------------------------------------------------------------- /cucumber-selenium-grid/nodejs-slave/contrib/bin/scl_enable: -------------------------------------------------------------------------------- 1 | # This will make scl collection binaries work out of box. 2 | unset BASH_ENV PROMPT_COMMAND ENV 3 | source scl_source enable rh-nodejs8 -------------------------------------------------------------------------------- /cucumber-selenium-grid/requirements.yml: -------------------------------------------------------------------------------- 1 | # This is the Ansible Galaxy requirements file to pull in the correct roles 2 | # to support the operation of CASL provisioning/runs. 3 | 4 | # From 'openshift-applier' 5 | - name: openshift-applier 6 | scm: git 7 | src: https://github.com/redhat-cop/openshift-applier 8 | version: v2.1.1 9 | -------------------------------------------------------------------------------- /jenkins-s2i/jenkins-s2i.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: jenkins2-s2i 5 | group: jenkins2-s2i 6 | metadata: 7 | annotations: 8 | description: Creates the Jenins2 image for CD Pipeline builds 9 | iconClass: icon-jenkins 10 | tags: instant-app,jenkins,cicd 11 | name: jenkins2-s2i 12 | parameters: 13 | - description: Custom Jenkins for CD Pipeline SCM location 14 | displayName: CD Jenkins Pipeline SCM URL 15 | name: JENKINS_GIT_URL 16 | required: true 17 | - description: Custom Jenkins for CD Pipeline SCM branch 18 | displayName: CD Jenkins Pipeline SCM branch 19 | name: JENKINS_GIT_BRANCH 20 | required: true 21 | value: 'master' 22 | - description: Context Directory inside of the Git repo 23 | displayName: Context Directory 24 | name: JENKINS_GIT_CONTEXT_DIR 25 | value: '' 26 | objects: 27 | # Jenkins2 28 | - apiVersion: image.openshift.io/v1 29 | kind: ImageStream 30 | metadata: 31 | labels: 32 | app: jenkins2-s2i 33 | template: jenkins2-s2i 34 | name: jenkins2-s2i 35 | - apiVersion: build.openshift.io/v1 36 | kind: BuildConfig 37 | metadata: 38 | labels: 39 | application: jenkins2-s2i 40 | template: jenkins2-s2i 41 | name: jenkins2-s2i 42 | spec: 43 | triggers: 44 | - type: "ConfigChange" 45 | output: 46 | to: 47 | kind: ImageStreamTag 48 | name: jenkins2-s2i:latest 49 | source: 50 | type: Git 51 | git: 52 | uri: "${JENKINS_GIT_URL}" 53 | ref: "${JENKINS_GIT_BRANCH}" 54 | contextDir: ${JENKINS_GIT_CONTEXT_DIR} 55 | strategy: 56 | sourceStrategy: 57 | from: 58 | kind: ImageStreamTag 59 | name: jenkins:latest 60 | namespace: openshift 61 | type: Source 62 | -------------------------------------------------------------------------------- /jenkins-s2i/plugins.txt: -------------------------------------------------------------------------------- 1 | kubernetes:0.9 2 | -------------------------------------------------------------------------------- /multi-cluster-multi-branch-jee/.applier/.gitignore: -------------------------------------------------------------------------------- 1 | roles 2 | *.retry -------------------------------------------------------------------------------- /multi-cluster-multi-branch-jee/.applier/apply.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Run OpenShift applier 3 | hosts: "{{ app_env }}" 4 | tasks: 5 | - include_role: 6 | name: openshift-applier/roles/openshift-applier 7 | -------------------------------------------------------------------------------- /multi-cluster-multi-branch-jee/.applier/inventory/group_vars/all.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Globals 3 | ansible_connection: local 4 | 5 | # NOTE: openshift_templates_raw MUST be accessible to OpenShift without authentication 6 | openshift_templates_raw: 'https://raw.githubusercontent.com/redhat-cop/openshift-templates' 7 | openshift_templates_raw_version_tag: 'v1.4.9' 8 | -------------------------------------------------------------------------------- /multi-cluster-multi-branch-jee/.applier/inventory/host_vars/app-dev.yml: -------------------------------------------------------------------------------- 1 | --- 2 | create_project: 3 | NAMESPACE: '{{ namespace }}' 4 | NAMESPACE_DISPLAY_NAME: '{{ namespace }}' 5 | 6 | jenkins_rolebinding: 7 | JENKINS_NAMESPACE: '{{ ci_cd_namespace }}' 8 | 9 | group_rolebinding: 10 | ROLE: 'admin' 11 | GROUP: "{{ app_owner_group_name }}" 12 | 13 | app_deploy: 14 | NAME: '{{ app_name }}' 15 | APP_TAG: '{{ app_image_tag }}' 16 | NAMESPACE: '{{ app_image_namespace }}' 17 | IMAGE_REPO: '{{ repo_name }}' 18 | IMAGE_PULL_SECRET: '{{ image_pull_secret }}' 19 | 20 | openshift_cluster_content: 21 | - object: deploy-dev 22 | content: 23 | - name: '{{ app_name }}-{{ namespace }}-create' 24 | template: '{{ openshift_templates_raw }}/{{ openshift_templates_raw_version_tag }}/project-requests/create-project.yml' 25 | action: create 26 | params_from_vars: '{{ create_project }}' 27 | namespace: '{{ namespace }}' 28 | tags: 29 | - deploy 30 | - dev 31 | - name: '{{ app_name }}-{{ namespace }}-jenkins-role-binding' 32 | template: '{{ openshift_templates_raw }}/{{ openshift_templates_raw_version_tag }}/role-bindings/jenkins-rolebinding-template.yml' 33 | params_from_vars: '{{ jenkins_rolebinding }}' 34 | namespace: '{{ namespace }}' 35 | tags: 36 | - deploy 37 | - dev 38 | - name: '{{ app_name }}-{{ namespace }}-owner-role-binding' 39 | template: '{{ openshift_templates_raw }}/{{ openshift_templates_raw_version_tag }}/role-bindings/group-rolebinding-template.yml' 40 | params_from_vars: '{{ group_rolebinding }}' 41 | namespace: '{{ namespace }}' 42 | tags: 43 | - deploy 44 | - dev 45 | - name: '{{ app_name }}-{{ namespace }}-deploy' 46 | template: '{{ inventory_dir }}/../.openshift/app-deploy-jboss-eap.yml' 47 | params_from_vars: '{{ app_deploy }}' 48 | namespace: '{{ namespace }}' 49 | tags: 50 | - deploy 51 | - dev 52 | -------------------------------------------------------------------------------- /multi-cluster-multi-branch-jee/.applier/inventory/host_vars/app-prod.yml: -------------------------------------------------------------------------------- 1 | --- 2 | create_project: 3 | NAMESPACE: '{{ namespace }}' 4 | NAMESPACE_DISPLAY_NAME: '{{ namespace }}' 5 | 6 | jenkins_rolebinding: 7 | JENKINS_NAMESPACE: '{{ ci_cd_namespace }}' 8 | 9 | group_rolebinding: 10 | ROLE: 'admin' 11 | GROUP: "{{ app_owner_group_name }}" 12 | 13 | app_deploy: 14 | NAME: '{{ app_name }}' 15 | APP_TAG: '{{ app_image_tag }}' 16 | NAMESPACE: '{{ app_image_namespace }}' 17 | IMAGE_REPO: '{{ repo_name }}' 18 | IMAGE_PULL_SECRET: '{{ image_pull_secret }}' 19 | 20 | openshift_cluster_content: 21 | - object: deploy-prod 22 | content: 23 | - name: '{{ app_name }}-{{ namespace }}-create' 24 | template: '{{ openshift_templates_raw }}/{{ openshift_templates_raw_version_tag }}/project-requests/create-project.yml' 25 | action: create 26 | params_from_vars: '{{ create_project }}' 27 | namespace: '{{ namespace }}' 28 | tags: 29 | - deploy 30 | - prod 31 | - name: '{{ app_name }}-{{ namespace }}-jenkins-role-binding' 32 | template: '{{ openshift_templates_raw }}/{{ openshift_templates_raw_version_tag }}/role-bindings/jenkins-rolebinding-template.yml' 33 | params_from_vars: '{{ jenkins_rolebinding }}' 34 | namespace: '{{ namespace }}' 35 | tags: 36 | - deploy 37 | - prod 38 | - name: '{{ app_name }}-{{ namespace }}-owner-role-binding' 39 | template: '{{ openshift_templates_raw }}/{{ openshift_templates_raw_version_tag }}/role-bindings/group-rolebinding-template.yml' 40 | params_from_vars: '{{ group_rolebinding }}' 41 | namespace: '{{ namespace }}' 42 | tags: 43 | - deploy 44 | - prod 45 | - name: '{{ app_name }}-{{ namespace }}-deploy' 46 | template: '{{ inventory_dir }}/../.openshift/app-deploy-jboss-eap.yml' 47 | params_from_vars: '{{ app_deploy }}' 48 | namespace: '{{ namespace }}' 49 | tags: 50 | - deploy 51 | - prod 52 | -------------------------------------------------------------------------------- /multi-cluster-multi-branch-jee/.applier/inventory/host_vars/app-qa.yml: -------------------------------------------------------------------------------- 1 | --- 2 | create_project: 3 | NAMESPACE: '{{ namespace }}' 4 | NAMESPACE_DISPLAY_NAME: '{{ namespace }}' 5 | 6 | jenkins_rolebinding: 7 | JENKINS_NAMESPACE: '{{ ci_cd_namespace }}' 8 | 9 | group_rolebinding: 10 | ROLE: 'admin' 11 | GROUP: "{{ app_owner_group_name }}" 12 | 13 | app_deploy: 14 | NAME: '{{ app_name }}' 15 | APP_TAG: '{{ app_image_tag }}' 16 | NAMESPACE: '{{ app_image_namespace }}' 17 | IMAGE_REPO: '{{ repo_name }}' 18 | IMAGE_PULL_SECRET: '{{ image_pull_secret }}' 19 | 20 | openshift_cluster_content: 21 | - object: deploy-qa 22 | content: 23 | - name: '{{ app_name }}-{{ namespace }}-create' 24 | template: '{{ openshift_templates_raw }}/{{ openshift_templates_raw_version_tag }}/project-requests/create-project.yml' 25 | action: create 26 | params_from_vars: '{{ create_project }}' 27 | namespace: '{{ namespace }}' 28 | tags: 29 | - deploy 30 | - qa 31 | - name: '{{ app_name }}-{{ namespace }}-jenkins-role-binding' 32 | template: '{{ openshift_templates_raw }}/{{ openshift_templates_raw_version_tag }}/role-bindings/jenkins-rolebinding-template.yml' 33 | params_from_vars: '{{ jenkins_rolebinding }}' 34 | namespace: '{{ namespace }}' 35 | tags: 36 | - deploy 37 | - qa 38 | - name: '{{ app_name }}-{{ namespace }}-owner-role-binding' 39 | template: '{{ openshift_templates_raw }}/{{ openshift_templates_raw_version_tag }}/role-bindings/group-rolebinding-template.yml' 40 | params_from_vars: '{{ group_rolebinding }}' 41 | namespace: '{{ namespace }}' 42 | tags: 43 | - deploy 44 | - qa 45 | - name: '{{ app_name }}-{{ namespace }}-deploy' 46 | template: '{{ inventory_dir }}/../.openshift/app-deploy-jboss-eap.yml' 47 | params_from_vars: '{{ app_deploy }}' 48 | namespace: '{{ namespace }}' 49 | tags: 50 | - deploy 51 | - qa 52 | -------------------------------------------------------------------------------- /multi-cluster-multi-branch-jee/.applier/inventory/host_vars/app-test.yml: -------------------------------------------------------------------------------- 1 | --- 2 | create_project: 3 | NAMESPACE: '{{ namespace }}' 4 | NAMESPACE_DISPLAY_NAME: '{{ namespace }}' 5 | 6 | jenkins_rolebinding: 7 | JENKINS_NAMESPACE: '{{ ci_cd_namespace }}' 8 | 9 | group_rolebinding: 10 | ROLE: 'admin' 11 | GROUP: "{{ app_owner_group_name }}" 12 | 13 | app_deploy: 14 | NAME: '{{ app_name }}' 15 | APP_TAG: '{{ app_image_tag }}' 16 | NAMESPACE: '{{ app_image_namespace }}' 17 | IMAGE_REPO: '{{ repo_name }}' 18 | IMAGE_PULL_SECRET: '{{ image_pull_secret }}' 19 | 20 | openshift_cluster_content: 21 | - object: deploy-test 22 | content: 23 | - name: '{{ app_name }}-{{ namespace }}-create' 24 | template: '{{ openshift_templates_raw }}/{{ openshift_templates_raw_version_tag }}/project-requests/create-project.yml' 25 | action: create 26 | params_from_vars: '{{ create_project }}' 27 | namespace: '{{ namespace }}' 28 | tags: 29 | - deploy 30 | - test 31 | - name: '{{ app_name }}-{{ namespace }}-jenkins-role-binding' 32 | template: '{{ openshift_templates_raw }}/{{ openshift_templates_raw_version_tag }}/role-bindings/jenkins-rolebinding-template.yml' 33 | params_from_vars: '{{ jenkins_rolebinding }}' 34 | namespace: '{{ namespace }}' 35 | tags: 36 | - deploy 37 | - test 38 | - name: '{{ app_name }}-{{ namespace }}-owner-role-binding' 39 | template: '{{ openshift_templates_raw }}/{{ openshift_templates_raw_version_tag }}/role-bindings/group-rolebinding-template.yml' 40 | params_from_vars: '{{ group_rolebinding }}' 41 | namespace: '{{ namespace }}' 42 | tags: 43 | - deploy 44 | - test 45 | - name: '{{ app_name }}-{{ namespace }}-deploy' 46 | template: '{{ inventory_dir }}/../.openshift/app-deploy-jboss-eap.yml' 47 | params_from_vars: '{{ app_deploy }}' 48 | namespace: '{{ namespace }}' 49 | tags: 50 | - deploy 51 | - test 52 | -------------------------------------------------------------------------------- /multi-cluster-multi-branch-jee/.applier/inventory/hosts: -------------------------------------------------------------------------------- 1 | [app-build] 2 | app-build 3 | 4 | [app-deploy] 5 | app-dev 6 | app-test 7 | app-qa 8 | app-prod 9 | -------------------------------------------------------------------------------- /multi-cluster-multi-branch-jee/.applier/requirements.yml: -------------------------------------------------------------------------------- 1 | # This is the Ansible Galaxy requirements file to pull in the correct roles 2 | # to support the operation of CASL provisioning/runs. 3 | 4 | # From 'openshift-applier' 5 | - src: https://github.com/redhat-cop/openshift-applier 6 | scm: git 7 | version: v2.1.1 8 | name: openshift-applier 9 | -------------------------------------------------------------------------------- /multi-cluster-multi-branch-jee/.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | -------------------------------------------------------------------------------- /multi-cluster-multi-branch-jee/.openshift/app-deploy-jboss-eap.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: template.openshift.io/v1 3 | kind: Template 4 | metadata: 5 | name: ${NAME}-deploy-jboss-eap 6 | annotations: 7 | openshift.io/display-name: Sample JBoss EAP JEE template 8 | description: A sample template to deploy your JBoss EAP JEE App with a HTTPS route 9 | iconClass: icon-cube 10 | tags: jee,eap 11 | labels: 12 | template: ${NAME}-deploy-template 13 | objects: 14 | - apiVersion: apps.openshift.io/v1 15 | kind: DeploymentConfig 16 | metadata: 17 | name: "${NAME}" 18 | labels: 19 | app: "${NAME}" 20 | spec: 21 | replicas: 1 22 | revisionHistoryLimit: 10 23 | selector: 24 | name: "${NAME}" 25 | strategy: 26 | activeDeadlineSeconds: 21600 27 | recreateParams: 28 | timeoutSeconds: 600 29 | resources: {} 30 | type: Rolling 31 | template: 32 | metadata: 33 | creationTimestamp: null 34 | labels: 35 | name: "${NAME}" 36 | spec: 37 | containers: 38 | - image: "${IMAGE_REPO}/${NAMESPACE}/${NAME}:${APP_TAG}" 39 | imagePullPolicy: Always 40 | name: "${NAME}" 41 | env: 42 | - name: JAVA_OPTS_APPEND 43 | value: "${JAVA_OPTS_APPEND}" 44 | livenessProbe: 45 | exec: 46 | command: 47 | - /bin/bash 48 | - '-c' 49 | - /opt/eap/bin/livenessProbe.sh 50 | failureThreshold: 3 51 | initialDelaySeconds: 60 52 | periodSeconds: 10 53 | successThreshold: 1 54 | timeoutSeconds: 1 55 | ports: 56 | - containerPort: 8778 57 | name: jolokia 58 | protocol: TCP 59 | - containerPort: 8080 60 | name: http 61 | protocol: TCP 62 | - containerPort: 8888 63 | name: ping 64 | protocol: TCP 65 | readinessProbe: 66 | exec: 67 | command: 68 | - /bin/bash 69 | - '-c' 70 | - /opt/eap/bin/readinessProbe.sh 71 | failureThreshold: 3 72 | periodSeconds: 10 73 | successThreshold: 1 74 | timeoutSeconds: 1 75 | resources: 76 | limits: 77 | memory: 1Gi 78 | requests: 79 | memory: 256Mi 80 | terminationMessagePath: /dev/termination-log 81 | terminationMessagePolicy: File 82 | dnsPolicy: ClusterFirst 83 | restartPolicy: Always 84 | schedulerName: default-scheduler 85 | securityContext: {} 86 | terminationGracePeriodSeconds: 75 87 | test: false 88 | triggers: [] 89 | - apiVersion: v1 90 | kind: Service 91 | metadata: 92 | labels: 93 | name: "${NAME}" 94 | name: "${NAME}" 95 | spec: 96 | ports: 97 | - port: 8080 98 | protocol: TCP 99 | targetPort: 8080 100 | selector: 101 | name: "${NAME}" 102 | sessionAffinity: None 103 | type: ClusterIP 104 | - apiVersion: v1 105 | kind: Service 106 | metadata: 107 | labels: 108 | name: "${NAME}-ping" 109 | name: "${NAME}-ping" 110 | spec: 111 | ports: 112 | - name: ping 113 | port: 8888 114 | protocol: TCP 115 | targetPort: 8888 116 | publishNotReadyAddresses: true 117 | selector: 118 | name: "${NAME}" 119 | sessionAffinity: None 120 | type: ClusterIP 121 | - apiVersion: route.openshift.io/v1 122 | kind: Route 123 | metadata: 124 | labels: 125 | name: "${NAME}" 126 | name: "${NAME}" 127 | spec: 128 | port: 129 | targetPort: 8080 130 | path: / 131 | tls: 132 | insecureEdgeTerminationPolicy: Redirect 133 | termination: edge 134 | to: 135 | kind: Service 136 | name: "${NAME}" 137 | weight: 100 138 | wildcardPolicy: None 139 | parameters: 140 | - name: NAME 141 | displayName: Name 142 | description: The name assigned to all objects and the related imagestream. 143 | required: true 144 | - name: APP_TAG 145 | displayName: App Tag 146 | description: The tag of the image to use eg latest. 147 | value: latest 148 | required: true 149 | - name: NAMESPACE 150 | displayName: Docker image namespace 151 | description: The namespace of the image to use eg js-apps. 152 | required: true 153 | - name: IMAGE_REPO 154 | displayName: Docker image repository 155 | description: The docker repository containing the image to use 156 | required: true 157 | value: docker-registry.default.svc:5000 158 | - name: IMAGE_PULL_SECRET 159 | displayName: Docker image repository pull secret 160 | description: The secret used to pull images from the docker repository 161 | required: true 162 | - name: JAVA_OPTS_APPEND 163 | displayName: Java Options Append 164 | description: Additional Java options to append to the JEE runtime 165 | -------------------------------------------------------------------------------- /multi-cluster-multi-branch-jee/Jenkinsfile.example: -------------------------------------------------------------------------------- 1 | library( 2 | identifier: 'my-orgs-pipeline-library@master', 3 | retriever: modernSCM([ 4 | $class: 'GitSCMSource', 5 | remote: 'TODO', 6 | credentialsId: 'TODO_IF_NOT_PUBLIC_REPO' 7 | ]) 8 | ) 9 | 10 | pipelineJEE8( 11 | 'my-app-foo', // applicationName 12 | 'my-service-hello', // serviceName 13 | 'my-ocp-user-group', // ownerGroupName 14 | 'https://my-image-push-registry.example.xyz', // imagePushRegistry 15 | 'https://my-image-pull-registry.example.xyz', // imagePullRegistry 16 | 'my-jenkins-credential-with-my-ansible-vault-password', // ansibleVaultJenkinsCredentialName 17 | 'image-push-repo-credential', // immagePushSecret - default value 18 | 'image-pull-repo-credential', // immagePullSecret - default value 19 | 'jboss-eap-7/eap72-openjdk11-openshift-rhel8:1.0', // builderImage - default value 20 | 'https://my-maven-mirror.example.xyz', // mavenMirrorUrl - optional 21 | '-Dcom.redhat.xpaas.repo.jbossorg', // mvnAdditionalArgs - optional. default value 22 | 'sonarQubeEnv' // sonarQubeEnv - optional 23 | ) 24 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/inventory-dev/group_vars/seed-hosts.yml: -------------------------------------------------------------------------------- 1 | openshift_cluster_content: 2 | - object: deployments 3 | content: 4 | - name: "deploy jenkins" 5 | template: "openshift//jenkins-ephemeral" 6 | params: "{{ inventory_dir }}/../params/jenkins" 7 | namespace: multicluster-spring-boot-dev 8 | - name: "create prod cluster credential" 9 | template: "{{ inventory_dir }}/../templates/cluster-secret.yml" 10 | params: "{{ inventory_dir }}/../params/prod-cluster-credentials" 11 | namespace: multicluster-spring-boot-dev 12 | - name: "create image mirror nonprod secret" 13 | template: "{{ inventory_dir }}/../templates/image-mirror-secret.yml" 14 | params: "{{ inventory_dir }}/../params/nonprod-credentials" 15 | namespace: multicluster-spring-boot-dev 16 | - name: "create image mirror prod secret" 17 | template: "{{ inventory_dir }}/../templates/image-mirror-secret.yml" 18 | params: "{{ inventory_dir }}/../params/prod-credentials" 19 | namespace: multicluster-spring-boot-dev 20 | - name: "deploy dev environment" 21 | template: "{{ inventory_dir }}/../templates/deployment.yml" 22 | params: "{{ inventory_dir }}/../params/deployment-dev" 23 | - name: "deply stage environment" 24 | template: "{{ inventory_dir }}/../templates/deployment.yml" 25 | params: "{{ inventory_dir }}/../params/deployment-stage" 26 | - object: builds 27 | content: 28 | - name: "deploy build pipeline to dev" 29 | template: "{{ inventory_dir }}/../templates/build.yml" 30 | params: "{{ inventory_dir }}/../params/build-dev" 31 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/inventory-dev/hosts: -------------------------------------------------------------------------------- 1 | [seed-hosts] 2 | localhost ansible_connection=local 3 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/inventory-pre-dev/group_vars/seed-hosts.yml: -------------------------------------------------------------------------------- 1 | openshift_cluster_content: 2 | - object: projects 3 | content: 4 | - name: "create environments" 5 | file: "{{ inventory_dir }}/../projects/projects.yml" 6 | action: create 7 | - object: deployments 8 | content: 9 | - name: "create image mirror service account" 10 | template: "{{ inventory_dir }}/../templates/image-mirror-sa.yml" 11 | params: "{{ inventory_dir }}/../params/registry-sa-nonprod-cluster" 12 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/inventory-pre-dev/hosts: -------------------------------------------------------------------------------- 1 | [seed-hosts] 2 | localhost ansible_connection=local 3 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/inventory-prod/group_vars/seed-hosts.yml: -------------------------------------------------------------------------------- 1 | openshift_cluster_content: 2 | - object: projects 3 | content: 4 | - name: "create environments" 5 | file: "{{ inventory_dir }}/../projects/projects-prod.yml" 6 | action: create 7 | - name: "create prod cluster credential" 8 | template: "{{ inventory_dir }}/../templates/image-mirror-sa.yml" 9 | params: "{{ inventory_dir }}/../params/registry-sa-prod-cluster" 10 | namespace: multicluster-spring-boot-prod 11 | - object: deployments 12 | content: 13 | - name: "deply prod environment" 14 | template: "{{ inventory_dir }}/../templates/deployment.yml" 15 | params: "{{ inventory_dir }}/../params/deployment-prod" 16 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/inventory-prod/hosts: -------------------------------------------------------------------------------- 1 | [seed-hosts] 2 | localhost ansible_connection=local 3 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/params/build-dev: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=spring-rest 2 | NAMESPACE=multicluster-spring-boot-dev 3 | PIPELINE_REPOSITORY_URL=https://github.com/Gl4di4torRr/container-pipelines.git 4 | PIPELINE_REPOSITORY_REF=multi-cluster-image-mirror 5 | PIPELINE_REPOSITORY_CONTEXT_DIR=multi-cluster-spring-boot/image-mirror-example 6 | SRC_API_URL= 7 | DEST_API_URL= 8 | SRC_REGISTRY= 9 | DEST_REGISTRY= -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/params/deployment-dev: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=spring-rest 2 | NAMESPACE=multicluster-spring-boot-dev 3 | SA_NAMESPACE=multicluster-spring-boot-dev 4 | READINESS_RESPONSE=status.:.UP 5 | READINESS_PATH=/health 6 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/params/deployment-prod: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=spring-rest 2 | NAMESPACE=multicluster-spring-boot-prod 3 | SA_NAMESPACE=multicluster-spring-boot-stage 4 | READINESS_RESPONSE=status.:.UP 5 | READINESS_PATH=/health 6 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/params/deployment-stage: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=spring-rest 2 | NAMESPACE=multicluster-spring-boot-stage 3 | SA_NAME=jenkins 4 | SA_NAMESPACE=multicluster-spring-boot-dev 5 | READINESS_RESPONSE=status.:.UP 6 | READINESS_PATH=/health 7 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/params/jenkins: -------------------------------------------------------------------------------- 1 | MEMORY_LIMIT=1.5Gi 2 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/params/nonprod-credentials: -------------------------------------------------------------------------------- 1 | TOKEN= 2 | SECRET_NAME=nonprod-credentials 3 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/params/prod-cluster-credentials: -------------------------------------------------------------------------------- 1 | TOKEN= 2 | API_URL= 3 | REGISTRY_URL= 4 | SECRET_NAME=prod-cluster-credentials 5 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/params/prod-credentials: -------------------------------------------------------------------------------- 1 | TOKEN= 2 | SECRET_NAME=prod-credentials 3 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/params/registry-sa-nonprod-cluster: -------------------------------------------------------------------------------- 1 | NAMESPACE=multicluster-spring-boot-stage 2 | SA_NAME=docker-registry-dev 3 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/params/registry-sa-prod-cluster: -------------------------------------------------------------------------------- 1 | NAMESPACE=multicluster-spring-boot-prod 2 | SA_NAME=docker-registry-prod 3 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/projects/projects-prod.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: List 3 | items: 4 | - apiVersion: project.openshift.io/v1 5 | kind: ProjectRequest 6 | metadata: 7 | name: multicluster-spring-boot-prod 8 | creationTimestam: null 9 | displayName: MultiCluster Pipeline - Prod 10 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/projects/projects.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: List 3 | items: 4 | - apiVersion: project.openshift.io/v1 5 | kind: ProjectRequest 6 | metadata: 7 | name: multicluster-spring-boot-dev 8 | creationTimestam: null 9 | displayName: MultiCluster Pipeline - Dev 10 | - apiVersion: project.openshift.io/v1 11 | kind: ProjectRequest 12 | metadata: 13 | name: multicluster-spring-boot-stage 14 | creationTimestam: null 15 | displayName: MultiCluster Pipeline - Stage 16 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/templates/build.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: generic-java-jenkins-pipeline 5 | metadata: 6 | annotations: 7 | description: Application template for JWS applications built using a Jenkins Pipeline 8 | iconClass: icon-tomcat 9 | tags: tomcat,tomcat8,java,jboss,xpaas,jenkins-ci 10 | version: 1.2.0 11 | name: generic-java-jenkins-pipeline 12 | objects: 13 | - apiVersion: build.openshift.io/v1 14 | kind: BuildConfig 15 | metadata: 16 | labels: 17 | application: ${APPLICATION_NAME} 18 | app: ${APPLICATION_NAME} 19 | build: ${APPLICATION_NAME} 20 | name: "${APPLICATION_NAME}" 21 | namespace: "${NAMESPACE}" 22 | spec: 23 | output: 24 | to: 25 | kind: ImageStreamTag 26 | name: "${APPLICATION_NAME}:latest" 27 | postCommit: {} 28 | resources: {} 29 | runPolicy: Serial 30 | source: 31 | binary: {} 32 | type: Binary 33 | strategy: 34 | sourceStrategy: 35 | from: 36 | kind: ImageStreamTag 37 | name: ${IMAGE_STREAM_TAG_NAME} 38 | namespace: ${IMAGE_STREAM_NAMESPACE} 39 | type: Source 40 | - apiVersion: build.openshift.io/v1 41 | kind: BuildConfig 42 | metadata: 43 | labels: 44 | application: ${APPLICATION_NAME} 45 | name: "${APPLICATION_NAME}-pipeline" 46 | namespace: "${NAMESPACE}" 47 | spec: 48 | source: 49 | type: Git 50 | git: 51 | uri: ${PIPELINE_REPOSITORY_URL} 52 | ref: ${PIPELINE_REPOSITORY_REF} 53 | contextDir: ${PIPELINE_REPOSITORY_CONTEXT_DIR} 54 | triggers: 55 | - type: "GitHub" 56 | github: 57 | secret: ${GITHUB_WEBHOOK_SECRET} 58 | - type: "ConfigChange" 59 | strategy: 60 | type: "JenkinsPipeline" 61 | jenkinsPipelineStrategy: 62 | jenkinsfilePath: ${PIPELINE_SCRIPT} 63 | env: 64 | - name: SOURCE_CODE_URL 65 | value: ${SOURCE_CODE_URL} 66 | - name: SOURCE_CODE_BRANCH 67 | value: ${SOURCE_CODE_BRANCH} 68 | - name: SKIP_TLS 69 | value: "true" 70 | - name: SRC_REGISTRY 71 | value: ${SRC_REGISTRY} 72 | - name: DEST_REGISTRY 73 | value: ${DEST_REGISTRY} 74 | - name: SRC_API_URL 75 | value: ${SRC_API_URL} 76 | - name: DEST_API_URL 77 | value: ${DEST_API_URL} 78 | parameters: 79 | - description: The name for the application. 80 | name: APPLICATION_NAME 81 | required: true 82 | value: basic-spring 83 | - description: The namespace to deploy into 84 | name: NAMESPACE 85 | required: true 86 | - description: Git source URI for application 87 | name: PIPELINE_REPOSITORY_URL 88 | required: true 89 | value: https://github.com/redhat-cop/container-pipelines.git 90 | - description: Git branch/tag reference 91 | name: PIPELINE_REPOSITORY_REF 92 | value: "master" 93 | - description: Path within Git project to build; empty for root project directory. 94 | name: PIPELINE_REPOSITORY_CONTEXT_DIR 95 | value: 96 | - description: Path within Git project pointing to the pipeline run script 97 | name: PIPELINE_SCRIPT 98 | value: Jenkinsfile 99 | - description: Git source URI for application 100 | name: SOURCE_CODE_URL 101 | required: true 102 | value: https://github.com/redhat-cop/spring-rest.git 103 | - description: Git branch/tag reference 104 | name: SOURCE_CODE_REF 105 | value: "master" 106 | - description: GitHub trigger secret 107 | from: '[a-zA-Z0-9]{8}' 108 | generate: expression 109 | name: GITHUB_WEBHOOK_SECRET 110 | required: true 111 | - description: Generic build trigger secret 112 | from: '[a-zA-Z0-9]{8}' 113 | generate: expression 114 | name: GENERIC_WEBHOOK_SECRET 115 | required: true 116 | - description: Namespace in which the ImageStreams for Red Hat Middleware images are 117 | installed. These ImageStreams are normally installed in the openshift namespace. 118 | You should only need to modify this if you've installed the ImageStreams in a 119 | different namespace/project. 120 | name: IMAGE_STREAM_NAMESPACE 121 | required: true 122 | value: openshift 123 | - description: Image stream tag for the image you'd like to use to build the application 124 | name: IMAGE_STREAM_TAG_NAME 125 | required: true 126 | value: redhat-openjdk18-openshift:1.1 127 | - description: The source docker registry used for image mirror 128 | name: SRC_REGISTRY 129 | required: true 130 | - description: The destination docker registry used for image mirror 131 | name: DEST_REGISTRY 132 | required: true 133 | - description: Set source code branch 134 | name: SOURCE_CODE_BRANCH 135 | required: true 136 | value: master 137 | - description: The source docker registry used for the docker registry url 138 | name: SRC_API_URL 139 | required: true 140 | - description: The destination docker registry used for the docker registry url 141 | name: DEST_API_URL 142 | required: true 143 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/templates/cluster-secret.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: cluster-credentials-secret 5 | metadata: 6 | annotations: 7 | description: Cluster Credential Secret 8 | tags: secret 9 | version: 1.0.0 10 | name: cluster-credentials-secret 11 | objects: 12 | - apiVersion: v1 13 | stringData: 14 | api: ${API_URL} 15 | registry: ${REGISTRY_URL} 16 | token: "${TOKEN}" 17 | data: 18 | kind: Secret 19 | metadata: 20 | name: ${SECRET_NAME} 21 | type: Opaque 22 | parameters: 23 | - description: The name for the application. 24 | name: SECRET_NAME 25 | required: true 26 | value: prod-credentials 27 | - description: The API URL 28 | name: API_URL 29 | required: true 30 | - description: The Registry Route URL 31 | name: REGISTRY_URL 32 | required: true 33 | - description: Service Account Token 34 | name: TOKEN 35 | required: true 36 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/templates/deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: basic-spring-boot 5 | metadata: 6 | annotations: 7 | description: Application template for JWS applications built using a Jenkins Pipeline 8 | iconClass: icon-tomcat 9 | tags: java,spring 10 | version: 1.2.0 11 | name: basic-sprint-boot 12 | objects: 13 | - apiVersion: v1 14 | kind: Service 15 | metadata: 16 | annotations: 17 | description: The web server's http port. 18 | labels: 19 | app: ${APPLICATION_NAME} 20 | name: ${APPLICATION_NAME} 21 | namespace: ${NAMESPACE} 22 | spec: 23 | ports: 24 | - port: 8080 25 | targetPort: 8080 26 | selector: 27 | deploymentConfig: ${APPLICATION_NAME} 28 | - apiVersion: route.openshift.io/v1 29 | kind: Route 30 | metadata: 31 | annotations: 32 | description: Route for application's http service. 33 | labels: 34 | app: ${APPLICATION_NAME} 35 | name: ${APPLICATION_NAME} 36 | namespace: ${NAMESPACE} 37 | spec: 38 | host: ${HOSTNAME_HTTP} 39 | to: 40 | name: ${APPLICATION_NAME} 41 | - apiVersion: image.openshift.io/v1 42 | kind: ImageStream 43 | metadata: 44 | labels: 45 | app: ${APPLICATION_NAME} 46 | name: ${APPLICATION_NAME} 47 | namespace: ${NAMESPACE} 48 | - apiVersion: apps.openshift.io/v1 49 | kind: DeploymentConfig 50 | metadata: 51 | labels: 52 | app: ${APPLICATION_NAME} 53 | name: ${APPLICATION_NAME} 54 | namespace: ${NAMESPACE} 55 | spec: 56 | replicas: 1 57 | selector: 58 | deploymentConfig: ${APPLICATION_NAME} 59 | strategy: 60 | type: Recreate 61 | template: 62 | metadata: 63 | labels: 64 | app: ${APPLICATION_NAME} 65 | deploymentConfig: ${APPLICATION_NAME} 66 | name: ${APPLICATION_NAME} 67 | spec: 68 | containers: 69 | - env: 70 | - name: JWS_ADMIN_USERNAME 71 | value: ${JWS_ADMIN_USERNAME} 72 | - name: JWS_ADMIN_PASSWORD 73 | value: ${JWS_ADMIN_PASSWORD} 74 | image: ${APPLICATION_NAME} 75 | imagePullPolicy: Always 76 | name: ${APPLICATION_NAME} 77 | ports: 78 | - containerPort: 8778 79 | name: jolokia 80 | protocol: TCP 81 | - containerPort: 8080 82 | name: http 83 | protocol: TCP 84 | readinessProbe: 85 | exec: 86 | command: 87 | - /bin/bash 88 | - -c 89 | - curl -s 'http://localhost:8080${READINESS_PATH}' 90 | |grep -iq '${READINESS_RESPONSE}' 91 | terminationGracePeriodSeconds: 60 92 | triggers: 93 | - imageChangeParams: 94 | automatic: true 95 | containerNames: 96 | - ${APPLICATION_NAME} 97 | from: 98 | kind: ImageStreamTag 99 | name: ${APPLICATION_NAME}:latest 100 | type: ImageChange 101 | - type: ConfigChange 102 | - apiVersion: rbac.authorization.k8s.io/v1 103 | kind: RoleBinding 104 | metadata: 105 | creationTimestamp: null 106 | labels: 107 | template: basic-tomcat-template 108 | name: jenkins_edit 109 | namespace: ${NAMESPACE} 110 | groupNames: null 111 | roleRef: 112 | apiGroup: rbac.authorization.k8s.io 113 | kind: ClusterRole 114 | name: edit 115 | subjects: 116 | - kind: ServiceAccount 117 | name: ${SA_NAME} 118 | namespace: ${SA_NAMESPACE} 119 | userNames: 120 | - system:serviceaccount:${SA_NAMESPACE}:${SA_NAME} 121 | parameters: 122 | - description: The name for the application. 123 | name: APPLICATION_NAME 124 | required: true 125 | value: jws-app 126 | - description: The namespace to deploy into 127 | name: NAMESPACE 128 | required: true 129 | - description: Name of a service account that can deploy to this project 130 | name: SA_NAME 131 | required: true 132 | value: jenkins 133 | - description: Namespace of service account that can deploy to this project 134 | name: SA_NAMESPACE 135 | required: true 136 | - description: 'Custom hostname for http service route. Leave blank for default hostname, 137 | e.g.: -.' 138 | name: HOSTNAME_HTTP 139 | - description: 'URI to check for app health' 140 | name: READINESS_PATH 141 | required: true 142 | value: '/' 143 | - description: 'String value expected back from readiness check' 144 | name: READINESS_RESPONSE 145 | required: true 146 | value: 'Hello World!' 147 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/templates/image-mirror-sa.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | metadata: 4 | annotations: 5 | description: template for image mirror service account 6 | objects: 7 | - apiVersion: v1 8 | kind: ServiceAccount 9 | metadata: 10 | name: ${SA_NAME} 11 | namespace: ${NAMESPACE} 12 | - apiVersion: rbac.authorization.k8s.io/v1 13 | kind: RoleBinding 14 | metadata: 15 | creationTimestamp: null 16 | name: edit 17 | namespace: ${NAMESPACE} 18 | groupNames: null 19 | roleRef: 20 | apiGroup: rbac.authorization.k8s.io 21 | kind: ClusterRole 22 | name: edit 23 | subjects: 24 | - kind: ServiceAccount 25 | name: ${SA_NAME} 26 | namespace: ${NAMESPACE} 27 | userNames: 28 | - system:serviceaccount:${NAMESPACE}:${SA_NAME} 29 | parameters: 30 | - description: The namespace to deploy into 31 | name: NAMESPACE 32 | required: true 33 | - description: The service account name 34 | name: SA_NAME 35 | required: true 36 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.applier/templates/image-mirror-secret.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: image-mirror-secret 5 | metadata: 6 | annotations: 7 | description: Cluster Credential Secret 8 | tags: secret 9 | version: 1.0.0 10 | name: image-mirror-secret 11 | objects: 12 | - apiVersion: v1 13 | stringData: 14 | username: generic 15 | password: "${TOKEN}" 16 | data: 17 | kind: Secret 18 | metadata: 19 | name: ${SECRET_NAME} 20 | labels: 21 | credential.sync.jenkins.openshift.io: 'true' 22 | type: kubernetes.io/basic-auth 23 | parameters: 24 | - description: The name for the application. 25 | name: SECRET_NAME 26 | required: true 27 | - description: Service Account Token 28 | name: TOKEN 29 | required: true -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/.gitignore: -------------------------------------------------------------------------------- 1 | galaxy/ -------------------------------------------------------------------------------- /multi-cluster-spring-boot/image-mirror-example/Jenkinsfile: -------------------------------------------------------------------------------- 1 | openshift.withCluster() { 2 | env.NAMESPACE = openshift.project() 3 | env.APP_NAME = "${env.JOB_NAME}".replaceAll(/-?pipeline-?/, '').replaceAll(/-?${env.NAMESPACE}-?/, '') 4 | echo "Starting Pipeline for ${APP_NAME}..." 5 | def projectBase = "${env.NAMESPACE}".replaceAll(/-dev/, '') 6 | env.STAGE1 = "${projectBase}-dev" 7 | env.STAGE2 = "${projectBase}-stage" 8 | env.STAGE3 = "${projectBase}-prod" 9 | } 10 | 11 | 12 | pipeline { 13 | 14 | agent { label 'maven' } 15 | 16 | stages { 17 | 18 | stage('Code Build') { 19 | steps { 20 | git url: "${SOURCE_CODE_URL}" 21 | sh "mvn -B clean install -q" 22 | } 23 | } 24 | 25 | stage('Image Build') { 26 | steps { 27 | echo 'Building Image from Jar File' 28 | sh """ 29 | rm -rf oc-build && mkdir -p oc-build/deployments 30 | for t in \$(echo "jar;war;ear" | tr ";" "\\n"); do 31 | cp -rfv ./target/*.\$t oc-build/deployments/ 2> /dev/null || echo "No \$t files" 32 | done 33 | """ 34 | script { 35 | openshift.withCluster() { 36 | openshift.startBuild("${APP_NAME}", "--from-dir=oc-build", "--wait", "--follow") 37 | } 38 | } 39 | } 40 | } 41 | 42 | stage ('Verify Deployment to Dev') { 43 | steps { 44 | script { 45 | openshift.withCluster() { 46 | def dcObj = openshift.selector('dc', env.APP_NAME).object() 47 | def podSelector = openshift.selector('pod', [deployment: "${APP_NAME}-${dcObj.status.latestVersion}"]) 48 | podSelector.untilEach { 49 | echo "pod: ${it.name()}" 50 | return it.object().status.containerStatuses[0].ready 51 | } 52 | } 53 | } 54 | } 55 | } 56 | 57 | stage('Promote to Stage') { 58 | steps { 59 | script { 60 | openshift.withCluster() { 61 | openshift.tag("${env.STAGE1}/${env.APP_NAME}:latest", "${env.STAGE2}/${env.APP_NAME}:latest") 62 | } 63 | } 64 | } 65 | } 66 | 67 | stage ('Verify Deployment to Stage') { 68 | steps { 69 | script { 70 | openshift.withCluster() { 71 | openshift.withProject("${STAGE2}") { 72 | def dcObj = openshift.selector('dc', env.APP_NAME).object() 73 | def podSelector = openshift.selector('pod', [deployment: "${APP_NAME}-${dcObj.status.latestVersion}"]) 74 | podSelector.untilEach { 75 | echo "pod: ${it.name()}" 76 | return it.object().status.containerStatuses[0].ready 77 | } 78 | } 79 | } 80 | } 81 | } 82 | } 83 | 84 | stage('Promote to Prod') { 85 | steps { 86 | withDockerRegistry([credentialsId: "${STAGE1}-nonprod-credentials", url: "${SRC_API_URL}"]) { 87 | 88 | withDockerRegistry([credentialsId: "${STAGE1}-prod-credentials", url: "${DEST_API_URL}"]) { 89 | 90 | sh """ 91 | oc image mirror --insecure=true ${SRC_REGISTRY}/${STAGE2}/${APP_NAME}:latest ${DEST_REGISTRY}/${STAGE3}/${APP_NAME}:latest 92 | """ 93 | 94 | } 95 | } 96 | } 97 | } 98 | 99 | stage ('Verify Deployment to Prod') { 100 | steps { 101 | script { 102 | openshift.withCluster() { 103 | def secretData = openshift.selector('secret/prod-cluster-credentials').object().data 104 | def encodedAPI = secretData.api 105 | def encodedToken = secretData.token 106 | env.API = sh(script:"set +x; echo ${encodedAPI} | base64 --decode", returnStdout: true).replaceAll(/https?/, 'insecure') 107 | env.TOKEN = sh(script:"set +x; echo ${encodedToken} | base64 --decode", returnStdout: true) 108 | } 109 | openshift.withCluster( env.API, env.TOKEN ) { 110 | openshift.withProject("${STAGE3}") { 111 | def dcObj = openshift.selector('dc', env.APP_NAME).object() 112 | def podSelector = openshift.selector('pod', [deployment: "${APP_NAME}-${dcObj.status.latestVersion}"]) 113 | podSelector.untilEach { 114 | echo "pod: ${it.name()}" 115 | return it.object().status.containerStatuses[0].ready 116 | } 117 | } 118 | } 119 | } 120 | } 121 | } 122 | 123 | } 124 | } -------------------------------------------------------------------------------- /multi-cluster-spring-boot/requirements.yml: -------------------------------------------------------------------------------- 1 | # This is the Ansible Galaxy requirements file to pull in the correct roles 2 | # to support the operation of CASL provisioning/runs. 3 | 4 | # From 'openshift-applier' 5 | - name: openshift-applier 6 | scm: git 7 | src: https://github.com/redhat-cop/openshift-applier 8 | version: v2.1.1 9 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/inventory-dev/group_vars/seed-hosts.yml: -------------------------------------------------------------------------------- 1 | openshift_cluster_content: 2 | - object: projects 3 | content: 4 | - name: "create environments" 5 | file: "{{ inventory_dir }}/../projects/projects.yml" 6 | action: create 7 | - object: deployments 8 | content: 9 | - name: "deploy jenkins" 10 | template: "openshift//jenkins-ephemeral" 11 | params: "{{ inventory_dir }}/../params/jenkins" 12 | namespace: multicluster-spring-boot-dev 13 | - name: "create prod cluster credential" 14 | template: "{{ inventory_dir }}/../templates/cluster-secret.yml" 15 | params: "{{ inventory_dir }}/../params/prod-credentials" 16 | namespace: multicluster-spring-boot-dev 17 | - name: "deploy dev environment" 18 | template: "{{ inventory_dir }}/../templates/deployment.yml" 19 | params: "{{ inventory_dir }}/../params/deployment-dev" 20 | - name: "deply stage environment" 21 | template: "{{ inventory_dir }}/../templates/deployment.yml" 22 | params: "{{ inventory_dir }}/../params/deployment-stage" 23 | - object: builds 24 | content: 25 | - name: Apply Image Build" 26 | namespace: "multicluster-spring-boot-dev" 27 | template: "https://raw.githubusercontent.com/redhat-cop/containers-quickstarts/master/jenkins-slaves/templates/jenkins-slave-image-mgmt-template.json" 28 | params: "{{ inventory_dir }}/../params/build-slave-dev" 29 | - name: "deploy build pipeline to dev" 30 | template: "{{ inventory_dir }}/../templates/build.yml" 31 | params: "{{ inventory_dir }}/../params/build-dev" 32 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/inventory-dev/hosts: -------------------------------------------------------------------------------- 1 | [seed-hosts] 2 | localhost ansible_connection=local 3 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/inventory-prod/group_vars/seed-hosts.yml: -------------------------------------------------------------------------------- 1 | openshift_cluster_content: 2 | - object: projects 3 | content: 4 | - name: "create environments" 5 | file: "{{ inventory_dir }}/../projects/projects-prod.yml" 6 | action: create 7 | - name: "create promoter account" 8 | file: "{{ inventory_dir }}/../projects/promoter-sa.yml" 9 | - object: deployments 10 | content: 11 | - name: "deply prod environment" 12 | template: "{{ inventory_dir }}/../templates/deployment.yml" 13 | params: "{{ inventory_dir }}/../params/deployment-prod" 14 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/inventory-prod/hosts: -------------------------------------------------------------------------------- 1 | [seed-hosts] 2 | localhost ansible_connection=local 3 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/params/build-dev: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=spring-rest 2 | NAMESPACE=multicluster-spring-boot-dev 3 | PIPELINE_REPOSITORY_URL=https://github.com/etsauer/container-pipelines.git 4 | PIPELINE_REPOSITORY_REF=multi-cluster-promotion 5 | PIPELINE_REPOSITORY_CONTEXT_DIR=multi-cluster-spring-boot/skopeo-example 6 | SOURCE_CODE_REF=1.5.8.Final-redhat-1.1 -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/params/build-slave-dev: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redhat-cop/container-pipelines/a01be2e6532cc543a781d3b679bad8e3d738efa8/multi-cluster-spring-boot/skopeo-example/.applier/params/build-slave-dev -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/params/deployment-dev: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=spring-rest 2 | NAMESPACE=multicluster-spring-boot-dev 3 | SA_NAMESPACE=multicluster-spring-boot-dev 4 | READINESS_RESPONSE=status.:.UP 5 | READINESS_PATH=/health 6 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/params/deployment-prod: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=spring-rest 2 | NAMESPACE=multicluster-spring-boot-prod 3 | SA_NAMESPACE=multicluster-spring-boot-dev 4 | READINESS_RESPONSE=status.:.UP 5 | READINESS_PATH=/health 6 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/params/deployment-stage: -------------------------------------------------------------------------------- 1 | APPLICATION_NAME=spring-rest 2 | NAMESPACE=multicluster-spring-boot-stage 3 | SA_NAME=jenkins 4 | SA_NAMESPACE=multicluster-spring-boot-dev 5 | READINESS_RESPONSE=status.:.UP 6 | READINESS_PATH=/health 7 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/params/jenkins: -------------------------------------------------------------------------------- 1 | MEMORY_LIMIT=1.5Gi 2 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/projects/projects-prod.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: List 3 | items: 4 | - apiVersion: project.openshift.io/v1 5 | kind: ProjectRequest 6 | metadata: 7 | name: multicluster-spring-boot-prod 8 | creationTimestam: null 9 | displayName: MultiCluster Pipeline - Prod 10 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/projects/projects.yml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: List 3 | items: 4 | - apiVersion: project.openshift.io/v1 5 | kind: ProjectRequest 6 | metadata: 7 | name: multicluster-spring-boot-dev 8 | creationTimestam: null 9 | displayName: MultiCluster Pipeline - Dev 10 | - apiVersion: project.openshift.io/v1 11 | kind: ProjectRequest 12 | metadata: 13 | name: multicluster-spring-boot-stage 14 | creationTimestam: null 15 | displayName: MultiCluster Pipeline - Stage 16 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/projects/promoter-sa.yml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: List 4 | items: 5 | - apiVersion: v1 6 | kind: ServiceAccount 7 | metadata: 8 | name: promoter 9 | namespace: multicluster-spring-boot-prod 10 | - apiVersion: rbac.authorization.k8s.io/v1 11 | kind: RoleBinding 12 | metadata: 13 | creationTimestamp: null 14 | name: edit 15 | namespace: multicluster-spring-boot-prod 16 | groupNames: null 17 | roleRef: 18 | apiGroup: rbac.authorization.k8s.io 19 | kind: ClusterRole 20 | name: edit 21 | subjects: 22 | - kind: ServiceAccount 23 | name: promoter 24 | namespace: multicluster-spring-boot-prod 25 | userNames: 26 | - system:serviceaccount:multicluster-spring-boot-prod:promoter 27 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/templates/build.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: generic-java-jenkins-pipeline 5 | metadata: 6 | annotations: 7 | description: Application template for JWS applications built using a Jenkins Pipeline 8 | iconClass: icon-tomcat 9 | tags: tomcat,tomcat8,java,jboss,xpaas,jenkins-ci 10 | version: 1.2.0 11 | name: generic-java-jenkins-pipeline 12 | objects: 13 | - apiVersion: build.openshift.io/v1 14 | kind: BuildConfig 15 | metadata: 16 | labels: 17 | application: ${APPLICATION_NAME} 18 | name: "${APPLICATION_NAME}-pipeline" 19 | namespace: "${NAMESPACE}" 20 | spec: 21 | source: 22 | type: Git 23 | git: 24 | uri: ${PIPELINE_REPOSITORY_URL} 25 | ref: ${PIPELINE_REPOSITORY_REF} 26 | contextDir: ${PIPELINE_REPOSITORY_CONTEXT_DIR} 27 | triggers: 28 | - type: "GitHub" 29 | github: 30 | secret: ${GITHUB_WEBHOOK_SECRET} 31 | - type: "ConfigChange" 32 | strategy: 33 | type: "JenkinsPipeline" 34 | jenkinsPipelineStrategy: 35 | jenkinsfilePath: ${PIPELINE_SCRIPT} 36 | env: 37 | - name: SOURCE_CODE_URL 38 | value: ${SOURCE_CODE_URL} 39 | - name: SOURCE_CODE_BRANCH 40 | value: ${SOURCE_CODE_BRANCH} 41 | - name: SKIP_TLS 42 | value: "true" 43 | - apiVersion: build.openshift.io/v1 44 | kind: BuildConfig 45 | metadata: 46 | labels: 47 | application: ${APPLICATION_NAME} 48 | name: ${APPLICATION_NAME} 49 | namespace: "${NAMESPACE}" 50 | spec: 51 | output: 52 | to: 53 | kind: ImageStreamTag 54 | name: ${APPLICATION_NAME}:latest 55 | source: 56 | binary: {} 57 | type: Binary 58 | strategy: 59 | sourceStrategy: 60 | from: 61 | kind: ImageStreamTag 62 | name: ${IMAGE_STREAM_TAG_NAME} 63 | namespace: ${IMAGE_STREAM_NAMESPACE} 64 | type: Source 65 | parameters: 66 | - description: The name for the application. 67 | name: APPLICATION_NAME 68 | required: true 69 | value: basic-spring 70 | - description: The namespace to deploy into 71 | name: NAMESPACE 72 | required: true 73 | - description: Git source URI for application 74 | name: PIPELINE_REPOSITORY_URL 75 | required: true 76 | value: https://github.com/redhat-cop/container-pipelines.git 77 | - description: Git branch/tag reference 78 | name: PIPELINE_REPOSITORY_REF 79 | value: "master" 80 | - description: Path within Git project to build; empty for root project directory. 81 | name: PIPELINE_REPOSITORY_CONTEXT_DIR 82 | value: 83 | - description: Path within Git project pointing to the pipeline run script 84 | name: PIPELINE_SCRIPT 85 | value: Jenkinsfile 86 | - description: Git source URI for application 87 | name: SOURCE_CODE_URL 88 | required: true 89 | value: https://github.com/redhat-cop/spring-rest.git 90 | - description: Git branch/tag reference 91 | name: SOURCE_CODE_REF 92 | value: "master" 93 | - description: GitHub trigger secret 94 | from: '[a-zA-Z0-9]{8}' 95 | generate: expression 96 | name: GITHUB_WEBHOOK_SECRET 97 | required: true 98 | - description: Generic build trigger secret 99 | from: '[a-zA-Z0-9]{8}' 100 | generate: expression 101 | name: GENERIC_WEBHOOK_SECRET 102 | required: true 103 | - description: Namespace in which the ImageStreams for Red Hat Middleware images are 104 | installed. These ImageStreams are normally installed in the openshift namespace. 105 | You should only need to modify this if you've installed the ImageStreams in a 106 | different namespace/project. 107 | name: IMAGE_STREAM_NAMESPACE 108 | required: true 109 | value: openshift 110 | - description: Image stream tag for the image you'd like to use to build the application 111 | name: IMAGE_STREAM_TAG_NAME 112 | required: true 113 | value: redhat-openjdk18-openshift:1.1 114 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/templates/cluster-secret.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: cluster-credentials-secret 5 | metadata: 6 | annotations: 7 | description: Cluster Credential Secret 8 | tags: secret 9 | version: 1.0.0 10 | name: cluster-credentials-secret 11 | objects: 12 | - apiVersion: v1 13 | stringData: 14 | api: ${API_URL} 15 | registry: ${REGISTRY_URL} 16 | token: "${TOKEN}" 17 | data: 18 | kind: Secret 19 | metadata: 20 | name: ${SECRET_NAME} 21 | type: Opaque 22 | parameters: 23 | - description: The name for the application. 24 | name: SECRET_NAME 25 | required: true 26 | value: prod-credentials 27 | - description: The API URL 28 | name: API_URL 29 | required: true 30 | - description: The Registry Route URL 31 | name: REGISTRY_URL 32 | required: true 33 | - description: Service Account Token 34 | name: TOKEN 35 | required: true 36 | -------------------------------------------------------------------------------- /multi-cluster-spring-boot/skopeo-example/.applier/templates/deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: basic-spring-boot 5 | metadata: 6 | annotations: 7 | description: Application template for JWS applications built using a Jenkins Pipeline 8 | iconClass: icon-tomcat 9 | tags: java,spring 10 | version: 1.2.0 11 | name: basic-sprint-boot 12 | objects: 13 | - apiVersion: v1 14 | kind: Service 15 | metadata: 16 | annotations: 17 | description: The web server's http port. 18 | labels: 19 | app: ${APPLICATION_NAME} 20 | name: ${APPLICATION_NAME} 21 | namespace: ${NAMESPACE} 22 | spec: 23 | ports: 24 | - port: 8080 25 | targetPort: 8080 26 | selector: 27 | deploymentConfig: ${APPLICATION_NAME} 28 | - apiVersion: route.openshift.io/v1 29 | kind: Route 30 | metadata: 31 | annotations: 32 | description: Route for application's http service. 33 | labels: 34 | app: ${APPLICATION_NAME} 35 | name: ${APPLICATION_NAME} 36 | namespace: ${NAMESPACE} 37 | spec: 38 | host: ${HOSTNAME_HTTP} 39 | to: 40 | name: ${APPLICATION_NAME} 41 | - apiVersion: image.openshift.io/v1 42 | kind: ImageStream 43 | metadata: 44 | labels: 45 | app: ${APPLICATION_NAME} 46 | name: ${APPLICATION_NAME} 47 | namespace: ${NAMESPACE} 48 | - apiVersion: apps.openshift.io/v1 49 | kind: DeploymentConfig 50 | metadata: 51 | labels: 52 | app: ${APPLICATION_NAME} 53 | name: ${APPLICATION_NAME} 54 | namespace: ${NAMESPACE} 55 | spec: 56 | replicas: 1 57 | selector: 58 | deploymentConfig: ${APPLICATION_NAME} 59 | strategy: 60 | type: Recreate 61 | template: 62 | metadata: 63 | labels: 64 | app: ${APPLICATION_NAME} 65 | deploymentConfig: ${APPLICATION_NAME} 66 | name: ${APPLICATION_NAME} 67 | spec: 68 | containers: 69 | - env: 70 | - name: JWS_ADMIN_USERNAME 71 | value: ${JWS_ADMIN_USERNAME} 72 | - name: JWS_ADMIN_PASSWORD 73 | value: ${JWS_ADMIN_PASSWORD} 74 | image: ${APPLICATION_NAME} 75 | imagePullPolicy: Always 76 | name: ${APPLICATION_NAME} 77 | ports: 78 | - containerPort: 8778 79 | name: jolokia 80 | protocol: TCP 81 | - containerPort: 8080 82 | name: http 83 | protocol: TCP 84 | readinessProbe: 85 | exec: 86 | command: 87 | - /bin/bash 88 | - -c 89 | - curl -s 'http://localhost:8080${READINESS_PATH}' 90 | |grep -iq '${READINESS_RESPONSE}' 91 | terminationGracePeriodSeconds: 60 92 | triggers: 93 | - imageChangeParams: 94 | automatic: true 95 | containerNames: 96 | - ${APPLICATION_NAME} 97 | from: 98 | kind: ImageStreamTag 99 | name: ${APPLICATION_NAME}:latest 100 | type: ImageChange 101 | - type: ConfigChange 102 | - apiVersion: rbac.authorization.k8s.io/v1 103 | kind: RoleBinding 104 | metadata: 105 | creationTimestamp: null 106 | labels: 107 | template: basic-tomcat-template 108 | name: jenkins_edit 109 | namespace: ${NAMESPACE} 110 | groupNames: null 111 | roleRef: 112 | apiGroup: rbac.authorization.k8s.io 113 | kind: ClusterRole 114 | name: edit 115 | subjects: 116 | - kind: ServiceAccount 117 | name: ${SA_NAME} 118 | namespace: ${SA_NAMESPACE} 119 | userNames: 120 | - system:serviceaccount:${SA_NAMESPACE}:${SA_NAME} 121 | parameters: 122 | - description: The name for the application. 123 | name: APPLICATION_NAME 124 | required: true 125 | value: jws-app 126 | - description: The namespace to deploy into 127 | name: NAMESPACE 128 | required: true 129 | - description: Name of a service account that can deploy to this project 130 | name: SA_NAME 131 | required: true 132 | value: jenkins 133 | - description: Namespace of service account that can deploy to this project 134 | name: SA_NAMESPACE 135 | required: true 136 | - description: 'Custom hostname for http service route. Leave blank for default hostname, 137 | e.g.: -.' 138 | name: HOSTNAME_HTTP 139 | - description: 'URI to check for app health' 140 | name: READINESS_PATH 141 | required: true 142 | value: '/' 143 | - description: 'String value expected back from readiness check' 144 | name: READINESS_RESPONSE 145 | required: true 146 | value: 'Hello World!' 147 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "config:best-practices", 5 | "schedule:earlyMondays" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /secure-spring-boot/.gitignore: -------------------------------------------------------------------------------- 1 | openshift-applier 2 | roles/* 3 | *.pyc 4 | .idea 5 | *.iml 6 | gdsl 7 | *.retry 8 | pre_post_requirements.yml -------------------------------------------------------------------------------- /secure-spring-boot/.openshift-applier/inventory/group_vars/seed-hosts.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | app_name: secure-spring-boot-app 4 | 5 | build: 6 | APPLICATION_NAME: "{{app_name}}" 7 | NAMESPACE: "{{ci_cd_namespace}}" 8 | SOURCE_REPOSITORY_URL: https://github.com/redhat-cop/container-pipelines.git 9 | SOURCE_REPOSITORY_REF: master 10 | CONTEXT_DIR: secure-spring-boot 11 | APPLICATION_SOURCE_REPO: https://github.com/redhat-cop/spring-rest.git 12 | APPLICATION_SOURCE_REF: 2.1.2.Final-redhat-00003.1 13 | PIPELINE_SCRIPT: Jenkinsfile 14 | 15 | dev_deploy: 16 | APPLICATION_NAME: "{{app_name}}" 17 | NAMESPACE: "{{dev_namespace}}" 18 | SA_NAME: jenkins 19 | SA_NAMESPACE: "{{ci_cd_namespace}}" 20 | 21 | test_deploy: 22 | APPLICATION_NAME: "{{app_name}}" 23 | NAMESPACE: "{{test_namespace}}" 24 | SA_NAME: jenkins 25 | SA_NAMESPACE: "{{ci_cd_namespace}}" 26 | 27 | openshift_cluster_content: 28 | - object: builds 29 | content: 30 | - name: "create application build pipeline" 31 | template: "{{ inventory_dir }}/../templates/build.yml" 32 | params_from_vars: "{{ build }}" 33 | tags: 34 | - build 35 | - object: deployments 36 | content: 37 | - name: "deploy application to dev environment" 38 | template: "{{ inventory_dir }}/../templates/deployment.yml" 39 | params_from_vars: "{{ dev_deploy }}" 40 | tags: 41 | - deployment 42 | - name: "deploy application to test environment" 43 | template: "{{ inventory_dir }}/../templates/deployment.yml" 44 | params_from_vars: "{{ test_deploy }}" 45 | tags: 46 | - deployment 47 | 48 | -------------------------------------------------------------------------------- /secure-spring-boot/.openshift-applier/inventory/hosts: -------------------------------------------------------------------------------- 1 | [seed-hosts] 2 | localhost ansible_connection=local 3 | -------------------------------------------------------------------------------- /secure-spring-boot/.openshift-applier/templates/build.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: generic-java-jenkins-pipeline 5 | metadata: 6 | annotations: 7 | description: Application template for JWS applications built using a Jenkins Pipeline 8 | iconClass: icon-tomcat 9 | tags: tomcat,tomcat8,java,jboss,xpaas,jenkins-ci 10 | version: 1.2.0 11 | name: generic-java-jenkins-pipeline 12 | objects: 13 | - apiVersion: image.openshift.io/v1 14 | kind: ImageStream 15 | metadata: 16 | labels: 17 | application: ${APPLICATION_NAME} 18 | name: ${APPLICATION_NAME} 19 | namespace: ${NAMESPACE} 20 | - apiVersion: build.openshift.io/v1 21 | kind: BuildConfig 22 | metadata: 23 | labels: 24 | application: ${APPLICATION_NAME} 25 | name: "${APPLICATION_NAME}-pipeline" 26 | namespace: "${NAMESPACE}" 27 | spec: 28 | source: 29 | type: Git 30 | git: 31 | uri: ${SOURCE_REPOSITORY_URL} 32 | ref: ${SOURCE_REPOSITORY_REF} 33 | contextDir: ${CONTEXT_DIR} 34 | triggers: 35 | - type: "GitHub" 36 | github: 37 | secret: ${GITHUB_WEBHOOK_SECRET} 38 | - type: "ConfigChange" 39 | strategy: 40 | type: "JenkinsPipeline" 41 | jenkinsPipelineStrategy: 42 | jenkinsfilePath: ${PIPELINE_SCRIPT} 43 | env: 44 | - name: "APPLICATION_SOURCE_REPO" 45 | value: "${APPLICATION_SOURCE_REPO}" 46 | - name: "APPLICATION_SOURCE_REF" 47 | value: "${APPLICATION_SOURCE_REF}" 48 | - apiVersion: build.openshift.io/v1 49 | kind: BuildConfig 50 | metadata: 51 | labels: 52 | application: ${APPLICATION_NAME} 53 | name: ${APPLICATION_NAME} 54 | namespace: "${NAMESPACE}" 55 | spec: 56 | output: 57 | to: 58 | kind: ImageStreamTag 59 | name: ${APPLICATION_NAME}:latest 60 | source: 61 | binary: {} 62 | type: Binary 63 | strategy: 64 | sourceStrategy: 65 | from: 66 | kind: ImageStreamTag 67 | name: ${IMAGE_STREAM_TAG_NAME} 68 | namespace: ${IMAGE_STREAM_NAMESPACE} 69 | type: Source 70 | parameters: 71 | - description: The name for the application. 72 | name: APPLICATION_NAME 73 | required: true 74 | value: secure-spring-boot 75 | - description: The namespace to deploy into 76 | name: NAMESPACE 77 | required: true 78 | - description: Git source URI for application 79 | name: SOURCE_REPOSITORY_URL 80 | required: true 81 | value: https://github.com/redhat-cop/container-pipelines.git 82 | - description: Git branch/tag reference 83 | name: SOURCE_REPOSITORY_REF 84 | value: master 85 | - description: Path within Git project to build; empty for root project directory. 86 | name: CONTEXT_DIR 87 | value: secure-spring-boot 88 | - description: Source code repo for demo app 89 | name: APPLICATION_SOURCE_REPO 90 | required: true 91 | value: https://github.com/redhat-cop/spring-rest.git 92 | - description: Source code branch for demo app 93 | name: APPLICATION_SOURCE_REF 94 | value: master 95 | - description: Path within Git project pointing to the pipeline run script 96 | name: PIPELINE_SCRIPT 97 | value: Jenkinsfile 98 | - description: GitHub trigger secret 99 | from: '[a-zA-Z0-9]{8}' 100 | generate: expression 101 | name: GITHUB_WEBHOOK_SECRET 102 | required: true 103 | - description: Generic build trigger secret 104 | from: '[a-zA-Z0-9]{8}' 105 | generate: expression 106 | name: GENERIC_WEBHOOK_SECRET 107 | required: true 108 | - description: Namespace in which the ImageStreams for Red Hat Middleware images are 109 | installed. These ImageStreams are normally installed in the openshift namespace. 110 | You should only need to modify this if you've installed the ImageStreams in a 111 | different namespace/project. 112 | name: IMAGE_STREAM_NAMESPACE 113 | required: true 114 | value: openshift 115 | - description: Image stream tag for the image you'd like to use to build the application 116 | name: IMAGE_STREAM_TAG_NAME 117 | required: true 118 | value: redhat-openjdk18-openshift:1.4 -------------------------------------------------------------------------------- /secure-spring-boot/.openshift-applier/templates/deployment.yml: -------------------------------------------------------------------------------- 1 | apiVersion: template.openshift.io/v1 2 | kind: Template 3 | labels: 4 | template: secure-spring-boot 5 | metadata: 6 | annotations: 7 | description: Application template for JWS applications built using a Jenkins Pipeline 8 | iconClass: icon-tomcat 9 | tags: java,spring 10 | version: 1.2.0 11 | name: secure-spring-boot 12 | objects: 13 | - apiVersion: v1 14 | kind: Service 15 | metadata: 16 | annotations: 17 | description: The web server's http port. 18 | labels: 19 | app: ${APPLICATION_NAME} 20 | name: ${APPLICATION_NAME} 21 | namespace: ${NAMESPACE} 22 | spec: 23 | ports: 24 | - port: 8080 25 | targetPort: 8080 26 | selector: 27 | deploymentConfig: ${APPLICATION_NAME} 28 | - apiVersion: route.openshift.io/v1 29 | kind: Route 30 | metadata: 31 | annotations: 32 | description: Route for application's http service. 33 | labels: 34 | app: ${APPLICATION_NAME} 35 | name: ${APPLICATION_NAME} 36 | namespace: ${NAMESPACE} 37 | spec: 38 | host: ${HOSTNAME_HTTP} 39 | to: 40 | name: ${APPLICATION_NAME} 41 | - apiVersion: image.openshift.io/v1 42 | kind: ImageStream 43 | metadata: 44 | labels: 45 | app: ${APPLICATION_NAME} 46 | name: ${APPLICATION_NAME} 47 | namespace: ${NAMESPACE} 48 | - apiVersion: apps.openshift.io/v1 49 | kind: DeploymentConfig 50 | metadata: 51 | labels: 52 | app: ${APPLICATION_NAME} 53 | name: ${APPLICATION_NAME} 54 | namespace: ${NAMESPACE} 55 | spec: 56 | replicas: 1 57 | selector: 58 | deploymentConfig: ${APPLICATION_NAME} 59 | strategy: 60 | type: Recreate 61 | template: 62 | metadata: 63 | labels: 64 | app: ${APPLICATION_NAME} 65 | deploymentConfig: ${APPLICATION_NAME} 66 | name: ${APPLICATION_NAME} 67 | spec: 68 | containers: 69 | - env: 70 | - name: JWS_ADMIN_USERNAME 71 | value: ${JWS_ADMIN_USERNAME} 72 | - name: JWS_ADMIN_PASSWORD 73 | value: ${JWS_ADMIN_PASSWORD} 74 | image: ${APPLICATION_NAME} 75 | imagePullPolicy: Always 76 | name: ${APPLICATION_NAME} 77 | ports: 78 | - containerPort: 8778 79 | name: jolokia 80 | protocol: TCP 81 | - containerPort: 8080 82 | name: http 83 | protocol: TCP 84 | readinessProbe: 85 | exec: 86 | command: 87 | - /bin/bash 88 | - -c 89 | - curl -s 'http://localhost:8080${READINESS_PATH}' 90 | |grep -i -q '${READINESS_RESPONSE}' 91 | terminationGracePeriodSeconds: 60 92 | triggers: 93 | - imageChangeParams: 94 | automatic: true 95 | containerNames: 96 | - ${APPLICATION_NAME} 97 | from: 98 | kind: ImageStreamTag 99 | name: ${APPLICATION_NAME}:latest 100 | type: ImageChange 101 | - type: ConfigChange 102 | - apiVersion: rbac.authorization.k8s.io/v1 103 | kind: RoleBinding 104 | metadata: 105 | creationTimestamp: null 106 | labels: 107 | template: basic-tomcat-template 108 | name: jenkins_edit 109 | namespace: ${NAMESPACE} 110 | groupNames: null 111 | roleRef: 112 | apiGroup: rbac.authorization.k8s.io 113 | kind: ClusterRole 114 | name: edit 115 | subjects: 116 | - kind: ServiceAccount 117 | name: ${SA_NAME} 118 | namespace: ${SA_NAMESPACE} 119 | userNames: 120 | - system:serviceaccount:${SA_NAMESPACE}:${SA_NAME} 121 | parameters: 122 | - description: The name for the application. 123 | name: APPLICATION_NAME 124 | required: true 125 | value: jws-app 126 | - description: The namespace to deploy into 127 | name: NAMESPACE 128 | required: true 129 | - description: Name of a service account that can deploy to this project 130 | name: SA_NAME 131 | required: true 132 | value: jenkins 133 | - description: Namespace of service account that can deploy to this project 134 | name: SA_NAMESPACE 135 | required: true 136 | - description: 'Custom hostname for http service route. Leave blank for default hostname, 137 | e.g.: -.' 138 | name: HOSTNAME_HTTP 139 | - description: 'URI to check for app health' 140 | name: READINESS_PATH 141 | required: true 142 | value: '/actuator/health' 143 | - description: 'String value expected back from readiness check' 144 | name: READINESS_RESPONSE 145 | required: true 146 | value: '{"status":"UP"}' -------------------------------------------------------------------------------- /secure-spring-boot/Jenkinsfile: -------------------------------------------------------------------------------- 1 | library identifier: "pipeline-library@v1.6", 2 | retriever: modernSCM( 3 | [ 4 | $class: "GitSCMSource", 5 | remote: "https://github.com/redhat-cop/pipeline-library.git" 6 | ] 7 | ) 8 | 9 | openshift.withCluster() { 10 | 11 | env.NAMESPACE = openshift.project() 12 | 13 | env.BUILD = "${env.NAMESPACE}" 14 | env.DEV = env.BUILD.replace('ci-cd', 'dev') 15 | env.TEST = env.BUILD.replace('ci-cd', 'test') 16 | 17 | env.MVN_SNAPSHOT_DEPLOYMENT_REPOSITORY = "nexus::default::http://nexus:8081/repository/maven-snapshots" 18 | 19 | env.APP_NAME = "${env.JOB_NAME}".replaceAll(/-?${env.PROJECT_NAME}-?/, '').replaceAll(/-?pipeline-?/, '').replaceAll('/','') 20 | env.POM_FILE = env.PIPELINE_CONTEXT_DIR ? "${env.PIPELINE_CONTEXT_DIR}/pom.xml" : "pom.xml" 21 | env.BUILD_OUTPUT_DIR = env.PIPELINE_CONTEXT_DIR ? "${env.PIPELINE_CONTEXT_DIR}/target" : "target" 22 | 23 | echo "Starting Pipeline for ${APP_NAME}..." 24 | 25 | } 26 | 27 | pipeline { 28 | // Use Jenkins Maven slave 29 | // Jenkins will dynamically provision this as OpenShift Pod 30 | // All the stages and steps of this Pipeline will be executed on this Pod 31 | // After Pipeline completes the Pod is killed so every run will have clean 32 | // workspace 33 | agent { 34 | label 'jenkins-slave-mvn' 35 | } 36 | 37 | // Pipeline Stages start here 38 | // Requeres at least one stage 39 | stages { 40 | 41 | // Checkout source code 42 | // This is required as Pipeline code is originally checked out 43 | // so this will pull the application source code to this slave 44 | stage('Git Checkout Application') { 45 | steps { 46 | // Turn off Git's SSL cert check, uncomment if needed 47 | // sh 'git config --global http.sslVerify false' 48 | git url: "${APPLICATION_SOURCE_REPO}" 49 | } 50 | } 51 | 52 | //verify nexus is up 53 | 54 | stage('Wait for Nexus') { 55 | steps { 56 | verifyDeployment(targetApp: "nexus", projectName: env.BUILD) 57 | } 58 | } 59 | 60 | // Run Maven build, skipping tests 61 | stage('Build, Unit Test, Dependency Scan'){ 62 | steps { 63 | 64 | // run build 65 | sh "mvn -B clean deploy -f ${POM_FILE} -DaltDeploymentRepository=${MVN_SNAPSHOT_DEPLOYMENT_REPOSITORY}" 66 | 67 | // publish unit test report 68 | publishHTML(target: [ 69 | reportDir : "${env.BUILD_OUTPUT_DIR}/site/jacoco", 70 | reportFiles : 'index.html', 71 | reportName : 'Jacoco Unit Test Report', 72 | keepAll : true, 73 | alwaysLinkToLastBuild: false, 74 | allowMissing : true 75 | ]) 76 | 77 | // publish dependency check report 78 | publishHTML(target: [ 79 | reportDir : "${env.BUILD_OUTPUT_DIR}", 80 | reportFiles : 'dependency-check-report.html', 81 | reportName : 'OWASP Dependency Check Report', 82 | keepAll : true, 83 | alwaysLinkToLastBuild: true, 84 | allowMissing : false 85 | ]) 86 | 87 | } 88 | } 89 | 90 | // Perform Static Code Analysis using SonarQube 91 | stage ('Code Analysis') { 92 | steps { 93 | sonarqubeStaticAnalysis( 94 | pomFile: "${POM_FILE}", 95 | buildServerWebHookName: "jenkins" 96 | ) 97 | } 98 | } 99 | 100 | // Build Container Image using the artifacts produced in previous stages 101 | stage('Build Container Image'){ 102 | steps { 103 | binaryBuild(projectName: env.BUILD, buildConfigName: env.APP_NAME, buildFromPath: "${env.BUILD_OUTPUT_DIR}") 104 | } 105 | } 106 | 107 | stage('Promote from Build to Dev') { 108 | steps { 109 | tagImage(sourceImageName: env.APP_NAME, sourceImagePath: env.BUILD, toImagePath: env.DEV) 110 | } 111 | } 112 | 113 | stage ('Verify Deployment to Dev') { 114 | steps { 115 | verifyDeployment(projectName: env.DEV, targetApp: env.APP_NAME) 116 | } 117 | } 118 | 119 | 120 | stage('Promotion gate') { 121 | steps { 122 | script { 123 | input message: 'Promote application to Test?' 124 | } 125 | } 126 | } 127 | 128 | stage('Promote from Dev to Test') { 129 | steps { 130 | tagImage(sourceImageName: env.APP_NAME, sourceImagePath: env.DEV, toImagePath: env.TEST) 131 | } 132 | } 133 | 134 | stage ('Verify Deployment to Test') { 135 | steps { 136 | verifyDeployment(projectName: env.TEST, targetApp: env.APP_NAME) 137 | } 138 | } 139 | 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /secure-spring-boot/README.md: -------------------------------------------------------------------------------- 1 | # Secure Spring Boot Pipeline 2 | 3 | The objective of this pipeline to provide a working example of using basic security and quality checks in a Spring Boot app running on OpenShift. There are many, many tools that can be used to this end. Currently this pipeline supports the plugins identified in [the CoP Spring Rest app](https://github.com/redhat-cop/spring-rest). 4 | 5 | ## Usage 6 | 7 | This repo assumes knowledge of the OpenShift Applier and ansible in general. If you are new to applier/ansible, please see [the docs](https://github.com/redhat-cop/openshift-applier) which have really useful tutorials. 8 | 9 | 1. `git clone https://github.com/redhat-cop/container-pipelines` 10 | 2. `cd container-pipelines/secure-spring-boot` 11 | 3. If you would like to customize the names of OpenShift projects created, edit `project-names.uml` 12 | 4. `ansible-galaxy install -r requirements.yml --roles-path=roles` 13 | 5. `oc login` 14 | 6. `ansible-playbook ci-cd-tooling.yml -i roles/labs-ci-cd/inventory/` 15 | 7. `ansible-playbook spring-boot-app.yml -i .openshift-applier/inventory/` 16 | 8. Navigate to the OpenShift Web console for your CI/CD project. You should see a pipeline build running automatically (once everything spins up). 17 | 18 | ## TODO Screen Shots of the pipeline to explain what's in the box 19 | See https://github.com/redhat-cop/container-pipelines/issues/72 20 | 21 | ## Advisories 22 | 23 | - Running the pipeline for the first time will take ~10 minutes because all maven dependencies and NIST DB need to be downloaded. Subsequent builds will be faster. Also see https://github.com/redhat-cop/container-pipelines/issues/71 24 | - If you have issues with Nexus certificate like seen [here](https://github.com/redhat-cop/infra-ansible/issues/342), then you can add the following ansible flag as a workaround: `-e nexus_validate_certs=false`. 25 | -------------------------------------------------------------------------------- /secure-spring-boot/ci-cd-tooling.yml: -------------------------------------------------------------------------------- 1 | # This playbook will install a targeted set of CI/CD tools for the spring boot pipeline by reusing https://github.com/rht-labs/labs-ci-cd 2 | --- 3 | - name: Create Projects and Policies 4 | hosts: bootstrap 5 | vars_files: 6 | - project-names.yml 7 | tasks: 8 | - include_role: 9 | name: openshift-applier/roles/openshift-applier 10 | vars: 11 | filter_tags: projects,rolebinding-jenkins 12 | 13 | - name: Create CI/CD tools 14 | hosts: tools 15 | vars_files: 16 | - project-names.yml 17 | tasks: 18 | # https://github.com/redhat-cop/openshift-applier/issues/113 19 | - copy: 20 | src: roles/labs-ci-cd/pre_post_requirements.yml 21 | dest: pre_post_requirements.yml 22 | - include_role: 23 | name: openshift-applier/roles/openshift-applier 24 | tags: 25 | - openshift-applier 26 | vars: 27 | filter_tags: sonarqube,mvn-slave,nexus,jenkins -------------------------------------------------------------------------------- /secure-spring-boot/project-names.yml: -------------------------------------------------------------------------------- 1 | # This is a variable file that declares the names of the OpenShift projects that will be created 2 | --- 3 | # this the variable you can change 4 | project_name_root: secure-spring-boot 5 | 6 | # do not touch these variables or things will break 7 | ci_cd_namespace: "{{ project_name_root }}-ci-cd" 8 | dev_namespace: "{{ project_name_root }}-dev" 9 | test_namespace: "{{ project_name_root }}-test" -------------------------------------------------------------------------------- /secure-spring-boot/requirements.yml: -------------------------------------------------------------------------------- 1 | # This is the Ansible Galaxy requirements file to pull in the correct roles 2 | - src: https://github.com/rht-labs/labs-ci-cd 3 | scm: git 4 | version: v3.11.5 5 | name: labs-ci-cd 6 | - src: https://github.com/redhat-cop/openshift-applier 7 | scm: git 8 | version: v2.1.1 9 | name: openshift-applier 10 | -------------------------------------------------------------------------------- /secure-spring-boot/spring-boot-app.yml: -------------------------------------------------------------------------------- 1 | # This playbook will install a targeted the spring book app using the configurations in this repo 2 | --- 3 | - name: Deploy Spring Boot Application 4 | hosts: seed-hosts 5 | vars_files: 6 | - project-names.yml 7 | tasks: 8 | - include_role: 9 | name: openshift-applier/roles/openshift-applier 10 | --------------------------------------------------------------------------------