├── .applier
├── group_vars
│ └── seed-hosts.yml
└── hosts
├── .github
├── PULL_REQUEST_TEMPLATE.md
├── stale.yml
└── workflows
│ └── mvn.yaml
├── .gitignore
├── .openshift
└── templates
│ └── build-pipelines.j2
├── .travis
└── check-missing.sh
├── LICENSE
├── OWNERS
├── README.md
├── TESTING.md
├── _test
└── setup.sh
├── galaxy-requirements.yml
├── jenkins-s2i
├── configuration
│ └── org.jenkinsci.plugins.workflow.libs.GlobalLibraries.xml
├── jenkins-s2i.yml
└── plugins.txt
├── meta
└── main.yml
├── pom.xml
├── requirements.yml
├── roles
├── configure-jenkins
│ ├── defaults
│ │ └── main.yml
│ └── tasks
│ │ └── main.yml
├── link-secret
│ └── tasks
│ │ └── main.yml
└── process-tests
│ ├── defaults
│ └── main.yml
│ └── tasks
│ └── main.yml
├── src
└── org
│ └── redhatcop
│ └── util
│ ├── Notifications.txt
│ └── notifications.groovy
├── test
├── Jenkinsfile-applier
├── Jenkinsfile-applier-fail-missingsecret
├── Jenkinsfile-applyTemplate
├── Jenkinsfile-applyTemplate-viahttp
├── Jenkinsfile-applyTemplate-withparams
├── Jenkinsfile-binaryBuild
├── Jenkinsfile-binaryBuild-fail-missingbuildconfig
├── Jenkinsfile-buildAndTag
├── Jenkinsfile-clusterCredentials
├── Jenkinsfile-clusterCredentials-fail-missingsecret
├── Jenkinsfile-configMap
├── Jenkinsfile-configMap-fail-missingconfigmap
├── Jenkinsfile-crossClusterPromote
├── Jenkinsfile-crossClusterPromote-fail-missingsecret
├── Jenkinsfile-patchBuildConfigOutputLabels
├── Jenkinsfile-rollback
├── Jenkinsfile-rollback-fail-missingdc
├── Jenkinsfile-rollout
├── Jenkinsfile-rollout-deployment
├── Jenkinsfile-rollout-fail-loghistory
├── Jenkinsfile-rollout-fail-missingdc
├── Jenkinsfile-sonarqubeStaticAnalysis
├── Jenkinsfile-tagAndDeploy
├── Jenkinsfile-tagImage
├── Jenkinsfile-verifyDeployment
├── Jenkinsfile-verifyDeployment-fail-viacrashloop
├── Jenkinsfile-verifyService
├── Jenkinsfile-verifyService-fail-nopods
├── create-pipeline-library.groovy
├── create-sonarqube-installation.groovy
├── disabled-imageMirror
└── org
│ └── redhatcop
│ └── util
│ ├── end-to-end
│ ├── Jenkinsfile
│ ├── README.md
│ ├── files
│ │ ├── params
│ │ │ ├── build
│ │ │ ├── deploy-dev
│ │ │ ├── deploy-test
│ │ │ ├── jenkins-deployment
│ │ │ └── jenkins-s2i
│ │ ├── projects.yml
│ │ └── templates
│ │ │ ├── build.yml
│ │ │ └── deployment.yml
│ └── inventory
│ │ ├── group_vars
│ │ └── seed-hosts.yml
│ │ └── hosts
│ ├── rocketchat
│ ├── Jenkinsfile
│ ├── README.md
│ ├── files
│ │ ├── params
│ │ │ ├── jenkins-deployment.params
│ │ │ ├── jenkins-s2i.params
│ │ │ └── notifications-build.params
│ │ ├── projects.yml
│ │ ├── rocketchat-secret.yml
│ │ └── templates
│ │ │ └── build-template.yml
│ └── inventory
│ │ ├── group_vars
│ │ └── seed-hosts.yml
│ │ └── hosts
│ └── rollback
│ ├── Jenkinsfile
│ ├── README.md
│ ├── files
│ ├── params
│ │ ├── build
│ │ ├── deploy
│ │ ├── jenkins-deployment
│ │ └── jenkins-s2i
│ ├── projects.yml
│ └── templates
│ │ ├── build.yml
│ │ └── deployment.yml
│ └── inventory
│ ├── group_vars
│ └── seed-hosts.yml
│ └── hosts
└── vars
├── applier.groovy
├── applier.txt
├── applyTemplate.groovy
├── applyTemplate.txt
├── binaryBuild.groovy
├── binaryBuild.txt
├── buildAndTag.groovy
├── buildAndTag.txt
├── clusterCredentials.groovy
├── clusterCredentials.txt
├── configMap.groovy
├── configMap.txt
├── crossClusterPromote.groovy
├── crossClusterPromote.txt
├── imageMirror.groovy
├── imageMirror.txt
├── patchBuildConfigOutputLabels.groovy
├── patchBuildConfigOutputLabels.txt
├── rollback.groovy
├── rollback.txt
├── rollout.groovy
├── rollout.txt
├── sonarqubeStaticAnalysis.groovy
├── sonarqubeStaticAnalysis.txt
├── tagAndDeploy.groovy
├── tagAndDeploy.txt
├── tagImage.groovy
├── tagImage.txt
├── verifyDeployment.groovy
├── verifyDeployment.txt
├── verifyService.groovy
└── verifyService.txt
/.applier/group_vars/seed-hosts.yml:
--------------------------------------------------------------------------------
1 | ---
2 | namespace: pipelinelib-testing
3 | repository_url: https://github.com/redhat-cop/pipeline-library.git
4 | repo_ref: master
5 | clone_dir: /tmp/redhat-cop/pipeline-library/master
6 | templates_repo_ref: v1.4.13
7 |
8 | secretdata_auth: "openshift1:{{ oc_token }}"
9 | secretdata:
10 | dockercfg_json: '{"auths": { "{{ internal_registry_url.split("/")[0] }}": {"username": "openshift1", "password": "{{ oc_token }}", "auth": "{{ secretdata_auth | b64encode }}", "email": "unused"}}}'
11 |
12 | secrets: '{
13 | "{{ namespace }}": {
14 | "local-registry-generic": {
15 | "username": "openshift1",
16 | "token": "{{ oc_token }}",
17 | "registry": "{{ internal_registry_url.split("/")[0] }}"
18 | },
19 | "my-token": {
20 | "username": "openshift1",
21 | "password": "{{ oc_token }}"
22 | }
23 | }
24 | }'
25 |
26 | jenkins:
27 | deploy:
28 | MEMORY_REQUEST: 2Gi
29 | MEMORY_LIMIT: 3Gi
30 | CPU_REQUEST: 2
31 | CPU_LIMIT: 3
32 | imagestreams:
33 | ansible:
34 | IMAGE_STREAM_ROLE: jenkins-slave
35 | IMAGE_STREAM_NAME: jenkins-slave-ansible
36 | IMAGE_STREAM_TAG_FROM_KIND: DockerImage
37 | IMAGE_STREAM_TAG_FROM_NAME: quay.io/redhat-cop/jenkins-slave-ansible:v1.15
38 | IMAGE_STREAM_NAMESPACE: "{{ namespace }}"
39 | imagemgmt:
40 | IMAGE_STREAM_ROLE: jenkins-slave
41 | IMAGE_STREAM_NAME: jenkins-slave-image-mgmt
42 | IMAGE_STREAM_TAG_FROM_KIND: DockerImage
43 | IMAGE_STREAM_TAG_FROM_NAME: siamaksade/jenkins-slave-skopeo-centos7
44 | IMAGE_STREAM_NAMESPACE: "{{ namespace }}"
45 | secrets:
46 | localregistrydockercfg:
47 | NAME: local-registry
48 | DOCKER_CONFIG: "{{ secretdata.dockercfg_json | to_json | b64encode }}"
49 | tests:
50 | files: "{{ lookup('fileglob', '{{ inventory_dir }}/../test/Jenkinsfile-*', wantlist=true) }}"
51 |
52 | openshift_cluster_content:
53 | - galaxy_requirements:
54 | - "{{ inventory_dir }}/../galaxy-requirements.yml"
55 | - object: Environment Setup
56 | content:
57 | - name: Create Projects
58 | template: "https://raw.githubusercontent.com/redhat-cop/openshift-templates/{{ templates_repo_ref }}/project-requests/create-project.yml"
59 | action: create
60 | params_from_vars:
61 | NAMESPACE: "{{ namespace }}"
62 | NAMESPACE_DESCRIPTION: "{{ namespace }}"
63 | NAMESPACE_DISPLAY_NAME: "{{ namespace }}"
64 | tags:
65 | - project
66 | - object: jenkins-imagestreams
67 | content:
68 | - name: jenkins-slave-ansible
69 | template: "https://raw.githubusercontent.com/redhat-cop/openshift-templates/{{ templates_repo_ref }}/imagestreams/imagestream-generic.yml"
70 | params_from_vars: "{{ jenkins.imagestreams.ansible }}"
71 | namespace: "{{ namespace }}"
72 | tags:
73 | - jenkins-imagestreams
74 | - name: jenkins-slave-image-mgmt
75 | template: "https://raw.githubusercontent.com/redhat-cop/openshift-templates/{{ templates_repo_ref }}/imagestreams/imagestream-generic.yml"
76 | params_from_vars: "{{ jenkins.imagestreams.imagemgmt }}"
77 | namespace: "{{ namespace }}"
78 | tags:
79 | - jenkins-imagestreams
80 | - object: jenkins-secrets
81 | content:
82 | - name: local-registry-dockercfg
83 | template: "https://raw.githubusercontent.com/redhat-cop/openshift-templates/{{ templates_repo_ref }}/secrets/secret-docker-cfg.yml"
84 | params_from_vars: "{{ jenkins.secrets.localregistrydockercfg }}"
85 | namespace: "{{ namespace }}"
86 | tags:
87 | - jenkins-secrets
88 | - name: generic
89 | file: "https://raw.githubusercontent.com/redhat-cop/openshift-templates/{{ templates_repo_ref }}/secrets/dynamic-opaque-jinja.j2"
90 | namespace: "{{ namespace }}"
91 | post_steps:
92 | - role: casl-ansible/roles/openshift-labels
93 | vars:
94 | label: "credential.sync.jenkins.openshift.io=true"
95 | target_object: "secret"
96 | target_name: "my-token"
97 | target_namespace: "{{ namespace }}"
98 | tags:
99 | - jenkins-secrets
100 | - object: jenkins
101 | content:
102 | - name: jenkins
103 | template: "https://raw.githubusercontent.com/redhat-cop/openshift-templates/{{ templates_repo_ref }}/jenkins/jenkins-ephemeral-template.yml"
104 | params_from_vars: "{{ jenkins.deploy }}"
105 | namespace: "{{ namespace }}"
106 | pre_steps:
107 | - role: pipeline-library/roles/process-tests
108 | post_steps:
109 | - role: casl-ansible/roles/openshift-replicas-ready
110 | vars:
111 | type: deploymentconfig
112 | resource: jenkins
113 | - role: casl-ansible/roles/openshift-route-status
114 | vars:
115 | target_namespace: "{{ namespace }}"
116 | route: jenkins
117 | protocol: https
118 | status: 200
119 | retries: 10
120 | delay: 30
121 | validate_certificates: no
122 | headers:
123 | Authorization: "Bearer {{ oc_token }}"
124 | - role: pipeline-library/roles/configure-jenkins
125 | - role: pipeline-library/roles/link-secret
126 | vars:
127 | sa_name: "jenkins"
128 | secret_name: "local-registry"
129 | - role: pipeline-library/roles/link-secret
130 | vars:
131 | sa_name: "jenkins"
132 | secret_name: "local-registry-generic"
133 | tags:
134 | - jenkins
135 | - object: test-pipelines
136 | content:
137 | - name: Deploy test pipelines
138 | file: "{{ inventory_dir }}/../.openshift/templates/build-pipelines.j2"
139 | namespace: "{{ namespace }}"
140 | tags:
141 | - test-pipelines
142 |
--------------------------------------------------------------------------------
/.applier/hosts:
--------------------------------------------------------------------------------
1 | [seed-hosts]
2 | localhost ansible_connection=local
3 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | #### What is this PR About?
2 | Describe the contents of the PR
3 |
4 | #### How do we test this?
5 | Provide commands/steps to test this PR.
6 |
7 | cc: @redhat-cop/day-in-the-life
8 |
--------------------------------------------------------------------------------
/.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/mvn.yaml:
--------------------------------------------------------------------------------
1 | # This workflow will build a Java project with Maven
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
3 |
4 | name: Java CI with Maven
5 |
6 | on: [push, pull_request]
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - name: Checkout
13 | uses: actions/checkout@v2
14 |
15 | - name: Set up JDK 1.8
16 | uses: actions/setup-java@v1
17 | with:
18 | java-version: 1.8
19 |
20 | - uses: actions/cache@v1
21 | with:
22 | path: ~/.m2/repository
23 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
24 | restore-keys: |
25 | ${{ runner.os }}-maven-
26 |
27 | - name: Build with Maven
28 | run: mvn -B clean install
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | deps/
2 | .DS_Store
3 | **/galaxy/
4 |
5 | ### Eclipse template
6 | .metadata
7 | bin/
8 | tmp/
9 | *.tmp
10 | *.bak
11 | *.swp
12 | *~.nib
13 | local.properties
14 | .settings/
15 | .loadpath
16 | .recommenders
17 |
18 | ### JetBrains template
19 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
20 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
21 |
22 | # User-specific stuff:
23 | .idea/
24 | .idea/**/workspace.xml
25 | .idea/**/tasks.xml
26 | .idea/dictionaries
27 |
28 | # Sensitive or high-churn files:
29 | .idea/**/dataSources/
30 | .idea/**/dataSources.ids
31 | .idea/**/dataSources.xml
32 | .idea/**/dataSources.local.xml
33 | .idea/**/sqlDataSources.xml
34 | .idea/**/dynamic.xml
35 | .idea/**/uiDesigner.xml
36 |
37 | ## File-based project format:
38 | *.iws
39 | *.iml
40 |
41 | ### Maven template
42 | target/
43 | pom.xml.tag
44 | pom.xml.releaseBackup
45 | pom.xml.versionsBackup
46 | pom.xml.next
47 | release.properties
48 | dependency-reduced-pom.xml
49 | buildNumber.properties
50 | .mvn/timing.properties
51 | .classpath
52 | .project
53 |
--------------------------------------------------------------------------------
/.openshift/templates/build-pipelines.j2:
--------------------------------------------------------------------------------
1 | ---
2 | # https://github.com/redhat-cop/openshift-templates/blob/v1.4.14/jenkins-pipelines/jenkins-pipeline-template-no-ocp-triggers.yml
3 | apiVersion: v1
4 | kind: List
5 | items:
6 | {% for current in jenkins_test_files %}
7 | {% set jenkinsfile = current.path | basename %}
8 | - apiVersion: v1
9 | kind: BuildConfig
10 | metadata:
11 | labels:
12 | build: "{{ jenkinsfile }}"
13 | name: "{{ jenkinsfile }}"
14 | type: "pipeline"
15 | name: "{{ jenkinsfile | lower }}"
16 | spec:
17 | runPolicy: "Serial"
18 | source:
19 | contextDir: "test"
20 | git:
21 | ref: "{{ repo_ref }}"
22 | uri: "{{ repository_url }}"
23 | type: Git
24 | strategy:
25 | jenkinsPipelineStrategy:
26 | jenkinsfile: |-
27 | {{ current.content | indent(10, True) }}
28 | type: JenkinsPipeline
29 | {% endfor %}
--------------------------------------------------------------------------------
/.travis/check-missing.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | echo "Checking for missing docs and tests"
4 |
5 | find vars -type f -name "*.groovy" -exec bash -c '[ -f vars/$(basename {} .groovy).txt ] || echo "Missing vars/$(basename {} .groovy).txt" >> fail.tmp' \;
6 | find vars -type f -name "*.groovy" ! -path "vars/imageMirror.groovy" -exec bash -c '[ -f test/Jenkinsfile-$(basename {} .groovy) ] || echo "Missing test/Jenkinsfile-$(basename {} .groovy)" >> fail.tmp' \;
7 |
8 | if [ -f fail.tmp ]; then
9 | echo "Found:"
10 |
11 | cat fail.tmp
12 | exit 1
13 | fi
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
--------------------------------------------------------------------------------
/OWNERS:
--------------------------------------------------------------------------------
1 | # See the OWNERS docs at https://go.k8s.io/owners
2 |
3 | reviewers:
4 | - etsauer
5 | - oybed
6 | - pabrahamsson
7 | - sabre1041
8 | - springdo
9 | approvers:
10 | - etsauer
11 | - garethahealy
12 | - oybed
13 | - pabrahamsson
14 | - sabre1041
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 | []()
3 |
4 | # OpenShift Pipeline Library
5 |
6 | ## What This Repo Is
7 |
8 | This is a shared library of Jenkins Pipeline functionality we've developed and use frequently within the CoP. This repo can be imported into a jenkins server (following [this doc](https://jenkins.io/doc/book/pipeline/shared-libraries/#using-libraries)) and used to add functionality to Pipeline scripts.
9 |
10 | You can include this repo in your Jenkins Pipeline by defining following at beginning of your Jenkinsfile:
11 |
12 | ```
13 | library identifier: "pipeline-library@master", retriever: modernSCM(
14 | [$class: "GitSCMSource",
15 | remote: "https://github.com/redhat-cop/pipeline-library.git"])
16 | ```
17 |
18 | Included in this library:
19 |
20 | * [org.redhatcop.util.Notifications](./src/org/redhatcop/util/Notifications.txt) - A build status notification system for chat-ops
21 | * [vars](./vars/) - Many small Jenkins functions for OpenShift
22 |
23 |
24 | Please see https://github.com/redhat-cop/container-pipelines or https://github.com/redhat-cop/containers-quickstarts for related content.
25 |
26 | ## Other Resources
27 |
28 | * https://jenkins.io/doc/book/pipeline/shared-libraries/
29 |
--------------------------------------------------------------------------------
/TESTING.md:
--------------------------------------------------------------------------------
1 | # Testing
2 | ## Automated
3 | We currently use openshift-applier for deployment and test as per:
4 |
5 | ```bash
6 | ./_test/setup.sh applier && ./_test/setup.sh test
7 | ```
8 |
9 | The scripts also support passing in the project, git repo and git branch as per:
10 | ```bash
11 | ./_test/setup.sh applier pipelinelib-testing garethahealy/pipeline-library master && ./_test/setup.sh test
12 | ```
13 |
14 | ## Manual
15 | The below steps can be used to test each pipeline lib method. If you are testing a PR or your local branch, you need to change the following:
16 | - test/create-pipeline-library.groovy - to point to your git repo, instead of https://github.com/redhat-cop/pipeline-library.git
17 | - test/Jenkinsfile-* - the branch for the Jenkinsfile needs to match the branch of the changes
18 |
19 | For convenience, the below commands can automate the above. NOTE: the below presumes the remote url is https based.
20 | ```bash
21 | sed -i "s|https://github.com/redhat-cop/pipeline-library.git|$(git config --get remote.origin.url)|g" test/create-pipeline-library.groovy
22 | find test -type f -name "Jenkinsfile*" -exec sed -i "s/pipeline-library@master/pipeline-library@$(git rev-parse --abbrev-ref HEAD)/g" {} \;
23 | ```
24 |
25 | ### Create projects
26 | ```bash
27 | oc new-project pipelinelib-testing
28 | ```
29 |
30 | ### Import additional image streams for slaves
31 | ```bash
32 | oc import-image jenkins-slave-ansible --from=quay.io/redhat-cop/jenkins-slave-ansible:v1.15 --confirm
33 | oc label imagestream jenkins-slave-ansible role=jenkins-slave
34 |
35 | oc import-image jenkins-slave-image-mgmt --from=siamaksade/jenkins-slave-skopeo-centos7 --confirm
36 | oc label imagestream jenkins-slave-image-mgmt role=jenkins-slave
37 | ```
38 |
39 | // NOTE: The below image is not released into quay yet, thats why we are using the above
40 | // oc import-image jenkins-slave-image-mgmt --from=quay.io/redhat-cop/jenkins-slave-image-mgmt --confirm
41 | // oc label imagestream jenkins-slave-image-mgmt role=jenkins-slave
42 |
43 | ### Create BuildConfigs
44 | ```bash
45 | find test -type f -name "Jenkinsfile-*" -exec bash -c '\
46 | oc process -f https://raw.githubusercontent.com/redhat-cop/openshift-templates/v1.4.9/jenkins-pipelines/jenkins-pipeline-template-no-ocp-triggers.yml \
47 | -p NAME=$(basename {} | tr 'A-Z' 'a-z') \
48 | -p PIPELINE_FILENAME=$(basename {}) \
49 | -p PIPELINE_CONTEXT_DIR=test \
50 | -p PIPELINE_SOURCE_REPOSITORY_URL=$(git config --get remote.origin.url) \
51 | -p PIPELINE_SOURCE_REPOSITORY_REF=$(git rev-parse --abbrev-ref HEAD)' \; | oc apply -f -
52 | ```
53 |
54 | ### Deploy Jenkins
55 | ```bash
56 | oc process -p MEMORY_REQUEST=2Gi -p MEMORY_LIMIT=3Gi -f https://raw.githubusercontent.com/redhat-cop/openshift-templates/v1.4.9/jenkins/jenkins-persistent-template.yml | oc apply -f -
57 | oc patch dc jenkins -p '{"apiVersion":"apps.openshift.io/v1","kind":"DeploymentConfig","metadata":{"name":"jenkins"},"spec":{"template":{"spec":{"containers":[{"name":"jenkins","resources":{"limits":{"cpu":"3"},"requests":{"cpu":"2"}}}]}}}}'
58 | oc rollout status dc/jenkins --watch=true
59 | ```
60 |
61 | ### Create global pipeline lib
62 | ```bash
63 | curl --header "Authorization: Bearer $(oc whoami --show-token)" --data-urlencode "script=$(< test/create-pipeline-library.groovy)" https://$(oc get route jenkins -o jsonpath={.spec.host})/scriptText
64 | ```
65 |
66 | ### Install plugins
67 | ```bash
68 | curl -X POST -d "" --header "Authorization: Bearer $(oc whoami --show-token)" --header "Content-Type: text/xml" https://$(oc get route jenkins -o jsonpath={.spec.host})/pluginManager/installNecessaryPlugins
69 | curl -X POST -d "" --header "Authorization: Bearer $(oc whoami --show-token)" --header "Content-Type: text/xml" https://$(oc get route jenkins -o jsonpath={.spec.host})/pluginManager/installNecessaryPlugins
70 | ```
71 |
72 | ### Create username/password and dockercfg secrets
73 | ```bash
74 | oc create secret generic my-token --from-literal=username=openshift1 --from-literal=password=$(oc whoami --show-token)
75 | oc label secret my-token credential.sync.jenkins.openshift.io=true
76 |
77 | oc create secret generic --from-literal=registry=$(oc get is jenkins -n openshift -o jsonpath={.status.dockerImageRepository} | cut -d '/' -f1 | xargs) --from-literal=username=openshift1 --from-literal=token=$(oc whoami --show-token) local-registry-generic
78 | oc secrets link --for=mount jenkins local-registry-generic
79 |
80 | oc create secret docker-registry --docker-server=$(oc get is jenkins -n openshift -o jsonpath={.status.dockerImageRepository} | cut -d '/' -f1 | xargs) --docker-username=openshift1 --docker-password=$(oc whoami --show-token) --docker-email=unused local-registry
81 | oc secrets link --for=mount jenkins local-registry
82 | ```
83 |
84 | ### Start all BuildConfigs
85 | ```bash
86 | find test -type f -name "Jenkinsfile-*" -exec bash -c 'oc start-build $(basename {} | tr 'A-Z' 'a-z')-pipeline' \;
87 | ```
88 |
89 | ### Cleanup
90 | ```bash
91 | oc delete project pipelinelib-testing{,-promotion-testing,-build-s2i-executable,-sonarqube}
92 | ```
--------------------------------------------------------------------------------
/_test/setup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | trap "exit 1" TERM
3 | export TOP_PID=$$
4 | NAMESPACE="${2:-pipelinelib-testing}"
5 | CI_REPO_SLUG="${3:-redhat-cop/pipeline-library}"
6 | CI_BRANCH="${4:-master}"
7 | CLONE_DIR="/tmp/${CI_REPO_SLUG}/${CI_BRANCH}"
8 |
9 | clone() {
10 | rm -rf ${CLONE_DIR}
11 | git clone -b ${CI_BRANCH} "https://github.com/${CI_REPO_SLUG}.git" ${CLONE_DIR}
12 | }
13 |
14 | applier() {
15 | pushd ${CLONE_DIR}
16 |
17 | echo "${CI_BRANCH}"
18 | echo "${CI_REPO_SLUG}"
19 |
20 | sed -i "7s|.*|- src: https://github.com/${CI_REPO_SLUG}.git|" galaxy-requirements.yml
21 | sed -i "9s/.*/ version: ${CI_BRANCH}/g" galaxy-requirements.yml
22 |
23 | ansible-galaxy install -r requirements.yml -p galaxy --force
24 | ansible-playbook -i .applier/ galaxy/openshift-applier/playbooks/openshift-cluster-seed.yml \
25 | -e namespace=${NAMESPACE} \
26 | -e repo_ref=${CI_BRANCH} \
27 | -e repository_url=https://github.com/${CI_REPO_SLUG}.git \
28 | -e clone_dir=${CLONE_DIR} \
29 | -e oc_token="$(oc whoami --show-token)" \
30 | -e internal_registry_url="$(oc get is jenkins -n openshift -o jsonpath={.status.dockerImageRepository})"
31 |
32 | popd
33 | }
34 |
35 | test() {
36 | # Make sure we're logged in, and we've found at least one build to test.
37 | oc status > /dev/null || echo "Please log in before running tests." || exit 1
38 | if [ $(oc get bc -l type=pipeline -n ${NAMESPACE} --no-headers | grep -c .) -lt 1 ]; then
39 | echo "Did not find any builds, make sure you've passed the proper arguments."
40 | exit 1
41 | fi
42 |
43 | echo "Ensure all Builds are executed..."
44 | for pipeline in $(oc get bc -l type=pipeline -n ${NAMESPACE} -o jsonpath='{.items[*].metadata.name}'); do
45 | oc start-build ${pipeline} -n ${NAMESPACE}
46 | done
47 |
48 | echo "Waiting for all builds to start..."
49 | while [[ "$(get_build_phases "New")" -ne 0 || $(get_build_phases "Pending") -ne 0 ]]; do
50 | echo -ne "New Builds: $(get_build_phases "New"), Pending Builds: $(get_build_phases "Pending")$([ "$TRAVIS" != "true" ] && echo "\r" || echo "\n")"
51 | sleep 1
52 | done
53 |
54 | echo "Waiting for all builds to complete..."
55 | while [ $(get_build_phases "Running") -ne 0 ]; do
56 | echo -ne "Running Builds: $(get_build_phases "Running")$([ "$TRAVIS" != "true" ] && echo "\r" || echo "\n")"
57 | sleep 1
58 | done
59 |
60 | download_jenkins_logs_for_failed "$(ls --ignore=*fail* ${CLONE_DIR}/test/ | grep "Jenkinsfile" | tr 'A-Z' 'a-z' | xargs)" "Complete"
61 | download_jenkins_logs_for_failed "$(ls ${CLONE_DIR}/test/Jenkinsfile-*-fail-* | xargs -n 1 basename | tr 'A-Z' 'a-z' | xargs)" "Failed"
62 |
63 | logcount=$(ls *.log | wc -l)
64 | if [[ $logcount -gt 0 ]]; then
65 | echo "Tests Completed Unsuccessfully. See logs above."
66 | exit 1
67 | else
68 | echo "Tests Completed Successfully!"
69 | fi
70 | }
71 |
72 | get_build_phases() {
73 | phase=$1
74 | result=$(retry 5 oc get builds -l type=pipeline -o jsonpath="{.items[?(@.status.phase==\"${phase}\")].metadata.name}" -n $NAMESPACE) || kill -s TERM $TOP_PID
75 | echo ${result} | wc -w
76 | }
77 |
78 | get_build_phase_for() {
79 | name=$1
80 | result=$(retry 5 oc get builds ${name} -o jsonpath="{.status.phase}" -n $NAMESPACE) || kill -s TERM $TOP_PID
81 | echo ${result}
82 | }
83 |
84 | get_buildnumber_for() {
85 | name=$1
86 | result=$(retry 5 oc get buildconfigs ${name} -o jsonpath="{.status.lastVersion}" -n $NAMESPACE) || kill -s TERM $TOP_PID
87 | echo ${result}
88 | }
89 |
90 | download_jenkins_logs_for_failed() {
91 | jobs=$1
92 | expectedphase=$2
93 |
94 | echo "Checking jobs which should have an expected phase of ${expectedphase}..."
95 |
96 | jenkins_url=$(oc get route jenkins -n ${NAMESPACE} -o jsonpath='{ .spec.host }')
97 | token=$(oc whoami --show-token)
98 |
99 | for pipeline in ${jobs}; do
100 | build_number=$(get_buildnumber_for ${pipeline})
101 | build="${pipeline}-${build_number}"
102 |
103 | phase=$(get_build_phase_for ${build})
104 | if [[ "${expectedphase}" != "${phase}" ]]; then
105 | echo ""
106 | echo "Downloading Jenkins logs for ${build} as phase (${phase}) does not match expected (${expectedphase})..."
107 | curl -k -sS -H "Authorization: Bearer ${token}" "https://${jenkins_url}/blue/rest/organizations/jenkins/pipelines/${NAMESPACE}/pipelines/${NAMESPACE}-${pipeline}/runs/${build_number}/log/?start=0&download=true" -o "${pipeline}.log"
108 |
109 | echo "## START LOGS: ${build}"
110 | cat "${pipeline}.log"
111 | echo "## END LOGS: ${build}"
112 | fi
113 | done
114 | }
115 |
116 | function retry {
117 | local retries=$1
118 | shift
119 |
120 | local count=0
121 | until "$@"; do
122 | exit=$?
123 | wait=$((2 ** $count))
124 | count=$(($count + 1))
125 | if [ $count -lt $retries ]; then
126 | echo "Retry $count/$retries exited $exit, retrying in $wait seconds..."
127 | sleep $wait
128 | else
129 | echo "Retry $count/$retries exited $exit, no more retries left."
130 | return $exit
131 | fi
132 | done
133 | return 0
134 | }
135 |
136 | # Process arguments
137 | case $1 in
138 | applier)
139 | clone
140 | applier
141 | ;;
142 | test)
143 | test
144 | ;;
145 | *)
146 | echo "Not an option"
147 | exit 1
148 | esac
149 |
--------------------------------------------------------------------------------
/galaxy-requirements.yml:
--------------------------------------------------------------------------------
1 | ---
2 | - src: https://github.com/redhat-cop/casl-ansible.git
3 | scm: git
4 | version: v3.11.6
5 | name: casl-ansible
6 |
7 | - src: https://github.com/redhat-cop/pipeline-library.git
8 | scm: git
9 | version: master
10 | name: pipeline-library
11 |
--------------------------------------------------------------------------------
/jenkins-s2i/configuration/org.jenkinsci.plugins.workflow.libs.GlobalLibraries.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | cop-library
6 |
7 |
8 | a568a19b-8f41-478b-b80f-28eeee157e05
9 | SAME
10 | etsauer
11 | pipeline-library
12 | *
13 |
14 | true
15 | true
16 | false
17 | false
18 | true
19 | false
20 |
21 |
22 | shared-lib
23 | false
24 | true
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/jenkins-s2i/jenkins-s2i.yml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | kind: Template
4 | labels:
5 | template: jenkins2-s2i
6 | group: jenkins2-s2i
7 | metadata:
8 | annotations:
9 | description: Creates the Jenkins2 image for CD Pipeline builds
10 | iconClass: icon-jenkins
11 | tags: instant-app,jenkins,cicd
12 | name: jenkins2-s2i
13 | parameters:
14 | - description: Custom Jenkins for CD Pipeline SCM location
15 | displayName: CD Jenkins Pipeline SCM URL
16 | name: JENKINS_GIT_URL
17 | required: true
18 | - description: Custom Jenkins for CD Pipeline SCM branch
19 | displayName: CD Jenkins Pipeline SCM branch
20 | name: JENKINS_GIT_BRANCH
21 | required: true
22 | value: 'master'
23 | - description: Context Directory inside of the Git repo
24 | displayName: Context Directory
25 | name: JENKINS_GIT_CONTEXT_DIR
26 | value: ''
27 | objects:
28 | # Jenkins2
29 | - apiVersion: v1
30 | kind: ImageStream
31 | metadata:
32 | labels:
33 | app: jenkins2-s2i
34 | template: jenkins2-s2i
35 | name: jenkins2-s2i
36 | - apiVersion: v1
37 | kind: BuildConfig
38 | metadata:
39 | labels:
40 | application: jenkins2-s2i
41 | template: jenkins2-s2i
42 | name: jenkins2-s2i
43 | spec:
44 | triggers:
45 | - type: "ConfigChange"
46 | output:
47 | to:
48 | kind: ImageStreamTag
49 | name: jenkins2-s2i:latest
50 | source:
51 | type: Git
52 | git:
53 | uri: "${JENKINS_GIT_URL}"
54 | ref: "${JENKINS_GIT_BRANCH}"
55 | contextDir: ${JENKINS_GIT_CONTEXT_DIR}
56 | strategy:
57 | sourceStrategy:
58 | from:
59 | kind: ImageStreamTag
60 | name: jenkins:latest
61 | namespace: openshift
62 | type: Source
63 |
--------------------------------------------------------------------------------
/jenkins-s2i/plugins.txt:
--------------------------------------------------------------------------------
1 | http_request:1.8.21
2 |
--------------------------------------------------------------------------------
/meta/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 | dependencies:
3 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 | 4.0.0
6 | org.redhatcop
7 | pipeline-library
8 | 1.7.0-SNAPSHOT
9 |
10 |
11 | UTF-8
12 | UTF-8
13 | 1.8
14 | ${java.version}
15 | ${java.version}
16 | 3.6.1
17 | 2.4.9
18 | 1.6.1
19 | 2.5.3
20 |
21 |
22 |
23 | scm:git:ssh://git@github.com:redhat-cop/pipeline-library.git
24 | scm:git:ssh://git@github.com:redhat-cop/pipeline-library.git
25 | https://github.com/redhat-cop/pipeline-library.git
26 | HEAD
27 |
28 |
29 |
30 |
31 | org.codehaus.groovy
32 | groovy-all
33 | 2.5.0
34 | pom
35 |
36 |
37 |
38 |
39 |
40 |
41 | org.codehaus.gmavenplus
42 | gmavenplus-plugin
43 | 1.6.1
44 |
45 |
46 |
47 | addSources
48 | addTestSources
49 | compile
50 | compileTests
51 |
52 |
53 |
54 |
55 | true
56 |
57 |
58 | ${project.basedir}/src
59 |
60 | **/*.groovy
61 |
62 |
63 |
64 | ${project.basedir}/vars
65 |
66 | **/*.groovy
67 |
68 |
69 |
70 |
71 |
72 | ${project.basedir}/test/groovy
73 |
74 | **/*.groovy
75 |
76 |
77 |
78 |
79 |
80 |
81 | org.apache.maven.plugins
82 | maven-compiler-plugin
83 | 3.8.1
84 |
85 |
86 | org.apache.maven.plugins
87 | maven-source-plugin
88 | 2.4
89 |
90 |
91 | attach-sources
92 |
93 | jar-no-fork
94 | test-jar-no-fork
95 |
96 |
97 |
98 |
99 |
100 | exec-maven-plugin
101 | org.codehaus.mojo
102 | 1.6.0
103 |
104 |
105 | test-compile
106 |
107 | exec
108 |
109 |
110 | ${basedir}/.travis/check-missing.sh
111 |
112 |
113 |
114 |
115 |
116 | org.apache.maven.plugins
117 | maven-release-plugin
118 | ${maven.release.plugin.version}
119 |
120 |
121 |
122 |
123 |
124 |
125 | repo.jenkins-ci.org
126 | http://repo.jenkins-ci.org/public/
127 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/roles/configure-jenkins/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | delay: 5
4 | retries: 3
--------------------------------------------------------------------------------
/roles/configure-jenkins/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: "Lookup route url for jenkins"
4 | shell: "oc get route jenkins -n {{ namespace }} -o jsonpath='{ .spec.host }'"
5 | register: url
6 |
7 | - name: Create pipeline library
8 | uri:
9 | url: "https://{{ url.stdout }}/scriptText"
10 | method: POST
11 | body: "{{ 'script=' ~ lookup('file', '{{ clone_dir }}/test/create-pipeline-library.groovy') | urlencode }}"
12 | headers:
13 | Authorization: "Bearer {{ oc_token }}"
14 | validate_certs: no
15 | retries: "{{ retries|int }}"
16 | delay: "{{ delay|int }}"
17 | register: createlib_result
18 | until: createlib_result is not failed
19 |
20 | - name: Install plugins
21 | uri:
22 | url: "https://{{ url.stdout }}/pluginManager/installNecessaryPlugins"
23 | method: POST
24 | status_code:
25 | - 200
26 | - 302
27 | body: ""
28 | headers:
29 | Authorization: "Bearer {{ oc_token }}"
30 | Content-Type: text/xml
31 | validate_certs: no
32 | retries: "{{ retries|int }}"
33 | delay: "{{ delay|int }}"
34 | register: plugininstall_result
35 | until: plugininstall_result is not failed
36 | with_items:
37 | - sonar@2.10
38 | - openshift-client@1.0.32
39 |
--------------------------------------------------------------------------------
/roles/link-secret/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Link secret to service account for mount
4 | command: "oc secrets link --for=mount {{ sa_name }} {{ secret_name }} -n {{ namespace }}"
--------------------------------------------------------------------------------
/roles/process-tests/defaults/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | delay: 5
4 | retries: 3
--------------------------------------------------------------------------------
/roles/process-tests/tasks/main.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | - name: Update pipeline-library with correct git branch
4 | replace:
5 | path: "{{ clone_dir }}/test/create-pipeline-library.groovy"
6 | regexp: "https://github.com/redhat-cop/pipeline-library.git"
7 | replace: "{{ repository_url }}"
8 |
9 | - name: Update Jenkinsfile tests with correct git branch
10 | replace:
11 | path: "{{ item }}"
12 | regexp: "pipeline-library@master"
13 | replace: "pipeline-library@{{ repo_ref }}"
14 | with_fileglob: "{{ clone_dir }}/test/Jenkinsfile*"
15 |
16 | - name: Update Jenkinsfile tests with correct Jenkins credential name
17 | replace:
18 | path: "{{ item }}"
19 | regexp: "pipelinelib-testing-my-token"
20 | replace: "{{ namespace }}-my-token"
21 | with_fileglob: "{{ clone_dir }}/test/Jenkinsfile*"
22 |
23 | - name: Update Sonar Jenkinsfile with correct git repo/branch
24 | replace:
25 | path: "{{ item }}"
26 | regexp: "git clone https://github.com/redhat-cop/pipeline-library.git"
27 | replace: "git clone {{ repository_url }}; pushd pipeline-library; git checkout {{ repo_ref }}; popd"
28 | with_fileglob: "{{ clone_dir }}/test/Jenkinsfile-sonarqubeStaticAnalysis"
29 |
30 | - name: Load Jenkinsfile content into memory
31 | set_fact:
32 | jenkins_test_files: "{{ jenkins_test_files|default([]) + [{'path': item, 'content': lookup('file', '{{ item }}') }] }}"
33 | with_items: "{{ lookup('fileglob', '{{ clone_dir }}/test/Jenkinsfile-*', wantlist=true) }}"
34 |
--------------------------------------------------------------------------------
/src/org/redhatcop/util/Notifications.txt:
--------------------------------------------------------------------------------
1 | # Notifications library
2 |
3 | Sends notifications on build status to rocketChat.
4 |
5 | This requires you to set up an [Incoming Webhook](https://rocket.chat/docs/administrator-guides/integrations/) in RocketChat.
6 |
7 | Sample usage:
8 |
9 | ```
10 | @Library('cop-library') _
11 |
12 | def rocketchat_url = 'https://rocket.example.com/hooks/[integration_id]/[integration_secret]'
13 | def n = new org.redhatcop.util.notifications()
14 |
15 | n.notifyBuild('STARTED', rocketchat_url)
16 | ```
17 |
--------------------------------------------------------------------------------
/src/org/redhatcop/util/notifications.groovy:
--------------------------------------------------------------------------------
1 | package org.redhatcop.util;
2 |
3 | def rocketChatSend(String url, String text, String emoji) {
4 | echo "Sending rocketchat message: {\"username\":\"Jenkins\",\"icon_emoji\":\"${emoji}\",\"text\": \"${text}\"}"
5 |
6 | // POST Message
7 | def response = httpRequest url: url,
8 | httpMode: 'POST',
9 | requestBody: "{\"username\":\"Jenkins\",\"icon_emoji\":\"${emoji}\",\"text\": \"${text}\"}"
10 | }
11 |
12 | def notifyBuild(String buildStatus = 'STARTED', String rocketChatUrl) {
13 | // build status of null means successful
14 | buildStatus = buildStatus ?: 'SUCCESSFUL'
15 |
16 | // Default values
17 | def colorName = 'RED'
18 | def colorCode = '#FF0000'
19 | def subject = "${buildStatus}: Job ${env.JOB_NAME} [${env.BUILD_NUMBER}]"
20 | def summary = "${subject} (${env.BUILD_URL})"
21 | def details = """
STARTED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':
22 | Check console output at "${env.JOB_NAME} [${env.BUILD_NUMBER}]"
"""
23 |
24 | // Override default values based on build status
25 | if (buildStatus == 'STARTED') {
26 | color = 'YELLOW'
27 | colorCode = '#FFFF00'
28 | status_icon = ':soon:'
29 | } else if (buildStatus == 'SUCCESSFUL') {
30 | color = 'GREEN'
31 | colorCode = '#00FF00'
32 | status_icon = ':white_check_mark:'
33 | } else {
34 | color = 'RED'
35 | colorCode = '#FF0000'
36 | status_icon = ':negative_squared_cross_mark:'
37 | }
38 |
39 | // Send notifications
40 | rocketChatSend(rocketChatUrl, summary, status_icon)
41 | echo "Sending RocketChat Notification: ${buildStatus}"
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-applier:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | def applierNamespace
5 | def testingNamespace
6 |
7 | node("jenkins-slave-ansible") {
8 | stage("SETUP: Clone containers-quickstarts") {
9 | testingNamespace = sh(script: "cat /var/run/secrets/kubernetes.io/serviceaccount/namespace", returnStdout: true)
10 | applierNamespace = testingNamespace + '-build-s2i-executable'
11 |
12 | sh "git clone https://github.com/redhat-cop/containers-quickstarts.git"
13 |
14 | openshift.logLevel(10)
15 | }
16 |
17 | stage("TEST: Run applier for 'build-s2i-executable'") {
18 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'pipelinelib-testing-my-token', usernameVariable: 'USERNAME', passwordVariable: 'TOKEN']]) {
19 | applier([
20 | inventoryPath : ".applier/hosts",
21 | requirementsPath: "requirements.yml",
22 | ansibleRootDir : "${WORKSPACE}/containers-quickstarts/build-s2i-executable",
23 | applierPlaybook : "galaxy/openshift-applier/playbooks/openshift-cluster-seed.yml",
24 | playbookAdditionalArgs: "-e namespace=${applierNamespace}",
25 | clusterAPI : "https://kubernetes.default.svc",
26 | clusterToken : "${TOKEN}"
27 | ])
28 | }
29 | }
30 |
31 | stage("ASSERT") {
32 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'pipelinelib-testing-my-token', usernameVariable: 'USERNAME', passwordVariable: 'TOKEN']]) {
33 | openshift.withCluster("https://kubernetes.default.svc", "${TOKEN}") {
34 | openshift.withProject(applierNamespace) {
35 | def buildConfig = openshift.selector("bc", "build-s2i-executable")
36 | assert buildConfig.exists()
37 | }
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-applier-fail-missingsecret:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("jenkins-slave-ansible") {
5 | stage("SETUP: Set logging to verbose") {
6 | openshift.logLevel(10)
7 | }
8 |
9 | stage("TEST: Run applier for 'build-s2i-executable' and fail") {
10 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'pipelinelib-testing-my-token', usernameVariable: 'USERNAME', passwordVariable: 'TOKEN']]) {
11 | applier([
12 | inventoryPath : ".applier/hosts",
13 | requirementsPath: "requirements.yml",
14 | ansibleRootDir : "${WORKSPACE}/containers-quickstarts/build-s2i-executable",
15 | applierPlaybook : "galaxy/openshift-applier/playbooks/openshift-cluster-seed.yml",
16 | secretName : "doesnt-exist",
17 | ])
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-applyTemplate:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("maven") {
5 | stage("SETUP: Create deployment files") {
6 | sh "curl -L -o cakephp-mysql.json https://raw.githubusercontent.com/openshift/origin/v3.11.0/examples/quickstarts/cakephp-mysql.json"
7 |
8 | openshift.logLevel(10)
9 | }
10 |
11 | stage("TEST: Can deploy via local file") {
12 | applyTemplate([
13 | templateFile : "cakephp-mysql.json",
14 | loglevel: 3
15 | ])
16 | }
17 |
18 | stage("ASSERT") {
19 | openshift.withCluster() {
20 | openshift.withProject() {
21 | def deployment = openshift.selector("dc", "cakephp-mysql-example")
22 | assert deployment.exists()
23 |
24 | //Scale down afterwards to lower quotas
25 | deployment.scale("--replicas=0")
26 | }
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/test/Jenkinsfile-applyTemplate-viahttp:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("maven") {
5 | stage("SETUP: Create deployment files") {
6 | def params = """
7 | NAME=applytemplate-http
8 | DATABASE_SERVICE_NAME=applytemplate-http
9 | """
10 |
11 | writeFile file: "params.txt", text: params
12 |
13 | openshift.logLevel(10)
14 | }
15 |
16 | stage("TEST: Can deploy via http") {
17 | applyTemplate([
18 | templateFile : "https://raw.githubusercontent.com/openshift/origin/v3.11.0/examples/quickstarts/cakephp-mysql.json",
19 | parameterFile: "params.txt"
20 | ])
21 | }
22 |
23 | stage("ASSERT") {
24 | openshift.withCluster() {
25 | openshift.withProject() {
26 | def deployment = openshift.selector("dc", "applytemplate-http")
27 | assert deployment.exists()
28 |
29 | //Scale down afterwards to lower quotas
30 | deployment.scale("--replicas=0")
31 | }
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/test/Jenkinsfile-applyTemplate-withparams:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("maven") {
5 | stage("SETUP: Create deployment files") {
6 | def params = """
7 | NAME=applytemplate
8 | DATABASE_SERVICE_NAME=applytemplate
9 | """
10 |
11 | writeFile file: "params.txt", text: params
12 |
13 | sh "curl -L -o cakephp-mysql.json https://raw.githubusercontent.com/openshift/origin/v3.11.0/examples/quickstarts/cakephp-mysql.json"
14 |
15 | openshift.logLevel(10)
16 | }
17 |
18 | stage("TEST: Can deploy via local file") {
19 | applyTemplate([
20 | templateFile : "cakephp-mysql.json",
21 | parameterFile: "params.txt"
22 | ])
23 | }
24 |
25 | stage("ASSERT") {
26 | openshift.withCluster() {
27 | openshift.withProject() {
28 | def deployment = openshift.selector("dc", "applytemplate")
29 | assert deployment.exists()
30 |
31 | //Scale down afterwards to lower quotas
32 | deployment.scale("--replicas=0")
33 | }
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/test/Jenkinsfile-binaryBuild:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | def firstBuildVersion
5 |
6 | node("maven") {
7 | stage("SETUP: Create build files") {
8 | openshift.withCluster() {
9 | openshift.withProject() {
10 | def buildConfig = openshift.selector("bc", "sample-build-binary")
11 | if (!buildConfig.exists()) {
12 | openshift.apply("-f", "https://raw.githubusercontent.com/openshift/origin/v3.11.0/test/extended/testdata/builds/test-build.yaml")
13 | }
14 |
15 | def buildConfigObject = buildConfig.object()
16 | firstBuildVersion = buildConfigObject.status?.lastVersion
17 | }
18 | }
19 |
20 | dir("build") {
21 | dockerfile = """
22 | FROM scratch
23 | COPY README.md /
24 | """
25 |
26 | writeFile file: "README.md", text: "Test file"
27 | writeFile file: "Dockerfile", text: dockerfile
28 | }
29 |
30 | openshift.logLevel(10)
31 | }
32 |
33 | stage("TEST: Can build using from-file") {
34 | binaryBuild([
35 | buildConfigName: "sample-build-binary",
36 | buildFromFlag : "--from-dir",
37 | buildFromPath : "${WORKSPACE}/build/"
38 | ])
39 | }
40 |
41 | stage("ASSERT") {
42 | openshift.withCluster() {
43 | openshift.withProject() {
44 | def build = openshift.selector("build", "sample-build-binary-${firstBuildVersion + 1}")
45 | assert build.exists()
46 | }
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/test/Jenkinsfile-binaryBuild-fail-missingbuildconfig:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("maven") {
5 | stage("SETUP: Create build files") {
6 | dir("build") {
7 | dockerfile = """
8 | FROM scratch
9 | COPY README.md /
10 | """
11 |
12 | writeFile file: "README.md", text: "Test file"
13 | writeFile file: "Dockerfile", text: dockerfile
14 | }
15 |
16 | openshift.logLevel(10)
17 | }
18 |
19 | stage("TEST: Can build using from-file and fail") {
20 | binaryBuild([
21 | buildConfigName: "doesnt-exist",
22 | buildFromFlag : "--from-dir",
23 | buildFromPath : "${WORKSPACE}/build/"
24 | ])
25 | }
26 | }
--------------------------------------------------------------------------------
/test/Jenkinsfile-buildAndTag:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | def dockerRegistry
5 | def firstBuildVersion
6 | def testingNamespace
7 |
8 | podTemplate(label: "jnlp", cloud: "openshift", inheritFrom: "jenkins-slave-image-mgmt", volumes: [
9 | secretVolume(mountPath: "/var/run/secrets/kubernetes.io/dockerconfigjson", secretName: "local-registry")
10 | ]) {
11 | node("jnlp") {
12 | stage("SETUP: Create build files") {
13 | testingNamespace = sh(script: "cat /var/run/secrets/kubernetes.io/serviceaccount/namespace", returnStdout: true)
14 |
15 | openshift.withCluster() {
16 | openshift.withProject("openshift") {
17 | def imageStream = openshift.selector("is", "jenkins")
18 | dockerRegistry = sh(returnStdout: true, script: "echo '${imageStream.object().status.dockerImageRepository}' | cut -d '/' -f1").trim()
19 | }
20 | }
21 |
22 | openshift.withCluster() {
23 | openshift.withProject() {
24 | def buildConfig = openshift.selector("bc", "sample-build")
25 | if (!buildConfig.exists()) {
26 | openshift.apply("-f", "https://raw.githubusercontent.com/openshift/origin/v3.11.0/test/extended/testdata/builds/test-build.yaml")
27 | }
28 |
29 | try {
30 | def patch = '{"apiVersion":"build.openshift.io/v1","kind":"BuildConfig","metadata":{"name":"sample-build"},"spec":{"output":{"to":{"kind":"ImageStreamTag","name":"sample-build:latest"}}}}'
31 | openshift.patch(buildConfig.object(), "'" + patch + "'")
32 | } catch(ex) {
33 | echo "Ignoring patch error: ${ex}"
34 | }
35 |
36 | def buildConfigObject = buildConfig.object()
37 | firstBuildVersion = buildConfigObject.status?.lastVersion
38 |
39 | def imageStream = openshift.selector("is", "sample-build")
40 | if (!imageStream.exists()) {
41 | openshift.create("imagestream", "sample-build")
42 | }
43 | }
44 | }
45 |
46 | dir("target") {
47 | writeFile file: "HelloWorld.txt", text: "HelloWorld"
48 | }
49 |
50 | openshift.logLevel(10)
51 | }
52 |
53 | stage("TEST: Can build and tag") {
54 | buildAndTag([
55 | imageName : "sample-build",
56 | fromFilePath : "${WORKSPACE}/target/",
57 | registryFQDN : "${dockerRegistry}",
58 | imageNamespace: "${testingNamespace}",
59 | imageVersion : "v2"
60 | ])
61 | }
62 |
63 | stage("ASSERT") {
64 | openshift.withCluster() {
65 | openshift.withProject() {
66 | def build = openshift.selector("build", "sample-build-${firstBuildVersion + 1}")
67 | assert build.exists()
68 |
69 | def imageStream = openshift.selector("is", "sample-build")
70 | imageStream.untilEach(1) {
71 | return it.object().status?.tags?.size() == 2
72 | }
73 | }
74 | }
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-clusterCredentials:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | def credentials
5 |
6 | node("maven") {
7 | stage("SETUP: Create secret") {
8 | def secret = """
9 | kind: Secret
10 | apiVersion: v1
11 | metadata:
12 | name: cluster-credential
13 | type: Opaque
14 | stringData:
15 | api: openshift.com:8443
16 | token: YmxhaAo=
17 | """
18 |
19 | writeFile file: "secret-example.yml", text: secret
20 |
21 | openshift.withCluster() {
22 | openshift.withProject() {
23 | openshift.apply("-f", "secret-example.yml")
24 | }
25 | }
26 |
27 | openshift.logLevel(10)
28 | }
29 |
30 | stage("TEST: Can get credential") {
31 | credentials = clusterCredentials([
32 | secretName: "cluster-credential"
33 | ])
34 | }
35 |
36 | stage("ASSERT") {
37 | assert credentials != null
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-clusterCredentials-fail-missingsecret:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("maven") {
5 | stage("SETUP: Set logging to verbose") {
6 | openshift.logLevel(10)
7 | }
8 |
9 | stage("TEST: Can get credential and fail") {
10 | credentials = clusterCredentials([
11 | secretName: "doesnt-exist"
12 | ])
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-configMap:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | def configMapData
5 |
6 | node("maven") {
7 | stage("SETUP: Create configmap") {
8 | def configMap = """
9 | apiVersion: v1
10 | kind: ConfigMap
11 | metadata:
12 | name: game-config
13 | data:
14 | game.properties: |
15 | enemies=aliens
16 | """
17 |
18 | writeFile file: "configmap-example.yml", text: configMap
19 |
20 | openshift.withCluster() {
21 | openshift.withProject() {
22 | openshift.apply("-f", "configmap-example.yml")
23 | }
24 | }
25 |
26 | openshift.logLevel(10)
27 | }
28 |
29 | stage("TEST: Can get configmap data") {
30 | configMapData = configMap([
31 | configMapName: "game-config"
32 | ])
33 | }
34 |
35 | stage("ASSERT") {
36 | assert configMapData != null
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-configMap-fail-missingconfigmap:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("maven") {
5 | stage("SETUP: Set logging to verbose") {
6 | openshift.logLevel(10)
7 | }
8 |
9 | stage("TEST: Can get configmap data and fail") {
10 | configMapData = configMap([
11 | configMapName: "doesnt-exist"
12 | ])
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-crossClusterPromote:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | def promotionNamespace
5 | def testingNamespace
6 |
7 | node("jenkins-slave-image-mgmt") {
8 | stage("SETUP: Check imagestream doesnt exist") {
9 | testingNamespace = sh(script: "cat /var/run/secrets/kubernetes.io/serviceaccount/namespace", returnStdout: true)
10 | promotionNamespace = testingNamespace + '-promotion-testing'
11 |
12 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'pipelinelib-testing-my-token', usernameVariable: 'USERNAME', passwordVariable: 'TOKEN']]) {
13 | openshift.withCluster("https://kubernetes.default.svc", "${TOKEN}") {
14 | try {
15 | openshift.newProject(promotionNamespace)
16 | } catch(ex) {
17 | echo "Ignoring new-project error: ${ex}"
18 | }
19 |
20 | openshift.withProject(promotionNamespace) {
21 | def imageStream = openshift.selector("is", "jenkins-slave-ansible")
22 | if (imageStream.exists()) {
23 | imageStream.delete()
24 | }
25 | }
26 | }
27 | }
28 |
29 | openshift.logLevel(10)
30 | }
31 |
32 | stage("TEST: Can promote image from one project to another") {
33 | crossClusterPromote([
34 | sourceImageName : "jenkins-slave-ansible",
35 | sourceImagePath : "${testingNamespace}",
36 | destinationImagePath : "${promotionNamespace}",
37 | targetRegistryCredentials: "local-registry-generic"
38 | ])
39 | }
40 |
41 | stage("ASSERT") {
42 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'pipelinelib-testing-my-token', usernameVariable: 'USERNAME', passwordVariable: 'TOKEN']]) {
43 | openshift.withCluster("https://kubernetes.default.svc", "${TOKEN}") {
44 | openshift.withProject(promotionNamespace) {
45 | def imageStream = openshift.selector("is", "jenkins-slave-ansible")
46 | assert imageStream.exists()
47 | }
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-crossClusterPromote-fail-missingsecret:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("jenkins-slave-image-mgmt") {
5 | stage("SETUP: Set logging to verbose") {
6 | openshift.logLevel(10)
7 | }
8 |
9 | stage("TEST: Can promote image from one project to another and fail") {
10 | crossClusterPromote([
11 | sourceImageName : "jenkins-slave-ansible",
12 | sourceImagePath : "pipelinelib-testing",
13 | destinationImagePath : "pipelinelib-promotion-testing",
14 | targetRegistryCredentials: "doesnt-exist"
15 | ])
16 | }
17 | }
--------------------------------------------------------------------------------
/test/Jenkinsfile-patchBuildConfigOutputLabels:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("maven") {
5 | stage("SETUP: Create build files") {
6 | openshift.withCluster() {
7 | openshift.withProject() {
8 | def buildConfig = openshift.selector("bc", "sample-verbose-build")
9 | if (!buildConfig.exists()) {
10 | openshift.apply("-f", "https://raw.githubusercontent.com/openshift/origin/v3.11.0/test/extended/testdata/builds/test-build.yaml")
11 | }
12 | }
13 | }
14 |
15 | openshift.logLevel(10)
16 | }
17 |
18 | stage("TEST: Can patch build config") {
19 | patchBuildConfigOutputLabels([
20 | bcName : "sample-verbose-build",
21 | domainPrefix: "org.example"
22 | ])
23 | }
24 |
25 | stage("ASSERT") {
26 | openshift.withCluster() {
27 | openshift.withProject() {
28 | def buildConfig = openshift.selector("bc", "sample-verbose-build")
29 | assert buildConfig.exists()
30 |
31 | def imageLabels = buildConfig.object().spec.output?.imageLabels
32 | assert imageLabels != null
33 | }
34 | }
35 | }
36 | }
--------------------------------------------------------------------------------
/test/Jenkinsfile-rollback:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | def firstDeploymentVersion
5 |
6 | node("maven") {
7 | stage("SETUP: Create deployment files") {
8 | openshift.withCluster() {
9 | openshift.withProject() {
10 | def model = openshift.process("https://raw.githubusercontent.com/openshift/origin/v3.11.0/examples/quickstarts/cakephp-mysql.json", "-p NAME=rollback", "-p DATABASE_SERVICE_NAME=rollback")
11 | openshift.apply(model)
12 |
13 | openshift.selector("bc", "rollback").startBuild("--wait")
14 |
15 | def deployment = openshift.selector("dc", "rollback")
16 | deployment.rollout().status("--watch=true")
17 |
18 | firstDeploymentVersion = deployment.object().status.latestVersion
19 |
20 | def patch = '{"apiVersion":"apps.openshift.io/v1","kind":"DeploymentConfig","metadata":{"name":"rollback"},"spec":{"template":{"metadata":{"labels":{"version":"v2"}}}}}'
21 | openshift.patch(deployment.object(), "'" + patch + "'")
22 |
23 | //Wait for v2
24 | deployment.rollout().status("--watch=true")
25 | }
26 | }
27 |
28 | openshift.logLevel(10)
29 | }
30 |
31 | stage("TEST: Can rollback to earlier version") {
32 | rollback([
33 | resourceKindAndName: "dc/rollback"
34 | ])
35 | }
36 |
37 | stage("ASSERT") {
38 | openshift.withCluster() {
39 | openshift.withProject() {
40 | def deployment = openshift.selector("dc", "rollback")
41 | deployment.rollout().status("--watch=true")
42 |
43 | def first = openshift.selector("rc", "rollback-${firstDeploymentVersion}")
44 | assert first.exists()
45 | assert first.object().spec.template.metadata.labels.version == null
46 |
47 | def second = openshift.selector("rc", "rollback-${firstDeploymentVersion + 1}")
48 | assert second.exists()
49 | assert second.object().spec.template.metadata.labels.version == "v2"
50 |
51 | def third = openshift.selector("rc", "rollback-${firstDeploymentVersion + 2}")
52 | assert third.exists()
53 | assert third.object().spec.template.metadata.labels.version == null
54 |
55 | //Scale down afterwards to lower quotas
56 | deployment.scale("--replicas=0")
57 | }
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/test/Jenkinsfile-rollback-fail-missingdc:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("maven") {
5 | stage("SETUP: Set logging to verbose") {
6 | openshift.logLevel(10)
7 | }
8 |
9 | stage("TEST: Can rollback to earlier version and fail") {
10 | rollback([
11 | resourceKindAndName: "dc/doesnt-exist"
12 | ])
13 | }
14 | }
--------------------------------------------------------------------------------
/test/Jenkinsfile-rollout:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | def firstDeploymentVersion
5 |
6 | node("maven") {
7 | stage("SETUP: Create deployment files") {
8 | openshift.withCluster() {
9 | openshift.withProject() {
10 | def model = openshift.process("https://raw.githubusercontent.com/openshift/origin/v3.11.0/examples/quickstarts/cakephp-mysql.json", "-p NAME=rollout", "-p DATABASE_SERVICE_NAME=rollout")
11 | openshift.apply(model)
12 |
13 | openshift.selector("bc", "rollout").startBuild("--wait")
14 |
15 | def deployment = openshift.selector("dc", "rollout")
16 | deployment.rollout().status("--watch=true")
17 |
18 | firstDeploymentVersion = deployment.object().status.latestVersion
19 | }
20 | }
21 |
22 | openshift.logLevel(10)
23 | }
24 |
25 | stage("TEST: Can rollout to latest version") {
26 | rollout([
27 | resourceKindAndName: "dc/rollout"
28 | ])
29 | }
30 |
31 | stage("ASSERT") {
32 | openshift.withCluster() {
33 | openshift.withProject() {
34 | def nextRcNumber = firstDeploymentVersion + 1
35 |
36 | def deployment = openshift.selector("dc", "rollout")
37 | assert deployment.object().status.latestVersion == nextRcNumber
38 |
39 | def rc = openshift.selector("rc", "rollout-${nextRcNumber}")
40 | assert rc.exists()
41 |
42 | //Scale down afterwards to lower quotas
43 | deployment.scale("--replicas=0")
44 | }
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-rollout-deployment:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("maven") {
5 | stage("SETUP: Create deployment files") {
6 | openshift.withCluster() {
7 | openshift.withProject() {
8 | openshift.apply("-f", "https://raw.githubusercontent.com/kubernetes/examples/master/guestbook/all-in-one/guestbook-all-in-one.yaml")
9 |
10 | openshift.patch(openshift.selector("deployment", "redis-master").object(), "'{\"spec\":{\"replicas\":0}}'")
11 | openshift.patch(openshift.selector("deployment", "redis-slave").object(), "'{\"spec\":{\"replicas\":1}}'")
12 | openshift.patch(openshift.selector("deployment", "frontend").object(), "'{\"spec\":{\"replicas\":0}}'")
13 | }
14 | }
15 |
16 | openshift.logLevel(10)
17 | }
18 |
19 | stage("TEST: Can rollout a k8s deployment") {
20 | rollout([
21 | resourceKindAndName: "deployment/redis-slave",
22 | latest: false
23 | ])
24 | }
25 |
26 | stage("ASSERT") {
27 | openshift.withCluster() {
28 | openshift.withProject() {
29 | def deployment = openshift.selector("deployment", "redis-slave")
30 | assert deployment.object().status.availableReplicas == 1
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-rollout-fail-loghistory:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("maven") {
5 | stage("SETUP: Create deployment files") {
6 | openshift.withCluster() {
7 | openshift.withProject() {
8 | def model = openshift.process("https://raw.githubusercontent.com/openshift/origin/v3.11.0/examples/quickstarts/cakephp-mysql.json", "-p NAME=rollout-fail-loghistory", "-p DATABASE_SERVICE_NAME=rollout-fail-loghistory")
9 | openshift.apply(model)
10 |
11 | openshift.patch(openshift.selector("dc", "rollout-fail-loghistory").object(), "'{\"spec\":{\"strategy\":{\"recreateParams\":{\"timeoutSeconds\":60}},\"template\":{\"spec\":{\"containers\":[{\"name\":\"mysql\",\"env\":null}]}}}}'")
12 | openshift.selector("dc", "rollout-fail-loghistory").rollout().cancel()
13 |
14 | //HACK: Wait for the deployment to stop
15 | sh "sleep 5"
16 | }
17 | }
18 | }
19 |
20 | stage("TEST: Can rollout to latest version and fail with history printed") {
21 | rollout([
22 | deploymentConfigName: "rollout-fail-loghistory"
23 | ])
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-rollout-fail-missingdc:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("maven") {
5 | stage("SETUP: Set logging to verbose") {
6 | openshift.logLevel(10)
7 | }
8 |
9 | stage("TEST: Can rollout to latest version and fail") {
10 | rollout([
11 | resourceKindAndName: "dc/doesnt-exist"
12 | ])
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-sonarqubeStaticAnalysis:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | def jenkinsUrl
5 | def sonarqubeNamespace
6 |
7 | node("jenkins-slave-ansible") {
8 | stage("SETUP: Deploy sonarqube via applier") {
9 | sonarqubeNamespace = sh(script: "cat /var/run/secrets/kubernetes.io/serviceaccount/namespace", returnStdout: true) + '-sonarqube'
10 |
11 | sh "git clone https://github.com/redhat-cop/containers-quickstarts.git"
12 |
13 | openshift.withCluster() {
14 | openshift.withProject() {
15 | def jenkinsRoute = openshift.selector("route", "jenkins")
16 | jenkinsUrl = "https://" + jenkinsRoute.object().spec?.host
17 | }
18 | }
19 |
20 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'pipelinelib-testing-my-token', usernameVariable: 'USERNAME', passwordVariable: 'TOKEN']]) {
21 | applier([
22 | inventoryPath : ".applier/hosts",
23 | requirementsPath : "requirements.yml",
24 | ansibleRootDir : "${WORKSPACE}/containers-quickstarts/sonarqube",
25 | applierPlaybook : "galaxy/openshift-applier/playbooks/openshift-cluster-seed.yml",
26 | playbookAdditionalArgs: "-e jenkins_url=${jenkinsUrl} -e namespace=${sonarqubeNamespace}",
27 | clusterAPI : "https://kubernetes.default.svc",
28 | clusterToken : "${TOKEN}"
29 | ])
30 | }
31 |
32 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'pipelinelib-testing-my-token', usernameVariable: 'USERNAME', passwordVariable: 'TOKEN']]) {
33 | openshift.withCluster("https://kubernetes.default.svc", "${TOKEN}") {
34 | openshift.withProject(sonarqubeNamespace) {
35 | def dbDeployment = openshift.selector("dc", "sonardb")
36 | dbDeployment.rollout().status("--watch=true")
37 |
38 | def sonarDeployment = openshift.selector("dc", "sonarqube")
39 |
40 | try {
41 | def patch = '{"apiVersion":"apps.openshift.io/v1","kind":"DeploymentConfig","metadata":{"name":"sonarqube"},"spec":{"template":{"spec":{"containers":[{"name":"sonarqube","livenessProbe":{"initialDelaySeconds":180},"readinessProbe":{"initialDelaySeconds":180}}]}}}}'
42 | openshift.patch(sonarDeployment.object(), "'" + patch + "'")
43 | } catch (ex) {
44 | echo "Ignoring patch error: ${ex}"
45 | }
46 |
47 | //Can be very flaky when following out..
48 | retry(3) {
49 | try {
50 | sonarDeployment.rollout().status("--watch=true")
51 | } catch(ex) {
52 | sonarDeployment.rollout().latest()
53 |
54 | error "Ignoring rollout error: ${ex}"
55 | }
56 | }
57 | }
58 | }
59 | }
60 | }
61 |
62 | stage("SETUP: Configure sonarqube") {
63 | sh """git clone https://github.com/redhat-cop/pipeline-library.git"""
64 |
65 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'pipelinelib-testing-my-token', usernameVariable: 'USERNAME', passwordVariable: 'TOKEN']]) {
66 | openshift.withCluster("https://kubernetes.default.svc", "${TOKEN}") {
67 | openshift.withProject(sonarqubeNamespace) {
68 | def route = openshift.selector("route", "sonarqube")
69 | def sonarUrl = "https://" + route.object().spec?.host
70 |
71 | writeFile file: "token.json", text: sh(returnStdout: true, script: "curl --insecure -L -X POST -u admin:admin ${sonarUrl}/api/user_tokens/generate?name=jenkins-b${env.BUILD_NUMBER}")
72 | def sonarqubeToken = readJSON file: "token.json"
73 |
74 | sh """
75 | sed -i 's|def SONAR_URL|def SONAR_URL = "${sonarUrl}"|' ${WORKSPACE}/pipeline-library/test/create-sonarqube-installation.groovy
76 | sed -i 's|def SONAR_TOKEN|def SONAR_TOKEN = "${sonarqubeToken.token}"|' ${WORKSPACE}/pipeline-library/test/create-sonarqube-installation.groovy
77 |
78 | curl --insecure --header "Authorization: Bearer ${TOKEN}" --data-urlencode "script=\$(< ${WORKSPACE}/pipeline-library/test/create-sonarqube-installation.groovy)" ${jenkinsUrl}/scriptText
79 | """
80 | }
81 | }
82 | }
83 | }
84 | }
85 |
86 | node("maven") {
87 | stage("TEST: Can run sonarqube static analysis") {
88 | sh """git clone https://github.com/redhat-cop/pipeline-library.git"""
89 |
90 | dir ("pipeline-library") {
91 | sonarqubeStaticAnalysis([
92 | curlOptions: "--insecure"
93 | ])
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-tagAndDeploy:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | def dockerRegistry
5 | def testingNamespace
6 |
7 | podTemplate(label: "jnlp", cloud: "openshift", inheritFrom: "jenkins-slave-image-mgmt", volumes: [
8 | secretVolume(mountPath: "/var/run/secrets/kubernetes.io/dockerconfigjson", secretName: "local-registry")
9 | ]) {
10 | node("jnlp") {
11 | stage("SETUP: Create build/deployment files") {
12 | testingNamespace = sh(script: "cat /var/run/secrets/kubernetes.io/serviceaccount/namespace", returnStdout: true)
13 | openshift.withCluster() {
14 | openshift.withProject("openshift") {
15 | def imageStream = openshift.selector("is", "jenkins")
16 | dockerRegistry = sh(returnStdout: true, script: "echo '${imageStream.object().status.dockerImageRepository}' | cut -d '/' -f1").trim()
17 | }
18 | }
19 |
20 | openshift.withCluster() {
21 | openshift.withProject() {
22 | def model = openshift.process("https://raw.githubusercontent.com/openshift/origin/v3.11.0/examples/quickstarts/cakephp-mysql.json", "-p NAME=taganddeploy", "-p DATABASE_SERVICE_NAME=taganddeploy")
23 | openshift.apply(model)
24 |
25 | openshift.selector("bc", "taganddeploy").startBuild("--wait")
26 |
27 | def imageStream = openshift.selector("is", "taganddeploy")
28 | imageStream.untilEach(1) {
29 | return it.object().status?.tags?.size() > 0
30 | }
31 |
32 | def deployment = openshift.selector("dc", "taganddeploy")
33 | deployment.rollout().status("--watch=true")
34 | }
35 | }
36 |
37 | openshift.logLevel(10)
38 | }
39 |
40 | stage("TEST: Can tag and deploy") {
41 | tagAndDeploy([
42 | registryFQDN : "${dockerRegistry}",
43 | imageNamespace : "${testingNamespace}",
44 | imageName : "taganddeploy",
45 | imageVersion : "latest",
46 | deployDestinationVersionTag : "v2",
47 | deployDestinationProjectName: "${testingNamespace}"
48 | ])
49 | }
50 |
51 | stage("ASSERT") {
52 | openshift.withCluster() {
53 | openshift.withProject() {
54 | def imageStream = openshift.selector("is", "taganddeploy")
55 | imageStream.untilEach(1) {
56 | return it.object().status?.tags?.size() == 2
57 | }
58 |
59 | //Scale down afterwards to lower quotas
60 | def deployment = openshift.selector("dc", "taganddeploy")
61 | deployment.scale("--replicas=0")
62 | }
63 | }
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-tagImage:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | def testingNamespace
5 |
6 | node("maven") {
7 | stage("SETUP: Resolve namespace") {
8 | testingNamespace = sh(script: "cat /var/run/secrets/kubernetes.io/serviceaccount/namespace", returnStdout: true)
9 | }
10 |
11 | stage("TEST: Can tag image") {
12 | tagImage([
13 | sourceImagePath: "openshift",
14 | sourceImageName: "jenkins",
15 | sourceImageTag : "2",
16 | toImagePath : "${testingNamespace}",
17 | toImageName : "tagimage",
18 | toImageTag : "2"
19 | ])
20 | }
21 |
22 | stage("ASSERT") {
23 | openshift.withCluster() {
24 | openshift.withProject() {
25 | def imageStream = openshift.selector("is", "tagimage")
26 | imageStream.untilEach(1) {
27 | return it.object().status?.tags?.size() == 1
28 | }
29 | }
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/test/Jenkinsfile-verifyDeployment:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("maven") {
5 | stage("SETUP: Create deployment files") {
6 | openshift.withCluster() {
7 | openshift.withProject() {
8 | def model = openshift.process("https://raw.githubusercontent.com/openshift/origin/v3.11.0/examples/quickstarts/cakephp-mysql.json", "-p NAME=verifydeployment", "-p DATABASE_SERVICE_NAME=verifydeployment")
9 | openshift.apply(model)
10 | }
11 | }
12 |
13 | openshift.logLevel(10)
14 | }
15 |
16 | stage("TEST: Can verify deployment") {
17 | verifyDeployment([
18 | targetApp: "verifydeployment"
19 | ])
20 | }
21 |
22 | stage("ASSERT") {
23 | openshift.withCluster() {
24 | openshift.withProject() {
25 | def deployment = openshift.selector("dc", "verifydeployment")
26 | deployment.rollout().status("--watch=true")
27 |
28 | //Scale down afterwards to lower quotas
29 | deployment.scale("--replicas=0")
30 | }
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/test/Jenkinsfile-verifyDeployment-fail-viacrashloop:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("maven") {
5 | stage("SETUP: Create deployment files") {
6 | openshift.withCluster() {
7 | openshift.withProject() {
8 | def model = openshift.process("https://raw.githubusercontent.com/openshift/origin/v3.11.0/examples/quickstarts/cakephp-mysql.json", "-p NAME=verifydeployment-fail-viacrashloop", "-p DATABASE_SERVICE_NAME=verifydeployment-fail-viacrashloop")
9 | openshift.apply(model)
10 |
11 | openshift.patch(openshift.selector("dc", "verifydeployment-fail-viacrashloop").object(), "'{\"spec\":{\"template\":{\"spec\":{\"containers\":[{\"name\":\"mysql\",\"env\":null}]}}}}'")
12 |
13 | //HACK: Wait for the deployment to be trigger
14 | sh "sleep 5"
15 | }
16 | }
17 | }
18 |
19 | stage("TEST: Can verify deployment and fail with due to crashloopbackoff") {
20 | verifyDeployment([
21 | targetApp: "verifydeployment-fail-viacrashloop"
22 | ])
23 | }
24 | }
--------------------------------------------------------------------------------
/test/Jenkinsfile-verifyService:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("maven") {
5 | stage("SETUP: Create deployment files") {
6 | openshift.withCluster() {
7 | openshift.withProject() {
8 | def model = openshift.process("https://raw.githubusercontent.com/openshift/origin/v3.11.0/examples/quickstarts/cakephp-mysql.json", "-p NAME=verifyservice", "-p DATABASE_SERVICE_NAME=verifyservice")
9 | openshift.apply(model)
10 |
11 | def deployment = openshift.selector("dc", "verifyservice")
12 | deployment.rollout().status("--watch=true")
13 | }
14 | }
15 |
16 | openshift.logLevel(10)
17 | }
18 |
19 | stage("TEST: Can verify service") {
20 | verifyService([
21 | serviceName: "verifyservice"
22 | ])
23 | }
24 |
25 | stage("ASSERT") {
26 | openshift.withCluster() {
27 | openshift.withProject() {
28 | def deployment = openshift.selector("dc", "verifyservice")
29 |
30 | sh "curl -L http://verifyservice:3306"
31 |
32 | //Scale down afterwards to lower quotas
33 | deployment.scale("--replicas=0")
34 | }
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/test/Jenkinsfile-verifyService-fail-nopods:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | node("maven") {
5 | stage("SETUP: Create deployment files") {
6 | openshift.withCluster() {
7 | openshift.withProject() {
8 | def model = openshift.process("https://raw.githubusercontent.com/openshift/origin/v3.11.0/examples/quickstarts/cakephp-mysql.json", "-p NAME=verifyservice-fail-nopods", "-p DATABASE_SERVICE_NAME=verifyservice-fail-nopods")
9 | openshift.apply(model)
10 |
11 | def deployment = openshift.selector("dc", "verifyservice-fail-nopods")
12 | deployment.rollout().status("--watch=true")
13 |
14 | deployment.scale("--replicas=0")
15 | }
16 | }
17 |
18 | openshift.logLevel(10)
19 | }
20 |
21 | stage("TEST: Can verify service and fail due to no pods behind service") {
22 | verifyService([
23 | serviceName: "verifyservice-fail-nopods"
24 | ])
25 | }
26 | }
--------------------------------------------------------------------------------
/test/create-pipeline-library.groovy:
--------------------------------------------------------------------------------
1 | import hudson.model.*
2 | import jenkins.model.*
3 | import jenkins.plugins.git.GitSCMSource
4 | import org.jenkinsci.plugins.workflow.libs.GlobalLibraries
5 | import org.jenkinsci.plugins.workflow.libs.LibraryConfiguration
6 | import org.jenkinsci.plugins.workflow.libs.SCMSourceRetriever
7 |
8 | final Jenkins jenkins = Jenkins.getInstance()
9 |
10 | GitSCMSource librarySource = new GitSCMSource("pipeline-library", "https://github.com/redhat-cop/pipeline-library.git", "", "*", "", true)
11 |
12 | LibraryConfiguration config = new LibraryConfiguration("pipeline-library", new SCMSourceRetriever(librarySource))
13 | config.setAllowVersionOverride(true)
14 | config.setImplicit(false)
15 | config.setDefaultVersion("master")
16 |
17 | List configurations = new ArrayList()
18 | configurations.add(config)
19 |
20 | GlobalLibraries globalLibraries = GlobalLibraries.get()
21 | globalLibraries.setLibraries(configurations)
22 |
23 | jenkins.save()
--------------------------------------------------------------------------------
/test/create-sonarqube-installation.groovy:
--------------------------------------------------------------------------------
1 | import jenkins.model.*
2 | import hudson.model.*
3 | import hudson.plugins.sonar.*
4 | import hudson.tools.*
5 | import hudson.util.Secret
6 | import com.cloudbees.plugins.credentials.impl.*
7 | import com.cloudbees.plugins.credentials.*
8 | import com.cloudbees.plugins.credentials.domains.*
9 | import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl
10 |
11 | def instance = Jenkins.getInstance()
12 |
13 | def SONAR_URL
14 | def SONAR_TOKEN
15 |
16 | def stringCredentials = new StringCredentialsImpl(CredentialsScope.GLOBAL, "sonartoken", null, Secret.fromString("${SONAR_TOKEN}"))
17 |
18 | SystemCredentialsProvider systemCredentialsProvider = SystemCredentialsProvider.getInstance()
19 | systemCredentialsProvider.getStore().addCredentials(Domain.global(), stringCredentials)
20 | systemCredentialsProvider.save()
21 |
22 | SonarInstallation sonarInstallation = new SonarInstallation("sonar", "${SONAR_URL}", "sonartoken", null, null, null, null, null, null)
23 |
24 | SonarGlobalConfiguration sonarGlobalConfiguration = instance.getDescriptor(SonarGlobalConfiguration.class)
25 | sonarGlobalConfiguration.setInstallations(sonarInstallation)
26 | sonarGlobalConfiguration.migrateCredentials()
27 | sonarGlobalConfiguration.save()
28 |
29 | instance.save()
--------------------------------------------------------------------------------
/test/disabled-imageMirror:
--------------------------------------------------------------------------------
1 | #!groovy
2 | @Library(["pipeline-library@master"]) _
3 |
4 | def dockerRegistry
5 | def promotionNamespace
6 | def testingNamespace
7 |
8 | node("maven") {
9 | stage("SETUP: Check imagestream doesnt exist") {
10 | openshift.withCluster() {
11 | testingNamespace = sh(script: "cat /var/run/secrets/kubernetes.io/serviceaccount/namespace", returnStdout: true)
12 | promotionNamespace = testingNamespace + '-promotion-testing'
13 |
14 | openshift.withProject("openshift") {
15 | def imageStream = openshift.selector("is", "jenkins")
16 | dockerRegistry = sh(returnStdout: true, script: "echo '${imageStream.object().status.dockerImageRepository}' | cut -d '/' -f1").trim()
17 | }
18 | }
19 |
20 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'pipelinelib-testing-my-token', usernameVariable: 'USERNAME', passwordVariable: 'TOKEN']]) {
21 | openshift.withCluster("https://kubernetes.default.svc", "${TOKEN}") {
22 | try {
23 | openshift.newProject(promotionNamespace)
24 | } catch(ex) {
25 | echo "Ignoring new-project error: ${ex}"
26 | }
27 |
28 | openshift.withProject(promotionNamespace) {
29 | def imageStream = openshift.selector("is", "jenkins-slave-image-mgmt")
30 | if (imageStream.exists()) {
31 | imageStream.delete()
32 | }
33 | }
34 | }
35 | }
36 |
37 | openshift.logLevel(10)
38 | }
39 |
40 | stage("TEST: Can promote image from one project to another") {
41 | imageMirror([
42 | sourceSecret : "pipelinelib-testing-my-token",
43 | sourceRegistry : "https://${dockerRegistry}",
44 | destinationSecret : "pipelinelib-testing-my-token",
45 | destinationRegistry : "https://${dockerRegistry}",
46 | insecure : "true",
47 | sourceNamespace : "${testingNamespace}",
48 | destinationNamespace : "${promotionNamespace}",
49 | sourceImage : "jenkins-slave-image-mgmt",
50 | sourceImageVersion : "latest",
51 | destinationImageVersion: "latest"
52 | ])
53 | }
54 |
55 | stage("ASSERT") {
56 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'pipelinelib-testing-my-token', usernameVariable: 'USERNAME', passwordVariable: 'TOKEN']]) {
57 | openshift.withCluster("https://kubernetes.default.svc", "${TOKEN}") {
58 | openshift.withProject(promotionNamespace) {
59 | def imageStream = openshift.selector("is", "jenkins-slave-image-mgmt")
60 | imageStream.untilEach(1) {
61 | return it.object().status?.tags?.size() == 1
62 | }
63 | }
64 | }
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/test/org/redhatcop/util/end-to-end/Jenkinsfile:
--------------------------------------------------------------------------------
1 | library identifier: "pipeline-library@master", retriever: modernSCM(
2 | [$class: "GitSCMSource",
3 | remote: "https://github.com/redhat-cop/pipeline-library.git"])
4 |
5 | pipeline {
6 | // Use Jenkins Maven slave
7 | // Jenkins will dynamically provision this as OpenShift Pod
8 | // All the stages and steps of this Pipeline will be executed on this Pod
9 | // After Pipeline completes the Pod is killed so every run will have clean
10 | // workspace
11 | agent {
12 | label 'maven'
13 | }
14 |
15 | // Pipeline Stages start here
16 | // Requeres at least one stage
17 | stages {
18 |
19 | // Checkout source code
20 | // This is required as Pipeline code is originally checkedout to
21 | // Jenkins Master but this will also pull this same code to this slave
22 | stage('Git Checkout') {
23 | steps {
24 | // Turn off Git's SSL cert check, uncomment if needed
25 | // sh 'git config --global http.sslVerify false'
26 | git url: "${SOURCE_CODE_URL}"
27 | }
28 | }
29 |
30 | // Run Maven build, skipping tests
31 | stage('Build'){
32 | steps {
33 | sh "mvn clean install -q"
34 | }
35 | }
36 |
37 | // Build Container Image using the artifacts produced in previous stages
38 | stage('Build Container Image'){
39 | steps {
40 | binaryBuild(projectName: "pipeline-library-dev", buildConfigName: "spring-rest", artifactsDirectoryName: "target")
41 | }
42 | }
43 |
44 | stage ('Verify Deployment to Dev') {
45 | steps {
46 | verifyDeployment(projectName: "pipeline-library-dev", targetApp: "spring-rest")
47 | }
48 | }
49 |
50 | stage('Promote image') {
51 | steps {
52 | tagImage(sourceImagePath: "pipeline-library-dev", sourceImageName: "spring-rest", toImagePath: "pipeline-library-test")
53 | }
54 | }
55 |
56 | stage ('Verify Deployment to test') {
57 | steps {
58 | verifyDeployment(projectName: "pipeline-library-test", targetApp: "spring-rest")
59 | }
60 | }
61 |
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/test/org/redhatcop/util/end-to-end/README.md:
--------------------------------------------------------------------------------
1 | # Testing the generic vars
2 |
3 | This directory contains a test inventory for testing the generic vars -files in OpenShift. It requires [openshift-applier](https://github.com/redhat-cop/openshift-applier.git) to test. This can be pulled in via ansible-galaxy.
4 |
5 | ## Dependencies
6 | [redhat-openjdk-18/openjdk18-openshift](https://access.redhat.com/containers/?tab=overview#/registry.access.redhat.com/redhat-openjdk-18/openjdk18-openshift) is needed in the `openshift` project to build the test app. Add the image to your `openshift` project: `oc import-image openshift/openjdk18-openshift --from=registry.access.redhat.com/redhat-openjdk-18/openjdk18-openshift --confirm`
7 |
8 | ## Steps to test
9 |
10 | 1. Pull in dependencies at root of this git repository.
11 | ```
12 | ansible-galaxy install -r requirements.yml -p deps
13 | ```
14 | 2. Run ansible under the test directory.
15 | ```
16 | ansible-playbook -i test/org/redhatcop/util/end-to-end/inventory/ deps/openshift-applier/playbooks/openshift-cluster-seed.yml
17 | ```
18 |
--------------------------------------------------------------------------------
/test/org/redhatcop/util/end-to-end/files/params/build:
--------------------------------------------------------------------------------
1 | NAMESPACE=pipeline-library-dev
2 | PIPELINE_REPOSITORY_URL=https://github.com/redhat-cop/pipeline-library.git
3 | PIPELINE_REPOSITORY_REF=master
4 | CONTEXT_DIR=test/org/redhatcop/util/end-to-end
--------------------------------------------------------------------------------
/test/org/redhatcop/util/end-to-end/files/params/deploy-dev:
--------------------------------------------------------------------------------
1 | APPLICATION_NAME=spring-rest
2 | NAMESPACE=pipeline-library-dev
3 | SA_NAMESPACE=pipeline-library-dev
4 | READINESS_RESPONSE=status.:.UP
5 | READINESS_PATH=/health
--------------------------------------------------------------------------------
/test/org/redhatcop/util/end-to-end/files/params/deploy-test:
--------------------------------------------------------------------------------
1 | APPLICATION_NAME=spring-rest
2 | NAMESPACE=pipeline-library-test
3 | SA_NAMESPACE=pipeline-library-dev
4 | READINESS_RESPONSE=status.:.UP
5 | READINESS_PATH=/health
--------------------------------------------------------------------------------
/test/org/redhatcop/util/end-to-end/files/params/jenkins-deployment:
--------------------------------------------------------------------------------
1 | NAMESPACE=pipeline-library-dev
2 | JENKINS_IMAGE_STREAM_TAG=jenkins2-s2i:latest
--------------------------------------------------------------------------------
/test/org/redhatcop/util/end-to-end/files/params/jenkins-s2i:
--------------------------------------------------------------------------------
1 | JENKINS_GIT_URL=https://github.com/redhat-cop/pipeline-library.git
2 | JENKINS_GIT_BRANCH=master
3 | JENKINS_GIT_CONTEXT_DIR=jenkins-s2i/
4 |
--------------------------------------------------------------------------------
/test/org/redhatcop/util/end-to-end/files/projects.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: List
3 | items:
4 | - kind: ProjectRequest
5 | apiVersion: v1
6 | metadata:
7 | name: pipeline-library-dev
8 | creationTimestam: null
9 | displayName: Pipeline Library Development Project
10 | - kind: ProjectRequest
11 | apiVersion: v1
12 | metadata:
13 | name: pipeline-library-test
14 | creationTimestam: null
15 | displayName: Pipeline Library Testing Project
--------------------------------------------------------------------------------
/test/org/redhatcop/util/end-to-end/files/templates/build.yml:
--------------------------------------------------------------------------------
1 | apiVersion: 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 | - kind: "BuildConfig"
14 | apiVersion: "v1"
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: ${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 | - apiVersion: 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 | parameters:
64 | - description: The name for the application.
65 | name: APPLICATION_NAME
66 | required: true
67 | value: spring-rest
68 | - description: The namespace to deploy into
69 | name: NAMESPACE
70 | required: true
71 | - description: Git source URI for application
72 | name: PIPELINE_REPOSITORY_URL
73 | required: true
74 | value: https://github.com/redhat-cop/pipeline-library.git
75 | - description: Git branch/tag reference
76 | name: PIPELINE_REPOSITORY_REF
77 | value: "master"
78 | - description: Path within Git project to build; empty for root project directory.
79 | name: CONTEXT_DIR
80 | value:
81 | - description: Path within Git project pointing to the pipeline run script
82 | name: PIPELINE_SCRIPT
83 | value: Jenkinsfile
84 | - description: Git source URI for application
85 | name: SOURCE_CODE_URL
86 | required: true
87 | value: https://github.com/redhat-cop/spring-rest.git
88 | - description: Git branch/tag reference
89 | name: SOURCE_CODE_REF
90 | value: "master"
91 | - description: GitHub trigger secret
92 | from: '[a-zA-Z0-9]{8}'
93 | generate: expression
94 | name: GITHUB_WEBHOOK_SECRET
95 | required: true
96 | - description: Generic build trigger secret
97 | from: '[a-zA-Z0-9]{8}'
98 | generate: expression
99 | name: GENERIC_WEBHOOK_SECRET
100 | required: true
101 | - description: Namespace in which the ImageStreams for Red Hat Middleware images are
102 | installed. These ImageStreams are normally installed in the openshift namespace.
103 | You should only need to modify this if you've installed the ImageStreams in a
104 | different namespace/project.
105 | name: IMAGE_STREAM_NAMESPACE
106 | required: true
107 | value: openshift
108 | - description: Image stream tag for the image you'd like to use to build the application
109 | name: IMAGE_STREAM_TAG_NAME
110 | required: true
111 | value: redhat-openjdk18-openshift:1.4
--------------------------------------------------------------------------------
/test/org/redhatcop/util/end-to-end/files/templates/deployment.yml:
--------------------------------------------------------------------------------
1 | apiVersion: 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
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 | application: ${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: v1
29 | id: ${APPLICATION_NAME}-http
30 | kind: Route
31 | metadata:
32 | annotations:
33 | description: Route for application's http service.
34 | labels:
35 | application: ${APPLICATION_NAME}
36 | name: ${APPLICATION_NAME}
37 | namespace: ${NAMESPACE}
38 | spec:
39 | host: ${HOSTNAME_HTTP}
40 | to:
41 | name: ${APPLICATION_NAME}
42 | - apiVersion: v1
43 | kind: ImageStream
44 | metadata:
45 | labels:
46 | application: ${APPLICATION_NAME}
47 | name: ${APPLICATION_NAME}
48 | namespace: ${NAMESPACE}
49 | - apiVersion: v1
50 | kind: DeploymentConfig
51 | metadata:
52 | labels:
53 | application: ${APPLICATION_NAME}
54 | name: ${APPLICATION_NAME}
55 | namespace: ${NAMESPACE}
56 | spec:
57 | replicas: 1
58 | selector:
59 | deploymentConfig: ${APPLICATION_NAME}
60 | strategy:
61 | type: Recreate
62 | template:
63 | metadata:
64 | labels:
65 | application: ${APPLICATION_NAME}
66 | deploymentConfig: ${APPLICATION_NAME}
67 | name: ${APPLICATION_NAME}
68 | spec:
69 | containers:
70 | - env:
71 | - name: JWS_ADMIN_USERNAME
72 | value: ${JWS_ADMIN_USERNAME}
73 | - name: JWS_ADMIN_PASSWORD
74 | value: ${JWS_ADMIN_PASSWORD}
75 | image: ${APPLICATION_NAME}
76 | imagePullPolicy: Always
77 | name: ${APPLICATION_NAME}
78 | ports:
79 | - containerPort: 8778
80 | name: jolokia
81 | protocol: TCP
82 | - containerPort: 8080
83 | name: http
84 | protocol: TCP
85 | readinessProbe:
86 | exec:
87 | command:
88 | - /bin/bash
89 | - -c
90 | - curl -s 'http://localhost:8080${READINESS_PATH}'
91 | |grep -iq '${READINESS_RESPONSE}'
92 | terminationGracePeriodSeconds: 60
93 | triggers:
94 | - imageChangeParams:
95 | automatic: true
96 | containerNames:
97 | - ${APPLICATION_NAME}
98 | from:
99 | kind: ImageStreamTag
100 | name: ${APPLICATION_NAME}:latest
101 | type: ImageChange
102 | - type: ConfigChange
103 | - apiVersion: v1
104 | groupNames: null
105 | kind: RoleBinding
106 | metadata:
107 | creationTimestamp: null
108 | labels:
109 | template: basic-tomcat-template
110 | name: jenkins_edit
111 | namespace: ${NAMESPACE}
112 | roleRef:
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: jws-app
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!'
--------------------------------------------------------------------------------
/test/org/redhatcop/util/end-to-end/inventory/group_vars/seed-hosts.yml:
--------------------------------------------------------------------------------
1 | openshift_cluster_content:
2 | - object: rollback test
3 | content:
4 | - name: create project
5 | file: "{{ inventory_dir }}/../files/projects.yml"
6 | action: create
7 | - name: build jenkins image
8 | template: "{{ inventory_dir }}/../../../../../../jenkins-s2i/jenkins-s2i.yml"
9 | params: "{{ inventory_dir }}/../files/params/jenkins-s2i"
10 | namespace: pipeline-library-dev
11 | - name: deploy jenkins
12 | template: "openshift//jenkins-ephemeral"
13 | params: "{{ inventory_dir }}/../files/params/jenkins-deployment"
14 | namespace: pipeline-library-dev
15 | - name: test app build
16 | template: "{{ inventory_dir }}/../files/templates/build.yml"
17 | params: "{{ inventory_dir }}/../files/params/build"
18 | - name: test app deploy dev
19 | template: "{{ inventory_dir }}/../files/templates/deployment.yml"
20 | params: "{{ inventory_dir }}/../files/params/deploy-dev"
21 | - name: test app deploy test
22 | template: "{{ inventory_dir }}/../files/templates/deployment.yml"
23 | params: "{{ inventory_dir }}/../files/params/deploy-test"
--------------------------------------------------------------------------------
/test/org/redhatcop/util/end-to-end/inventory/hosts:
--------------------------------------------------------------------------------
1 | [seed-hosts]
2 | localhost ansible_connection=local
3 |
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rocketchat/Jenkinsfile:
--------------------------------------------------------------------------------
1 | /*
2 | Must create a secret in openshift project with the following:
3 | apiVersion: v1
4 | kind: Secret
5 | metadata:
6 | name: rocketchat-secret
7 | stringData:
8 | server: https://rocketchat.example.com
9 | key: somehookid
10 | secret: somehooksecret
11 | */
12 |
13 | @Library('cop-library') _
14 |
15 | podTemplate(label: 'slave-ruby', cloud: 'openshift', serviceAccount: "jenkins", containers: [
16 | containerTemplate(name: 'jnlp', image: 'docker.io/redhatcop/jenkins-slave-ruby', privileged: false, alwaysPullImage: true, workingDir: '/tmp', args: '${computer.jnlpmac} ${computer.name}', ttyEnabled: false,
17 | envVars: [
18 | secretEnvVar(key: 'ROCKETCHAT_SERVER', secretName: 'rocketchat-secret', secretKey: 'server'),
19 | secretEnvVar(key: 'ROCKETCHAT_KEY', secretName: 'rocketchat-secret', secretKey: 'key'),
20 | secretEnvVar(key: 'ROCKETCHAT_SECRET', secretName: 'rocketchat-secret', secretKey: 'secret')
21 | ]
22 | )
23 | ]) {
24 |
25 | node ('slave-ruby') {
26 | rocketchat_url = "${env.ROCKETCHAT_SERVER}/hooks/${env.ROCKETCHAT_KEY}/${env.ROCKETCHAT_SECRET}"
27 | def n = new org.redhatcop.util.notifications()
28 |
29 | stage('Test Notifications') {
30 | n.notifyBuild('STARTED', rocketchat_url)
31 | n.notifyBuild('FAILED', rocketchat_url)
32 | n.notifyBuild('SUCCESSFUL', rocketchat_url)
33 | }
34 | }
35 |
36 | }
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rocketchat/README.md:
--------------------------------------------------------------------------------
1 | # Testing the org.redhatcop.util package
2 |
3 | This directory contains a test inventory for testing the `org.redhatcop.utils` package in OpenShift. It requires [casl-ansible](https://github.com/redhat-cop/casl-ansible.git) to test. This can be pulled in via ansible-galaxy.
4 |
5 | ## Steps to test
6 |
7 | 1. Must create a rocketchat [incoming webhook integration](https://rocket.chat/docs/administrator-guides/integrations/)
8 | 2. Update files/rocketchat-secret.yml to match the webhook integration you created. The secret should look like:
9 | ```
10 | apiVersion: v1
11 | kind: Secret
12 | metadata:
13 | name: rocketchat-secret
14 | stringData:
15 | server: https://rocketchat.example.com
16 | key: somehookid
17 | secret: somehooksecret
18 | ```
19 | Where the full rocketchat URL looks like `https://rocketchat.example.com/hooks/somehookid/somehooksecret`.
20 | 3. Pull in dependencies
21 | ```
22 | ansible-galaxy install -r requirements.yml -p deps
23 | ```
24 | 4. Run ansible.
25 | ```
26 | ansible-playbook -i .test/org/redhatcop/util/inventory/ deps/casl-ansible/playbooks/openshift-cluster-seed.yml
27 | ```
28 |
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rocketchat/files/params/jenkins-deployment.params:
--------------------------------------------------------------------------------
1 | NAMESPACE=pipeline-library-test
2 | JENKINS_IMAGE_STREAM_TAG=jenkins2-s2i:latest
3 |
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rocketchat/files/params/jenkins-s2i.params:
--------------------------------------------------------------------------------
1 | JENKINS_GIT_URL=https://github.com/redhat-cop/pipeline-library.git
2 | JENKINS_GIT_BRANCH=master
3 | JENKINS_GIT_CONTEXT_DIR=jenkins-s2i/
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rocketchat/files/params/notifications-build.params:
--------------------------------------------------------------------------------
1 | APPLICATION_NAME=notifications-test
2 | NAMESPACE=pipeline-library-test
3 | SOURCE_REPOSITORY_URL=https://github.com/redhat-cop/pipeline-library.git
4 | SOURCE_REPOSITORY_REF=master
5 | CONTEXT_DIR=test/org/redhatcop/util/rocketchat
6 |
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rocketchat/files/projects.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: List
3 | items:
4 | - kind: ProjectRequest
5 | apiVersion: v1
6 | metadata:
7 | name: pipeline-library-test
8 | creationTimestam: null
9 | displayName: Pipeline Library Testing Project
10 |
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rocketchat/files/rocketchat-secret.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Secret
3 | metadata:
4 | name: rocketchat-secret
5 | namespace: pipeline-library-test
6 | stringData:
7 | server: https://rocketchat.example.com
8 | key: somehookid
9 | secret: somehooksecret
10 |
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rocketchat/files/templates/build-template.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Template
3 | labels:
4 | template: pipeline-library-test
5 | metadata:
6 | annotations:
7 | description: Application template for testing pipelines
8 | tags: jenkins,pipeline
9 | version: 1.0.0
10 | name: pipeline-library-test
11 | objects:
12 | - kind: "BuildConfig"
13 | apiVersion: "v1"
14 | metadata:
15 | labels:
16 | application: ${APPLICATION_NAME}
17 | template: pipeline-library-test
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: "Jenkinsfile"
36 | parameters:
37 | - description: The name for the application.
38 | name: APPLICATION_NAME
39 | required: true
40 | value: pipeline-test
41 | - description: The namespace to deploy into
42 | name: NAMESPACE
43 | required: true
44 | - description: Git source URI for application
45 | name: SOURCE_REPOSITORY_URL
46 | required: true
47 | value: https://github.com/redhat-cop/pipeline-library.git
48 | - description: Git branch/tag reference
49 | name: SOURCE_REPOSITORY_REF
50 | value: "master"
51 | - description: Path within Git project to build; empty for root project directory.
52 | name: CONTEXT_DIR
53 | value:
54 | - description: Path within Git project pointing to the pipeline run script
55 | name: PIPELINE_SCRIPT
56 | value: Jenkinsfile
57 | - description: GitHub trigger secret
58 | from: '[a-zA-Z0-9]{8}'
59 | generate: expression
60 | name: GITHUB_WEBHOOK_SECRET
61 | required: true
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rocketchat/inventory/group_vars/seed-hosts.yml:
--------------------------------------------------------------------------------
1 | openshift_cluster_content:
2 | - object: notifications test
3 | content:
4 | - name: create project
5 | file: "{{ inventory_dir }}/../files/projects.yml"
6 | - name: create secret
7 | file: "{{ inventory_dir }}/../files/rocketchat-secret.yml"
8 | - name: build jenkins image
9 | template: "{{ inventory_dir }}/../../../../../../jenkins-s2i/jenkins-s2i.yml"
10 | params: "{{ inventory_dir }}/../files/params/jenkins-s2i.params"
11 | namespace: pipeline-library-test
12 | - name: deploy jenkins
13 | template: "openshift//jenkins-ephemeral"
14 | params: "{{ inventory_dir }}/../files/params/jenkins-deployment.params"
15 | namespace: pipeline-library-test
16 | - name: test pipeline build
17 | template: "{{ inventory_dir }}/../files/templates/build-template.yml"
18 | params: "{{ inventory_dir }}/../files/params/notifications-build.params"
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rocketchat/inventory/hosts:
--------------------------------------------------------------------------------
1 | [seed-hosts]
2 | localhost ansible_connection=local
3 |
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rollback/Jenkinsfile:
--------------------------------------------------------------------------------
1 |
2 | @Library('cop-library') _
3 |
4 | node ('maven') {
5 | stage('Code Build') {
6 | git url: "${SOURCE_CODE_URL}"
7 | sh "mvn clean install -q"
8 | }
9 |
10 | stage('Image Build') {
11 | echo 'Building Image from Jar File'
12 | sh """
13 | set +x
14 | rm -rf oc-build && mkdir -p oc-build/deployments
15 | for t in \$(echo "jar;war;ear" | tr ";" "\\n"); do
16 | cp -rfv ./target/*.\$t oc-build/deployments/ 2> /dev/null || echo "No \$t files"
17 | done
18 | """
19 | script {
20 | openshift.withCluster() {
21 | openshift.startBuild("spring-rest", "--from-dir=oc-build", "--wait", "--follow")
22 | }
23 | }
24 | }
25 |
26 | stage ('Verify Deployment to Dev') {
27 | script {
28 | openshift.withCluster() {
29 | def dcObj = openshift.selector('dc', "spring-rest").object()
30 | def podSelector = openshift.selector('pod', [deployment: "spring-rest-${dcObj.status.latestVersion}"])
31 | podSelector.untilEach {
32 | echo "pod: ${it.name()}"
33 | return it.object().status.containerStatuses[0].ready
34 | }
35 | }
36 | }
37 | }
38 |
39 | stage('Test Rollback') {
40 | rollback(deploymentConfig: "dc/spring-rest")
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rollback/README.md:
--------------------------------------------------------------------------------
1 | # Testing the org.redhatcop.util.rollback package
2 |
3 | This directory contains a test inventory for testing the `org.redhatcop.utils.rollback` package in OpenShift. It requires [casl-ansible](https://github.com/redhat-cop/casl-ansible.git) to test. This can be pulled in via ansible-galaxy.
4 |
5 | ## Dependencies
6 | [redhat-openjdk-18/openjdk18-openshift](https://access.redhat.com/containers/?tab=overview#/registry.access.redhat.com/redhat-openjdk-18/openjdk18-openshift) is needed in the `openshift` project to build the test app. Add the image to your `openshift` project: `oc import-image openshift/openjdk18-openshift --from=registry.access.redhat.com/redhat-openjdk-18/openjdk18-openshift --confirm`
7 |
8 | ## Steps to test
9 |
10 | 1. Pull in dependencies
11 | ```
12 | ansible-galaxy install -r requirements.yml -p deps
13 | ```
14 | 2. Run ansible.
15 | ```
16 | ansible-playbook -i .test/org/redhatcop/util/rollback/inventory/ deps/casl-ansible/playbooks/openshift-cluster-seed.yml
17 | ```
18 |
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rollback/files/params/build:
--------------------------------------------------------------------------------
1 | NAMESPACE=pipeline-library-test
2 | PIPELINE_REPOSITORY_URL=https://github.com/Gl4di4torRr/pipeline-library.git
3 | PIPELINE_REPOSITORY_REF=rollback
4 | CONTEXT_DIR=test/org/redhatcop/util/rollback
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rollback/files/params/deploy:
--------------------------------------------------------------------------------
1 | APPLICATION_NAME=spring-rest
2 | NAMESPACE=pipeline-library-test
3 | SA_NAMESPACE=pipeline-library-test
4 | READINESS_RESPONSE=status.:.UP
5 | READINESS_PATH=/health
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rollback/files/params/jenkins-deployment:
--------------------------------------------------------------------------------
1 | NAMESPACE=pipeline-library-test
2 | JENKINS_IMAGE_STREAM_TAG=jenkins2-s2i:latest
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rollback/files/params/jenkins-s2i:
--------------------------------------------------------------------------------
1 | JENKINS_GIT_URL=https://github.com/redhat-cop/pipeline-library.git
2 | JENKINS_GIT_BRANCH=master
3 | JENKINS_GIT_CONTEXT_DIR=jenkins-s2i/
4 |
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rollback/files/projects.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: List
3 | items:
4 | - kind: ProjectRequest
5 | apiVersion: v1
6 | metadata:
7 | name: pipeline-library-test
8 | creationTimestam: null
9 | displayName: Pipeline Library Testing Project
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rollback/files/templates/build.yml:
--------------------------------------------------------------------------------
1 | apiVersion: 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 | - kind: "BuildConfig"
14 | apiVersion: "v1"
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: ${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 | - apiVersion: 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 | parameters:
64 | - description: The name for the application.
65 | name: APPLICATION_NAME
66 | required: true
67 | value: spring-rest
68 | - description: The namespace to deploy into
69 | name: NAMESPACE
70 | required: true
71 | - description: Git source URI for application
72 | name: PIPELINE_REPOSITORY_URL
73 | required: true
74 | value: https://github.com/redhat-cop/pipeline-library.git
75 | - description: Git branch/tag reference
76 | name: PIPELINE_REPOSITORY_REF
77 | value: "master"
78 | - description: Path within Git project to build; empty for root project directory.
79 | name: CONTEXT_DIR
80 | value:
81 | - description: Path within Git project pointing to the pipeline run script
82 | name: PIPELINE_SCRIPT
83 | value: Jenkinsfile
84 | - description: Git source URI for application
85 | name: SOURCE_CODE_URL
86 | required: true
87 | value: https://github.com/redhat-cop/spring-rest.git
88 | - description: Git branch/tag reference
89 | name: SOURCE_CODE_REF
90 | value: "master"
91 | - description: GitHub trigger secret
92 | from: '[a-zA-Z0-9]{8}'
93 | generate: expression
94 | name: GITHUB_WEBHOOK_SECRET
95 | required: true
96 | - description: Generic build trigger secret
97 | from: '[a-zA-Z0-9]{8}'
98 | generate: expression
99 | name: GENERIC_WEBHOOK_SECRET
100 | required: true
101 | - description: Namespace in which the ImageStreams for Red Hat Middleware images are
102 | installed. These ImageStreams are normally installed in the openshift namespace.
103 | You should only need to modify this if you've installed the ImageStreams in a
104 | different namespace/project.
105 | name: IMAGE_STREAM_NAMESPACE
106 | required: true
107 | value: openshift
108 | - description: Image stream tag for the image you'd like to use to build the application
109 | name: IMAGE_STREAM_TAG_NAME
110 | required: true
111 | value: openjdk18-openshift:latest
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rollback/files/templates/deployment.yml:
--------------------------------------------------------------------------------
1 | apiVersion: 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 | application: ${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: v1
29 | id: ${APPLICATION_NAME}-http
30 | kind: Route
31 | metadata:
32 | annotations:
33 | description: Route for application's http service.
34 | labels:
35 | application: ${APPLICATION_NAME}
36 | name: ${APPLICATION_NAME}
37 | namespace: ${NAMESPACE}
38 | spec:
39 | host: ${HOSTNAME_HTTP}
40 | to:
41 | name: ${APPLICATION_NAME}
42 | - apiVersion: v1
43 | kind: ImageStream
44 | metadata:
45 | labels:
46 | application: ${APPLICATION_NAME}
47 | name: ${APPLICATION_NAME}
48 | namespace: ${NAMESPACE}
49 | - apiVersion: v1
50 | kind: DeploymentConfig
51 | metadata:
52 | labels:
53 | application: ${APPLICATION_NAME}
54 | name: ${APPLICATION_NAME}
55 | namespace: ${NAMESPACE}
56 | spec:
57 | replicas: 1
58 | selector:
59 | deploymentConfig: ${APPLICATION_NAME}
60 | strategy:
61 | type: Recreate
62 | template:
63 | metadata:
64 | labels:
65 | application: ${APPLICATION_NAME}
66 | deploymentConfig: ${APPLICATION_NAME}
67 | name: ${APPLICATION_NAME}
68 | spec:
69 | containers:
70 | - env:
71 | - name: JWS_ADMIN_USERNAME
72 | value: ${JWS_ADMIN_USERNAME}
73 | - name: JWS_ADMIN_PASSWORD
74 | value: ${JWS_ADMIN_PASSWORD}
75 | image: ${APPLICATION_NAME}
76 | imagePullPolicy: Always
77 | name: ${APPLICATION_NAME}
78 | ports:
79 | - containerPort: 8778
80 | name: jolokia
81 | protocol: TCP
82 | - containerPort: 8080
83 | name: http
84 | protocol: TCP
85 | readinessProbe:
86 | exec:
87 | command:
88 | - /bin/bash
89 | - -c
90 | - curl -s 'http://localhost:8080${READINESS_PATH}'
91 | |grep -iq '${READINESS_RESPONSE}'
92 | terminationGracePeriodSeconds: 60
93 | triggers:
94 | - imageChangeParams:
95 | automatic: true
96 | containerNames:
97 | - ${APPLICATION_NAME}
98 | from:
99 | kind: ImageStreamTag
100 | name: ${APPLICATION_NAME}:latest
101 | type: ImageChange
102 | - type: ConfigChange
103 | - apiVersion: v1
104 | groupNames: null
105 | kind: RoleBinding
106 | metadata:
107 | creationTimestamp: null
108 | labels:
109 | template: basic-tomcat-template
110 | name: jenkins_edit
111 | namespace: ${NAMESPACE}
112 | roleRef:
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: jws-app
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!'
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rollback/inventory/group_vars/seed-hosts.yml:
--------------------------------------------------------------------------------
1 | openshift_cluster_content:
2 | - object: rollback test
3 | content:
4 | - name: create project
5 | file: "{{ inventory_dir }}/../files/projects.yml"
6 | - name: build jenkins image
7 | template: "{{ inventory_dir }}/../../../../../../jenkins-s2i/jenkins-s2i.yml"
8 | params: "{{ inventory_dir }}/../files/params/jenkins-s2i"
9 | namespace: pipeline-library-test
10 | - name: deploy jenkins
11 | template: "openshift//jenkins-ephemeral"
12 | params: "{{ inventory_dir }}/../files/params/jenkins-deployment"
13 | namespace: pipeline-library-test
14 | - name: test pipeline deploy
15 | template: "{{ inventory_dir }}/../files/templates/deployment.yml"
16 | params: "{{ inventory_dir }}/../files/params/deploy"
17 | - name: test pipeline build
18 | template: "{{ inventory_dir }}/../files/templates/build.yml"
19 | params: "{{ inventory_dir }}/../files/params/build"
20 |
--------------------------------------------------------------------------------
/test/org/redhatcop/util/rollback/inventory/hosts:
--------------------------------------------------------------------------------
1 | [seed-hosts]
2 | localhost ansible_connection=local
3 |
--------------------------------------------------------------------------------
/vars/applier.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | // orginial from https://github.com/redhat-cop/pipeline-library/blob/master/vars/applier.groovy
4 |
5 | class ApplierInput implements Serializable {
6 | //Required
7 | String inventoryPath = ''
8 | String requirementsPath = ''
9 | String ansibleRootDir = ''
10 | String rolesPath = 'galaxy'
11 | String applierPlaybook = 'galaxy/openshift-applier/playbooks/openshift-cluster-seed.yml'
12 |
13 | //Optional
14 | String playbookAdditionalArgs = ''
15 | String secretName = ''
16 |
17 | //Optional - Platform
18 | String clusterAPI = ''
19 | String clusterToken = ''
20 | Integer loglevel = 0
21 | }
22 |
23 | def call(Map input) {
24 | call(new ApplierInput(input))
25 | }
26 |
27 | def call(ApplierInput input) {
28 | assert input.inventoryPath?.trim() : "Param inventoryPath should be defined."
29 | assert input.requirementsPath?.trim() : "Param requirementsPath should be defined."
30 | assert input.ansibleRootDir?.trim() : "Param ansibleRootDir should be defined."
31 | assert input.rolesPath?.trim() : "Param rolesPath should be defined."
32 | assert input.applierPlaybook?.trim() : "Param applierPlaybook should be defined."
33 |
34 | openshift.loglevel(input.loglevel)
35 |
36 | def clusterAPI
37 | def clusterToken
38 |
39 | // if secretName is given then get cluster token from there
40 | // else use given clusterToken
41 | // useful to prevent loading the cluster token from secret over and over again
42 | // which can be a slow operation but also preserves backward compatibility in this function
43 | if(!input.secretName.allWhitespace) {
44 | openshift.withCluster() {
45 | def secretData = openshift.selector("secret/${input.secretName}").object().data
46 | def encodedToken = secretData.token
47 |
48 | clusterToken = sh(script:"set +x; echo ${encodedToken} | base64 --decode", returnStdout: true)
49 | clusterAPI = input.clusterAPI
50 | }
51 | } else {
52 | clusterAPI = input.clusterAPI
53 | clusterToken = input.clusterToken
54 | }
55 |
56 | openshift.withCluster(clusterAPI, clusterToken) {
57 | openshift.withProject() {
58 | openshift.raw("login")
59 |
60 | sh """
61 | pushd ${input.ansibleRootDir}
62 | ansible-galaxy install --role-file=${input.requirementsPath} --roles-path=${input.rolesPath}
63 | ansible-playbook -i ${input.inventoryPath} ${input.applierPlaybook} ${input.playbookAdditionalArgs}
64 | popd
65 | """
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/vars/applier.txt:
--------------------------------------------------------------------------------
1 | # applier
2 |
3 | ## Summary
4 |
5 | Applier executes [openshift-applier](https://github.com/redhat-cop/openshift-applier) templates on a specified cluster.
6 |
7 | ## Usage
8 |
9 | ### Requirements
10 |
11 | Requires Jenkins agent with:
12 | - OC
13 | - Ansible
14 |
15 | ### Parameters
16 |
17 | The method supports the following parameters:
18 | ```groovy
19 | // applier.groovy#L6-L20
20 |
21 | //Required
22 | String inventoryPath = ''
23 | String requirementsPath = ''
24 | String ansibleRootDir = ''
25 | String rolesPath = 'galaxy'
26 | String applierPlaybook = 'galaxy/openshift-applier/playbooks/openshift-cluster-seed.yml'
27 |
28 | //Optional
29 | String playbookAdditionalArgs = ''
30 | String secretName = ''
31 |
32 | //Optional - Platform
33 | String clusterAPI = ''
34 | String clusterToken = ''
35 | Integer loglevel = 0
36 | ```
37 |
38 | ### Example
39 |
40 | ```groovy
41 | // ../test/Jenkinsfile-applier#L11-L22
42 |
43 | stage("TEST: Run applier for 'build-s2i-executable'") {
44 | withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'pipelinelib-testing-my-token', usernameVariable: 'USERNAME', passwordVariable: 'TOKEN']]) {
45 | applier([
46 | inventoryPath : ".applier/hosts",
47 | requirementsPath: "requirements.yml",
48 | ansibleRootDir : "${WORKSPACE}/containers-quickstarts/build-s2i-executable",
49 | applierPlaybook : "galaxy/openshift-applier/playbooks/openshift-cluster-seed.yml",
50 | clusterAPI : "https://kubernetes.default.svc",
51 | clusterToken : "${TOKEN}"
52 | ])
53 | }
54 | }
55 | ```
56 |
57 | ### Local vs Remote cluster support
58 |
59 | As the underlying technology used is the [openshift-client-plugin](https://github.com/openshift/jenkins-client-plugin),
60 | the ability to connect to a the local cluster, a cluster via URL/Token or using
61 | [Jenkins configuration](https://github.com/openshift/jenkins-client-plugin#configuring-an-openshift-cluster) is as easy
62 | as setting the clusterAPI and clusterToken parameters.
63 |
64 | ### Secret Format
65 |
66 | This method supports using a secret (via secretName) which is used to login to the cluster that the applier will work against. Typically,
67 | a [service account token](https://docs.openshift.com/container-platform/3.11/dev_guide/service_accounts.html#using-a-service-accounts-credentials-externally)
68 | would be used within the secret.
69 |
70 | ```yaml
71 | ---
72 | kind: Template
73 | apiVersion: v1
74 | metadata:
75 | name: cluster-credential-secret
76 | annotations:
77 | openshift.io/display-name: Cluster Credential Secret
78 | objects:
79 | - apiVersion: v1
80 | kind: Secret
81 | metadata:
82 | name: "${NAME}"
83 | labels:
84 | credential.sync.jenkins.openshift.io: "true"
85 | type: Opaque
86 | data:
87 | api: "${API_B64}"
88 | token: "${TOKEN_B64}"
89 | parameters:
90 | - name: NAME
91 | displayName: Name
92 | description: The name of secret.
93 | required: true
94 | - name: API_B64
95 | displayName: API
96 | description: API url of the cluster the credential is for.
97 | required: true
98 | - name: TOKEN_B64
99 | displayName: Token
100 | description: Token to use when authenticating.
101 | required: true
102 | ```
--------------------------------------------------------------------------------
/vars/applyTemplate.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | class ApplyTemplateInput implements Serializable {
4 | //Required
5 | String templateFile
6 |
7 | //Optional
8 | String parameterFile
9 |
10 | //Optional - Platform
11 | String clusterUrl = ""
12 | String clusterAPI = ""
13 | String clusterToken = ""
14 | String projectName = ""
15 | Integer loglevel = 0
16 | }
17 |
18 | def call(Map input) {
19 | call(new ApplyTemplateInput(input))
20 | }
21 |
22 | def call(ApplyTemplateInput input) {
23 | assert input.templateFile?.trim() : "Param templateFile should be defined."
24 |
25 | openshift.loglevel(input.loglevel)
26 |
27 | if (input.clusterUrl?.trim().length() > 0) {
28 | error "clusterUrl is deprecated and will be removed in the next release. Please use 'clusterAPI'"
29 | }
30 |
31 | openshift.withCluster(input.clusterAPI, input.clusterToken) {
32 | openshift.withProject(input.projectName) {
33 | def fileNameArg = input.templateFile.toLowerCase().startsWith("http") ? input.templateFile : "--filename=${input.templateFile}"
34 | def parameterFileArg = input.parameterFile?.trim()?.length() <= 0 ? "" : "--param-file=${input.parameterFile}"
35 |
36 | echo "Attempting to process template '${fileNameArg}' in ${openshift.project()}"
37 |
38 | def models = openshift.process(fileNameArg, parameterFileArg, "--ignore-unknown-parameters")
39 |
40 | echo "Processed template '${fileNameArg}' will instantiate ${models.size()} objects"
41 |
42 | def created = openshift.apply( models )
43 | echo "Created: ${created.names()}"
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/vars/applyTemplate.txt:
--------------------------------------------------------------------------------
1 | # applyTemplate
2 |
3 | ## Summary
4 |
5 | Process and apply an OpenShift [template](https://docs.openshift.com/container-platform/3.11/dev_guide/templates.html).
6 |
7 | ## Usage
8 |
9 | ### Requirements
10 |
11 | Requires Jenkins agent with:
12 | - OC
13 |
14 | ### Parameters
15 |
16 | The method supports the following parameters:
17 | ```groovy
18 | // applyTemplate.groovy#L4-L15
19 |
20 | //Required
21 | String templateFile
22 |
23 | //Optional
24 | String parameterFile
25 |
26 | //Optional - Platform
27 | String clusterUrl = ""
28 | String clusterAPI = ""
29 | String clusterToken = ""
30 | String projectName = ""
31 | Integer loglevel = 0
32 | ```
33 |
34 | ### Example
35 |
36 | ```groovy
37 | // ../test/Jenkinsfile-applyTemplate#L11-L16
38 |
39 | stage("TEST: Can deploy via local file") {
40 | applyTemplate([
41 | templateFile : "cakephp-mysql.json"
42 | ])
43 | }
44 | ```
45 |
46 | ### Local vs Remote cluster support
47 |
48 | As the underlying technology used is the [openshift-client-plugin](https://github.com/openshift/jenkins-client-plugin),
49 | the ability to connect to a the local cluster, a cluster via URL/Token or using
50 | [Jenkins configuration](https://github.com/openshift/jenkins-client-plugin#configuring-an-openshift-cluster) is as easy
51 | as setting the clusterAPI and clusterToken parameters.
--------------------------------------------------------------------------------
/vars/binaryBuild.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | class BinaryBuildInput implements Serializable {
4 | //Required
5 | String buildConfigName = ""
6 | String buildFromFlag = "--from-dir"
7 | String buildFromPath = ""
8 |
9 | //Optional - Platform
10 | String clusterAPI = ""
11 | String clusterToken = ""
12 | String projectName = ""
13 | Integer loglevel = 0
14 | }
15 |
16 | def call(Map input) {
17 | call(new BinaryBuildInput(input))
18 | }
19 |
20 | def call(BinaryBuildInput input) {
21 | assert input.buildConfigName?.trim() : "Param buildConfigName should be defined."
22 | assert input.buildFromFlag?.trim() : "Param buildFromFlag should be defined."
23 | assert input.buildFromPath?.trim() : "Param buildFromPath should be defined."
24 |
25 | openshift.loglevel(input.loglevel)
26 |
27 | openshift.withCluster(input.clusterAPI, input.clusterToken) {
28 | openshift.withProject(input.projectName) {
29 | echo "Attemping to start and follow 'buildconfig/${input.buildConfigName}' in ${openshift.project()}"
30 |
31 | def buildConfig = openshift.selector('bc', input.buildConfigName)
32 | def build = buildConfig.startBuild("${input.buildFromFlag}=${input.buildFromPath}", '--wait')
33 | build.logs('-f')
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/vars/binaryBuild.txt:
--------------------------------------------------------------------------------
1 | # binaryBuild
2 |
3 | ## Summary
4 |
5 | Trigger a BuildConfig using the [binary build strategy](https://docs.openshift.com/container-platform/3.11/dev_guide/dev_tutorials/binary_builds.html).
6 |
7 | ## Usage
8 |
9 | ### Requirements
10 |
11 | Requires Jenkins agent with:
12 | - OC
13 |
14 | ### Parameters
15 |
16 | The method supports the following parameters:
17 | ```groovy
18 | // binaryBuild.groovy#L4-L13
19 |
20 | //Required
21 | String buildConfigName = ""
22 | String buildFromFlag = "--from-dir"
23 | String buildFromPath = ""
24 |
25 | //Optional - Platform
26 | String clusterAPI = ""
27 | String clusterToken = ""
28 | String projectName = ""
29 | Integer loglevel = 0
30 | ```
31 |
32 | ### Example
33 |
34 | ```groovy
35 | // ../test/Jenkinsfile-binaryBuild#L33-L39
36 |
37 | stage("TEST: Can build using from-file") {
38 | binaryBuild([
39 | buildConfigName: "sample-build-binary",
40 | buildFromFlag : "--from-dir",
41 | buildFromPath : "${WORKSPACE}/build/"
42 | ])
43 | }
44 | ```
45 |
46 | ### Local vs Remote cluster support
47 |
48 | As the underlying technology used is the [openshift-client-plugin](https://github.com/openshift/jenkins-client-plugin),
49 | the ability to connect to a the local cluster, a cluster via URL/Token or using
50 | [Jenkins configuration](https://github.com/openshift/jenkins-client-plugin#configuring-an-openshift-cluster) is as easy
51 | as setting the clusterAPI and clusterToken parameters.
--------------------------------------------------------------------------------
/vars/buildAndTag.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | class BuildAndTagInput implements Serializable {
4 | //Required
5 | String imageName = ''
6 | String imageNamespace = ''
7 | String imageVersion = ''
8 | String registryFQDN = ''
9 |
10 | //Optional
11 | String fromFilePath = ""
12 | String tagDestinationTLSVerify = "true"
13 | String tagSourceTLSVerify = "true"
14 | String tagAuthFile = "/var/run/secrets/kubernetes.io/dockerconfigjson/.dockerconfigjson"
15 | String tagDestinationCertDir = "/run/secrets/kubernetes.io/serviceaccount/"
16 | String tagSourceCertDir = "/run/secrets/kubernetes.io/serviceaccount/"
17 |
18 | //Optional - Platform
19 | String clusterAPI = ""
20 | String clusterToken = ""
21 | String buildProjectName = ""
22 | Integer loglevel = 0
23 | }
24 |
25 | def call(Map input) {
26 | call(new BuildAndTagInput(input))
27 | }
28 |
29 | def call(BuildAndTagInput input) {
30 | assert input.imageName?.trim() : "Param imageName should be defined."
31 | assert input.imageNamespace?.trim() : "Param imageNamespace should be defined."
32 | assert input.imageVersion?.trim() : "Param imageVersion should be defined."
33 | assert input.registryFQDN?.trim() : "Param registryFQDN should be defined."
34 |
35 | binaryBuild([
36 | clusterAPI : input.clusterAPI,
37 | clusterToken : input.clusterToken,
38 | projectName : input.buildProjectName,
39 | buildConfigName: input.imageName,
40 | buildFromPath : input.fromFilePath,
41 | loglevel: input.loglevel
42 | ])
43 |
44 | def authFileArg = input.tagAuthFile?.trim()?.length() <= 0 ? "" : "--authfile=${input.tagAuthFile}"
45 | def srcTlsVerifyArg = input.tagSourceTLSVerify?.trim()?.length() <= 0 ? "" : "--src-tls-verify=${input.tagSourceTLSVerify}"
46 | def destTlsVerifyArg = input.tagDestinationTLSVerify?.trim()?.length() <= 0 ? "" : "--dest-tls-verify=${input.tagDestinationTLSVerify}"
47 | def destCertDirArg = input.tagDestinationCertDir?.trim()?.length() <= 0 ? "" : "--dest-cert-dir=${input.tagDestinationCertDir}"
48 | def srcCertDirArg = input.tagSourceCertDir?.trim()?.length() <= 0 ? "" : "--src-cert-dir=${input.tagSourceCertDir}"
49 |
50 | def source = "docker://${input.registryFQDN}/${input.imageNamespace}/${input.imageName}:latest"
51 | def destination = "docker://${input.registryFQDN}/${input.imageNamespace}/${input.imageName}:${input.imageVersion}"
52 |
53 | echo "Attempting to tag; ${source} -> ${destination}"
54 |
55 | sh "skopeo copy $authFileArg $srcTlsVerifyArg $destTlsVerifyArg $destCertDirArg $srcCertDirArg $source $destination"
56 | }
57 |
--------------------------------------------------------------------------------
/vars/buildAndTag.txt:
--------------------------------------------------------------------------------
1 | # buildAndTag
2 |
3 | ## Summary
4 |
5 | Trigger a BuildConfig using the [binary build strategy](https://docs.openshift.com/container-platform/3.11/dev_guide/dev_tutorials/binary_builds.html)
6 | and tag the resulting image.
7 |
8 | ## Usage
9 |
10 | ### Requirements
11 |
12 | Requires Jenkins agent with:
13 | - OC
14 | - Skopeo
15 |
16 | ### Parameters
17 |
18 | The method supports the following parameters:
19 | ```groovy
20 | // buildAndTag.groovy#L4-L22
21 |
22 | //Required
23 | String imageName = ''
24 | String imageNamespace = ''
25 | String imageVersion = ''
26 | String registryFQDN = ''
27 |
28 | //Optional
29 | String fromFilePath = ""
30 | String tagDestinationTLSVerify = "true"
31 | String tagSourceTLSVerify = "true"
32 | String tagAuthFile = "/var/run/secrets/kubernetes.io/dockerconfigjson/.dockerconfigjson"
33 | String tagDestinationCertDir = "/run/secrets/kubernetes.io/serviceaccount/"
34 | String tagSourceCertDir = "/run/secrets/kubernetes.io/serviceaccount/"
35 |
36 | //Optional - Platform
37 | String clusterAPI = ""
38 | String clusterToken = ""
39 | String buildProjectName = ""
40 | Integer loglevel = 0
41 | ```
42 |
43 | ### Example
44 |
45 | ```groovy
46 | // ../test/Jenkinsfile-buildAndTag#L50-L58
47 |
48 | stage("TEST: Can build and tag") {
49 | buildAndTag([
50 | imageName : "sample-build",
51 | fromFilePath : "${WORKSPACE}/target/",
52 | registryFQDN : "${dockerRegistry}",
53 | imageNamespace: "pipelinelib-testing",
54 | imageVersion : "v2"
55 | ])
56 | }
57 | ```
58 |
59 | ### Local vs Remote cluster support
60 |
61 | As the underlying technology used is the [openshift-client-plugin](https://github.com/openshift/jenkins-client-plugin),
62 | the ability to connect to a the local cluster, a cluster via URL/Token or using
63 | [Jenkins configuration](https://github.com/openshift/jenkins-client-plugin#configuring-an-openshift-cluster) is as easy
64 | as setting the clusterAPI and clusterToken parameters.
--------------------------------------------------------------------------------
/vars/clusterCredentials.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | class ClusterCredentialsInput implements Serializable {
4 | //Required
5 | String secretName = ""
6 |
7 | //Optional
8 | boolean insecure = false
9 |
10 | //Optional - Platform
11 | String clusterAPI = ""
12 | String clusterToken = ""
13 | String projectName = ""
14 | Integer loglevel = 0
15 | }
16 |
17 | def call(Map input) {
18 | call(new ClusterCredentialsInput(input))
19 | }
20 |
21 | def call(ClusterCredentialsInput input) {
22 | assert input.secretName?.trim() : "Param secretName should be defined."
23 |
24 | openshift.loglevel(input.loglevel)
25 |
26 | def encodedApi
27 | def encodedToken
28 |
29 | openshift.withCluster(input.clusterAPI, input.clusterToken) {
30 | openshift.withProject(input.projectName) {
31 | echo "Attemping to retrieve ClusterCredentials 'secret/${input.secretName}' in ${openshift.project()}"
32 |
33 | def secret = openshift.selector("secret/${input.secretName}")
34 | def secretObject = secret.object()
35 | def secretData = secretObject.data
36 |
37 | encodedApi = secretData.api
38 | encodedToken = secretData.token
39 | }
40 | }
41 |
42 | def api = sh(script:"set +x; echo ${encodedApi} | base64 --decode", returnStdout: true)
43 | def token = sh(script:"set +x; echo ${encodedToken} | base64 --decode", returnStdout: true)
44 |
45 | //NOTE: the regex here makes it so that the jenkins-client-plugin wont verify the CA
46 | api = input.insecure ? api.replaceAll(/https?/, 'insecure') : api
47 |
48 | return [api, token]
49 | }
50 |
--------------------------------------------------------------------------------
/vars/clusterCredentials.txt:
--------------------------------------------------------------------------------
1 | # clusterCredentials
2 |
3 | ## Summary
4 |
5 | Retrieve a [Secret](https://docs.openshift.com/container-platform/3.11/dev_guide/secrets.html) which contains
6 | credentials to authenticate against a cluster.
7 |
8 | ## Usage
9 |
10 | ### Requirements
11 |
12 | Requires Jenkins agent with:
13 | - OC
14 |
15 | ### Parameters
16 |
17 | The method supports the following parameters:
18 | ```groovy
19 | // clusterCredentials.groovy#L4-L14
20 |
21 | //Required
22 | String secretName = ""
23 |
24 | //Optional
25 | boolean insecure = false
26 |
27 | //Optional - Platform
28 | String clusterAPI = ""
29 | String clusterToken = ""
30 | String projectName = ""
31 | Integer loglevel = 0
32 | ```
33 |
34 | ### Example
35 |
36 | ```groovy
37 | // ../test/Jenkinsfile-clusterCredentials#L30-L34
38 |
39 | stage("TEST: Can get credential") {
40 | credentials = clusterCredentials([
41 | secretName: "cluster-credential"
42 | ])
43 | }
44 | ```
45 |
46 | ### Local vs Remote cluster support
47 |
48 | As the underlying technology used is the [openshift-client-plugin](https://github.com/openshift/jenkins-client-plugin),
49 | the ability to connect to a the local cluster, a cluster via URL/Token or using
50 | [Jenkins configuration](https://github.com/openshift/jenkins-client-plugin#configuring-an-openshift-cluster) is as easy
51 | as setting the clusterAPI and clusterToken parameters.
52 |
53 | ### Secret Format
54 |
55 | The credentials which are retrieved by this method are expected to be in a secret using the following format.
56 |
57 | ```yaml
58 | ---
59 | kind: Template
60 | apiVersion: v1
61 | metadata:
62 | name: cluster-credential-secret
63 | annotations:
64 | openshift.io/display-name: Cluster Credential Secret
65 | objects:
66 | - kind: Secret
67 | apiVersion: v1
68 | metadata:
69 | name: "${NAME}"
70 | labels:
71 | credential.sync.jenkins.openshift.io: "true"
72 | type: Opaque
73 | data:
74 | api: "${API_B64}"
75 | token: "${TOKEN_B64}"
76 | parameters:
77 | - name: NAME
78 | displayName: Name
79 | description: The name of secret.
80 | required: true
81 | - name: API_B64
82 | displayName: API
83 | description: API url of the cluster the credential is for.
84 | required: true
85 | - name: TOKEN_B64
86 | displayName: Token
87 | description: Authentication token for the cluster.
88 | required: true
89 | ```
--------------------------------------------------------------------------------
/vars/configMap.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | class ConfigMapInput implements Serializable {
4 | //Required
5 | String configMapName = ""
6 |
7 | //Optional - Platform
8 | String clusterAPI = ""
9 | String clusterToken = ""
10 | String projectName = ""
11 | Integer loglevel = 0
12 | }
13 |
14 | def call(Map input) {
15 | call(new ConfigMapInput(input))
16 | }
17 |
18 | def call(ConfigMapInput input) {
19 | assert input.configMapName?.trim() : "Param configMapName should be defined."
20 |
21 | openshift.loglevel(input.loglevel)
22 |
23 | def configMapData
24 |
25 | openshift.withCluster(input.clusterAPI, input.clusterToken) {
26 | openshift.withProject(input.projectName) {
27 | echo "Attemping to retrieve 'configmap/${input.configMapName}' in ${openshift.project()}"
28 |
29 | def configMap = openshift.selector("configmap/${input.configMapName}")
30 | def configMapObject = configMap.object()
31 | configMapData = configMapObject.data
32 | }
33 | }
34 |
35 | return configMapData
36 | }
37 |
--------------------------------------------------------------------------------
/vars/configMap.txt:
--------------------------------------------------------------------------------
1 | # configMap
2 |
3 | ## Summary
4 |
5 | Retrieve a (ConfigMap)[https://docs.openshift.com/container-platform/3.11/dev_guide/configmaps.html] data.
6 |
7 | ## Usage
8 |
9 | ### Requirements
10 |
11 | Requires Jenkins agent with:
12 | - OC
13 |
14 | ### Parameters
15 |
16 | The method supports the following parameters:
17 | ```groovy
18 | // configMap.groovy#L4-L11
19 |
20 | //Required
21 | String configMapName = ""
22 |
23 | //Optional - Platform
24 | String clusterAPI = ""
25 | String clusterToken = ""
26 | String projectName = ""
27 | Integer loglevel = 0
28 | ```
29 |
30 | ### Example
31 |
32 | ```groovy
33 | // ../test/Jenkinsfile-configMap#L29-L33
34 |
35 | stage("TEST: Can get configmap data") {
36 | configMapData = configMap([
37 | configMapName: "game-config"
38 | ])
39 | }
40 | ```
41 |
42 | ### Local vs Remote cluster support
43 |
44 | As the underlying technology used is the [openshift-client-plugin](https://github.com/openshift/jenkins-client-plugin),
45 | the ability to connect to a the local cluster, a cluster via URL/Token or using
46 | [Jenkins configuration](https://github.com/openshift/jenkins-client-plugin#configuring-an-openshift-cluster) is as easy
47 | as setting the clusterAPI and clusterToken parameters.
--------------------------------------------------------------------------------
/vars/crossClusterPromote.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | class CopyImageInput implements Serializable {
4 | //Required
5 | String sourceImageName
6 | String sourceImageTag = "latest"
7 | String destinationImageName
8 | String destinationImageTag
9 | String destinationImagePath
10 | String targetRegistryCredentials = "other-cluster-credentials"
11 |
12 | //Optional
13 | String sourceImagePath = ""
14 |
15 | //Optional - Platform
16 | String clusterUrl = ""
17 | String clusterAPI = ""
18 | String clusterToken = ""
19 | Integer loglevel = 0
20 |
21 | CopyImageInput init() {
22 | if(!destinationImageName?.trim()) destinationImageName = sourceImageName
23 | if(!destinationImageTag?.trim()) destinationImageTag = sourceImageTag
24 | if(!destinationImagePath?.trim()) destinationImagePath = sourceImagePath
25 | return this
26 | }
27 | }
28 |
29 | def call(Map input) {
30 | call(new CopyImageInput(input).init())
31 | }
32 |
33 | def call(CopyImageInput input) {
34 | assert input.targetRegistryCredentials?.trim() : "Param targetRegistryCredentials should be defined."
35 | assert input.sourceImageName?.trim() : "Param sourceImageName should be defined."
36 | assert input.sourceImageTag?.trim() : "Param sourceImageTag should be defined."
37 | assert input.destinationImagePath?.trim() : "Param destinationImagePath should be defined."
38 | assert input.destinationImageName?.trim() : "Param destinationImageName should be defined."
39 | assert input.destinationImageTag?.trim() : "Param destinationImageTag should be defined."
40 |
41 | openshift.loglevel(input.loglevel)
42 |
43 | if (input.clusterUrl?.trim().length() > 0) {
44 | error "clusterUrl is deprecated and will be removed in the next release. Please use 'clusterAPI'"
45 | }
46 |
47 | openshift.withCluster(input.clusterAPI, input.clusterToken) {
48 | def localToken = readFile("/var/run/secrets/kubernetes.io/serviceaccount/token").trim()
49 |
50 | def secretData = openshift.selector("secret/${input.targetRegistryCredentials}").object().data
51 | def registry = sh(script:"set +x; echo ${secretData.registry} | base64 --decode", returnStdout: true)
52 | def token = sh(script:"set +x; echo ${secretData.token} | base64 --decode", returnStdout: true)
53 | def username = sh(script:"set +x; echo ${secretData.username} | base64 --decode", returnStdout: true)
54 |
55 | openshift.withProject(input.sourceImagePath) {
56 | def localRegistry = openshift.selector( "is", "${input.sourceImageName}").object().status.dockerImageRepository
57 | def from = "docker://${localRegistry}:${input.sourceImageTag}"
58 | def to = "docker://${registry}/${input.destinationImagePath}/${input.destinationImageName}:${input.destinationImageTag}"
59 |
60 | echo "Now Promoting ${from} -> ${to}"
61 | sh """
62 | set +x
63 | skopeo copy --remove-signatures \
64 | --src-creds openshift:${localToken} --src-cert-dir=/run/secrets/kubernetes.io/serviceaccount/ \
65 | --dest-creds ${username}:${token} --dest-tls-verify=false ${from} ${to}
66 | """
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/vars/crossClusterPromote.txt:
--------------------------------------------------------------------------------
1 | # crossClusterPromote
2 |
3 | ## Summary
4 |
5 | Promote an image from the local cluster to a remote registry.
6 |
7 | ## Usage
8 |
9 | ### Requirements
10 |
11 | Requires Jenkins agent with:
12 | - OC
13 | - Skopeo
14 |
15 | ### Parameters
16 |
17 | The method supports the following parameters:
18 | ```groovy
19 | // crossClusterPromote.groovy#L4-L19
20 |
21 | //Required
22 | String sourceImageName
23 | String sourceImageTag = "latest"
24 | String destinationImageName
25 | String destinationImageTag
26 | String destinationImagePath
27 | String targetRegistryCredentials = "other-cluster-credentials"
28 |
29 | //Optional
30 | String sourceImagePath = ""
31 |
32 | //Optional - Platform
33 | String clusterUrl = ""
34 | String clusterAPI = ""
35 | String clusterToken = ""
36 | Integer loglevel = 0
37 | ```
38 |
39 | ### Example
40 |
41 | ```groovy
42 | // ../test/Jenkinsfile-crossClusterPromote#L26-L33
43 |
44 | stage("TEST: Can promote image from one project to another") {
45 | crossClusterPromote([
46 | sourceImageName : "jenkins-slave-ansible",
47 | sourceImagePath : "pipelinelib-testing",
48 | destinationImagePath : "pipelinelib-promotion-testing",
49 | targetRegistryCredentials: "local-registry-generic"
50 | ])
51 | }
52 | ```
53 |
54 | ### Local vs Remote cluster support
55 |
56 | As the underlying technology used is the [openshift-client-plugin](https://github.com/openshift/jenkins-client-plugin),
57 | the ability to connect to a the local cluster, a cluster via URL/Token or using
58 | [Jenkins configuration](https://github.com/openshift/jenkins-client-plugin#configuring-an-openshift-cluster) is as easy
59 | as setting the clusterAPI and clusterToken parameters.
60 |
61 | ### Secret Format
62 |
63 | This method supports using a secret (via targetRegistryCredentials) which is used to login to the cluster that you want to push the image to. Typically,
64 | a [service account token](https://docs.openshift.com/container-platform/3.11/dev_guide/service_accounts.html#using-a-service-accounts-credentials-externally)
65 | would be used within the secret.
66 |
67 | ```yaml
68 | ---
69 | kind: Template
70 | apiVersion: v1
71 | metadata:
72 | name: cluster-promote-credential-secret
73 | annotations:
74 | openshift.io/display-name: Cluster Promote Credential Secret
75 | objects:
76 | - apiVersion: v1
77 | kind: Secret
78 | metadata:
79 | name: "${NAME}"
80 | type: Opaque
81 | data:
82 | username: "${USERNAME_B64}"
83 | token: "${TOKEN_B64}"
84 | registry: "${REGISTRY_URL_B64}"
85 | parameters:
86 | - name: NAME
87 | displayName: Name
88 | description: The name of secret.
89 | required: true
90 | - name: USERNAME_B64
91 | displayName: Username
92 | description: Username to use when authenticating against destination registry.
93 | required: true
94 | - name: TOKEN_B64
95 | displayName: Token
96 | description: Authentication token to use when authenticating against destination registry.
97 | required: true
98 | - name: REGISTRY_URL_B64
99 | displayName: Registry URL
100 | description: Registry URL of destination registry.
101 | required: true
102 | ```
--------------------------------------------------------------------------------
/vars/imageMirror.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | class ImageMirrorInput implements Serializable {
4 | //Required
5 | String sourceSecret = ""
6 | String sourceRegistry = ""
7 | String destinationSecret = ""
8 | String destinationRegistry = ""
9 | String insecure = "false"
10 | String sourceNamespace = ""
11 | String destinationNamespace = ""
12 | String sourceImage = ""
13 | String destinationImage = ""
14 | String sourceImageVersion = "latest"
15 | String destinationImageVersion = "latest"
16 |
17 | //Optional - Platform
18 | Integer loglevel = 0
19 |
20 | ImageMirrorInput init() {
21 | if(!destinationImage?.trim()) destinationImage = sourceImage
22 | if(!destinationNamespace?.trim()) destinationNamespace = sourceNamespace
23 | return this
24 | }
25 | }
26 |
27 | def call(Map input) {
28 | call(new ImageMirrorInput(input).init())
29 | }
30 |
31 | def call(ImageMirrorInput input) {
32 | assert input.sourceSecret?.trim(): "Param sourceSecret should be defined."
33 | assert input.sourceRegistry?.trim(): "Param sourceRegistry should be defined."
34 | assert input.destinationSecret?.trim(): "Param destinationSecret should be defined."
35 | assert input.destinationRegistry?.trim(): "Param destinationRegistry should be defined."
36 | assert input.sourceNamespace?.trim(): "Param sourceNamespace should be defined."
37 | assert input.sourceImage?.trim(): "Param sourceImage should be defined."
38 | assert input.destinationNamespace?.trim(): "Param destinationNamespace should be defined."
39 | assert input.destinationImage?.trim(): "Param destinationImage should be defined."
40 | assert input.destinationImageVersion?.trim(): "Param destinationImageVersion should be defined."
41 | assert input.insecure?.trim(): "Param insecure should be defined."
42 |
43 | openshift.loglevel(input.loglevel)
44 |
45 | String sourceApi = input.sourceRegistry.replaceFirst("^(http[s]?://\\.|http[s]?://)", "")
46 | String destinationApi = input.destinationRegistry.replaceFirst("^(http[s]?://\\.|http[s]?://)", "")
47 |
48 | withDockerRegistry([credentialsId: "${input.sourceSecret}", url: "${input.sourceRegistry}"]) {
49 | withDockerRegistry([credentialsId: "${input.destinationSecret}", url: "${input.destinationRegistry}"]) {
50 | openshift.withCluster() {
51 | def source = "${sourceApi}/${input.sourceNamespace}/${input.sourceImage}:${input.sourceImageVersion}"
52 | def destination = "${destinationApi}/${input.destinationNamespace}/${input.destinationImage}:${input.destinationImageVersion}"
53 |
54 | echo "Attempting to mirror; ${source} -> ${destination}"
55 |
56 | openshift.raw("image", "mirror", source, destination, "--insecure=${input.insecure}")
57 | }
58 | }
59 | }
60 | }
61 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/vars/imageMirror.txt:
--------------------------------------------------------------------------------
1 | # imageMirror
2 |
3 | ## Summary
4 |
5 | (Mirror)[https://docs.openshift.com/container-platform/3.11/dev_guide/managing_images.html#managing-images-mirror-registry-images] an image from one registry to another.
6 |
7 | ## Usage
8 |
9 | ### Requirements
10 |
11 | Requires Jenkins agent with:
12 | - OC
13 |
14 | ### Parameters
15 |
16 | The method supports the following parameters:
17 | ```groovy
18 | // imageMirror.groovy#L4-L18
19 |
20 | //Required
21 | String sourceSecret = ""
22 | String sourceRegistry = ""
23 | String destinationSecret = ""
24 | String destinationRegistry = ""
25 | String insecure = "false"
26 | String sourceNamespace = ""
27 | String destinationNamespace = ""
28 | String sourceImage = ""
29 | String destinationImage = ""
30 | String sourceImageVersion = "latest"
31 | String destinationImageVersion = "latest"
32 |
33 | //Optional - Platform
34 | Integer loglevel = 0
35 | ```
36 |
37 | ### Example
38 |
39 | ```groovy
40 | // ../test/Jenkinsfile-imageMirror#L35-L48
41 |
42 | stage("TEST: Can promote image from one project to another") {
43 | imageMirror([
44 | sourceSecret : "pipelinelib-testing-my-token",
45 | sourceRegistry : "https://${dockerRegistry}",
46 | destinationSecret : "pipelinelib-testing-my-token",
47 | destinationRegistry : "https://${dockerRegistry}",
48 | insecure : "true",
49 | sourceNamespace : "pipelinelib-testing",
50 | destinationNamespace : "pipelinelib-promotion-testing",
51 | sourceImage : "jenkins-slave-image-mgmt",
52 | sourceImageVersion : "latest",
53 | destinationImageVersion: "latest"
54 | ])
55 | }
56 | ```
57 |
58 | ### Local vs Remote cluster support
59 |
60 | As the underlying technology used is the [openshift-client-plugin](https://github.com/openshift/jenkins-client-plugin),
61 | the ability to connect to a the local cluster, a cluster via URL/Token or using
62 | [Jenkins configuration](https://github.com/openshift/jenkins-client-plugin#configuring-an-openshift-cluster) is as easy
63 | as setting the clusterAPI and clusterToken parameters.
64 |
65 | #### Secret Format
66 |
67 | This method supports using a Jenkins credential (via sourceSecret and destinationSecret) which is used to login to the cluster that the image mirror will work against. Typically,
68 | a [service account token](https://docs.openshift.com/container-platform/3.11/dev_guide/service_accounts.html#using-a-service-accounts-credentials-externally)
69 | would be used within the secret.
70 |
71 | ```yaml
72 | ---
73 | kind: Template
74 | apiVersion: v1
75 | metadata:
76 | name: image-mirror-credential-secret
77 | annotations:
78 | openshift.io/display-name: Image Mirror Credential Secret
79 | objects:
80 | - apiVersion: v1
81 | kind: Secret
82 | metadata:
83 | name: "${NAME}"
84 | labels:
85 | credential.sync.jenkins.openshift.io: "true"
86 | type: Opaque
87 | data:
88 | username: "${USERNAME_B64}"
89 | password: "${PASSWORD_B64}"
90 | parameters:
91 | - name: NAME
92 | displayName: Name
93 | description: The name of secret.
94 | required: true
95 | - name: USERNAME_B64
96 | displayName: Username
97 | description: Username to use when authenticating.
98 | required: true
99 | - name: PASSWORD_B64
100 | displayName: Password
101 | description: Password to use when authenticating.
102 | required: true
103 | ```
--------------------------------------------------------------------------------
/vars/patchBuildConfigOutputLabels.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | import groovy.json.JsonOutput
4 |
5 | // When using the non-declarative pipeline, git env variables need to be set through scm checkout
6 | class PatchBuildConfigOutputLabelsInput implements Serializable {
7 | //Required
8 | String domainPrefix = "com.redhat"
9 | String bcName = ""
10 |
11 | //Optional
12 | String clusterAPI = ""
13 | String clusterToken = ""
14 | String projectName = ""
15 | Integer loglevel = 0
16 | }
17 |
18 | def call(Map input) {
19 | call(new PatchBuildConfigOutputLabelsInput(input))
20 | }
21 |
22 | def call(PatchBuildConfigOutputLabelsInput input) {
23 | assert input.domainPrefix?.trim(): "Param domainPrefix should be defined"
24 | assert input.bcName?.trim(): "Param bcName (build config name) should be defined"
25 |
26 | openshift.loglevel(input.loglevel)
27 |
28 | def patch = [
29 | spec: [
30 | output: [
31 | imageLabels: [
32 | [name: "${input.domainPrefix}.jenkins.build.url", value: "${env.BUILD_URL}"],
33 | [name: "${input.domainPrefix}.jenkins.build.tag", value: "${env.BUILD_NUMBER}"],
34 | [name: "${input.domainPrefix}.git.branch", value: "${env.GIT_BRANCH}"],
35 | [name: "${input.domainPrefix}.git.url", value: "${env.GIT_URL}"],
36 | [name: "${input.domainPrefix}.git.commit", value: "${env.GIT_COMMIT}"]
37 | ]
38 | ]
39 | ]
40 | ]
41 |
42 | openshift.withCluster(input.clusterAPI, input.clusterToken) {
43 | openshift.withProject(input.projectName) {
44 | echo "Attemping to patch 'buildconfig/${input.bcName}' in ${openshift.project()}"
45 |
46 | def buildConfig = openshift.selector("bc", input.bcName)
47 | if (buildConfig.exists()) {
48 | openshift.patch(buildConfig.object(), "'" + JsonOutput.toJson(patch) + "'")
49 | } else {
50 | error "Failed to find 'bc/${input.bcName}' in ${openshift.project()}"
51 | }
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/vars/patchBuildConfigOutputLabels.txt:
--------------------------------------------------------------------------------
1 | # patchBuildConfigOutputLabels
2 |
3 | ## Summary
4 |
5 | Patch a BuildConfig to contain annotations about the current Jenkins and GIT build information.
6 |
7 | ## Usage
8 |
9 | ### Requirements
10 |
11 | Requires Jenkins agent with:
12 | - OC
13 |
14 | ### Parameters
15 |
16 | The method supports the following parameters:
17 | ```groovy
18 | // patchBuildConfigOutputLabels.groovy#L7-L15
19 |
20 | //Required
21 | String domainPrefix = "com.redhat"
22 | String bcName = ""
23 |
24 | //Optional
25 | String clusterAPI = ""
26 | String clusterToken = ""
27 | String projectName = ""
28 | Integer loglevel = 0
29 | ```
30 |
31 | ### Example
32 |
33 | ```groovy
34 | // ../test/Jenkinsfile-patchBuildConfigOutputLabels#L18-L23
35 |
36 | stage("TEST: Can patch build config") {
37 | patchBuildConfigOutputLabels([
38 | bcName : "sample-verbose-build",
39 | domainPrefix: "org.example"
40 | ])
41 | }
42 | ```
43 |
44 | ### Local vs Remote cluster support
45 |
46 | As the underlying technology used is the [openshift-client-plugin](https://github.com/openshift/jenkins-client-plugin),
47 | the ability to connect to a the local cluster, a cluster via URL/Token or using
48 | [Jenkins configuration](https://github.com/openshift/jenkins-client-plugin#configuring-an-openshift-cluster) is as easy
49 | as setting the clusterAPI and clusterToken parameters.
--------------------------------------------------------------------------------
/vars/rollback.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | class Rollback implements Serializable {
4 | //Required
5 | String deploymentConfig
6 | String resourceKindAndName = ""
7 |
8 | //Optional
9 | String rollbackVersion = ""
10 |
11 | //Optional - Platform
12 | String clusterUrl = ""
13 | String clusterAPI = ""
14 | String clusterToken = ""
15 | String projectName = ""
16 | Integer loglevel = 0
17 | }
18 |
19 | def call(Map input) {
20 | call(new Rollback(input))
21 | }
22 |
23 | def call(Rollback input) {
24 | if (input.deploymentConfig?.trim()?.length() > 0) {
25 | echo "deploymentConfig is deprecated. Please use 'resourceKindAndName'"
26 |
27 | input.resourceKindAndName = input.deploymentConfig
28 | }
29 |
30 | assert input.resourceKindAndName?.trim(): "Param resourceKindAndName should be defined"
31 |
32 | openshift.loglevel(input.loglevel)
33 |
34 | if (input.clusterUrl?.trim().length() > 0) {
35 | error "clusterUrl is deprecated and will be removed in the next release. Please use 'clusterAPI'"
36 | }
37 |
38 | openshift.withCluster(input.clusterAPI, input.clusterToken) {
39 | openshift.withProject(input.projectName) {
40 | def cmd = input.rollbackVersion?.trim().length() <= 0 ? "" : "--to-revision=${input.rollbackVersion}"
41 |
42 | echo "Attempting to rollback '${input.resourceKindAndName}' in ${openshift.project()} ${cmd}"
43 |
44 | def resource = openshift.selector(input.resourceKindAndName)
45 | resource.rollout().undo(cmd)
46 | }
47 | }
48 | }
--------------------------------------------------------------------------------
/vars/rollback.txt:
--------------------------------------------------------------------------------
1 | # rollback
2 |
3 | ## Summary
4 |
5 | (Rollback)[https://docs.openshift.com/container-platform/3.11/dev_guide/deployments/basic_deployment_operations.html#rolling-back-a-deployment]
6 | a deployment to a previous version.
7 |
8 | ## Usage
9 |
10 | ### Requirements
11 |
12 | Requires Jenkins agent with:
13 | - OC
14 |
15 | ### Parameters
16 |
17 | The method supports the following parameters:
18 | ```groovy
19 | // rollback.groovy#L4-L16
20 |
21 | //Required
22 | String deploymentConfig
23 | String resourceKindAndName = ""
24 |
25 | //Optional
26 | String rollbackVersion = ""
27 |
28 | //Optional - Platform
29 | String clusterUrl = ""
30 | String clusterAPI = ""
31 | String clusterToken = ""
32 | String projectName = ""
33 | Integer loglevel = 0
34 | ```
35 |
36 | ### Example
37 |
38 | ```groovy
39 | // ../test/Jenkinsfile-rollback#L31-L35
40 |
41 | stage("TEST: Can rollback to earlier version") {
42 | rollback([
43 | resourceKindAndName: "dc/rollback"
44 | ])
45 | }
46 | ```
47 |
48 | ### Local vs Remote cluster support
49 |
50 | As the underlying technology used is the [openshift-client-plugin](https://github.com/openshift/jenkins-client-plugin),
51 | the ability to connect to a the local cluster, a cluster via URL/Token or using
52 | [Jenkins configuration](https://github.com/openshift/jenkins-client-plugin#configuring-an-openshift-cluster) is as easy
53 | as setting the clusterAPI and clusterToken parameters.
--------------------------------------------------------------------------------
/vars/rollout.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | class RolloutInput implements Serializable {
4 | //Required
5 | String deploymentConfigName = ""
6 | String resourceKindAndName = ""
7 |
8 | //Optional
9 | boolean latest = true
10 |
11 | //Optional - Platform
12 | String clusterAPI = ""
13 | String clusterToken = ""
14 | String projectName = ""
15 | Integer loglevel = 0
16 | }
17 |
18 | def call(Map input) {
19 | call(new RolloutInput(input))
20 | }
21 |
22 | def call(RolloutInput input) {
23 | if (input.deploymentConfigName?.trim()?.length() > 0) {
24 | echo "deploymentConfig is deprecated. Please use 'resourceKindAndName'"
25 |
26 | input.resourceKindAndName = input.deploymentConfigName
27 | }
28 |
29 | assert input.resourceKindAndName?.trim() : "Param resourceKindAndName should be defined."
30 |
31 | openshift.loglevel(input.loglevel)
32 |
33 | openshift.withCluster(input.clusterAPI, input.clusterToken) {
34 | openshift.withProject(input.projectName) {
35 | echo "Attemping to rollout latest '${input.resourceKindAndName}' in ${openshift.project()}"
36 |
37 | def resource = openshift.selector(input.resourceKindAndName)
38 | def rolloutManager = resource.rollout()
39 |
40 | if (input.latest) {
41 | rolloutManager.latest()
42 | }
43 |
44 | echo "Waiting for rollout of '${input.resourceKindAndName}' in ${openshift.project()} to complete..."
45 |
46 | try {
47 | rolloutManager.status("--watch=true")
48 | } catch (ex) {
49 | //Something went wrong, so lets print out some helpful information
50 | rolloutManager.history()
51 | resource.describe()
52 |
53 | throw ex
54 | }
55 | }
56 | }
57 | }
--------------------------------------------------------------------------------
/vars/rollout.txt:
--------------------------------------------------------------------------------
1 | # rollout
2 |
3 | ## Summary
4 |
5 | (Rollout)[https://docs.openshift.com/container-platform/3.11/dev_guide/deployments/basic_deployment_operations.html#start-deployment]
6 | a deployment and wait until it is successful.
7 |
8 | ## Usage
9 |
10 | ### Requirements
11 |
12 | Requires Jenkins agent with:
13 | - OC
14 |
15 | ### Parameters
16 |
17 | The method supports the following parameters:
18 | ```groovy
19 | // rollout.groovy#L4-L15
20 |
21 | //Required
22 | String deploymentConfigName = ""
23 | String resourceKindAndName = ""
24 |
25 | //Optional
26 | boolean latest = true
27 |
28 | //Optional - Platform
29 | String clusterAPI = ""
30 | String clusterToken = ""
31 | String projectName = ""
32 | Integer loglevel = 0
33 | ```
34 |
35 | ### Example
36 |
37 | ```groovy
38 | // ../test/Jenkinsfile-rollout#L25-L29
39 |
40 | stage("TEST: Can rollout to latest version") {
41 | rollout([
42 | resourceKindAndName: "dc/rollout"
43 | ])
44 | }
45 | ```
46 |
47 | ### Local vs Remote cluster support
48 |
49 | As the underlying technology used is the [openshift-client-plugin](https://github.com/openshift/jenkins-client-plugin),
50 | the ability to connect to a the local cluster, a cluster via URL/Token or using
51 | [Jenkins configuration](https://github.com/openshift/jenkins-client-plugin#configuring-an-openshift-cluster) is as easy
52 | as setting the clusterAPI and clusterToken parameters.
--------------------------------------------------------------------------------
/vars/sonarqubeStaticAnalysis.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | class SonarQubeConfigurationInput implements Serializable {
4 | //Optional
5 | String pomFile = "pom.xml"
6 | String buildServerWebHookName = "jenkins"
7 | String curlOptions = ""
8 | }
9 |
10 | def call() {
11 | call(new SonarQubeConfigurationInput())
12 | }
13 |
14 | def call(Map input) {
15 | call(new SonarQubeConfigurationInput(input))
16 | }
17 |
18 | def call(SonarQubeConfigurationInput input) {
19 | // make sure build server web hook is available
20 | checkForBuildServerWebHook(input)
21 |
22 | // Execute the Maven goal sonar:sonar to attempt to generate
23 | // the report files.
24 | withSonarQubeEnv('sonar') {
25 | try {
26 | sh "mvn sonar:sonar -f ${input.pomFile}"
27 | } catch (error) {
28 | error error.getMessage()
29 | }
30 | }
31 |
32 | // Check the quality gate to make sure
33 | // it is in a passing state.
34 | def qualitygate = waitForQualityGate()
35 | if (qualitygate.status != "OK") {
36 | error "Pipeline aborted due to quality gate failure: ${qualitygate.status}"
37 | }
38 | }
39 |
40 | def checkForBuildServerWebHook(SonarQubeConfigurationInput input) {
41 | withSonarQubeEnv('sonar') {
42 | echo "Validating webhook with name ${input.buildServerWebHookName} exists..."
43 |
44 | def retVal = sh(returnStdout: true, script: "curl ${input.curlOptions} -u '${SONAR_AUTH_TOKEN}:' ${SONAR_HOST_URL}/api/webhooks/list")
45 | echo "Return Value is $retVal"
46 |
47 | def tmpfile = "/tmp/sonarwebhooks-${java.util.UUID.randomUUID()}.json"
48 | writeFile file: tmpfile, text: retVal
49 |
50 | def webhooksObj = readJSON file: tmpfile
51 | def foundHook = webhooksObj?.webhooks?.find { it.name.equalsIgnoreCase(input.buildServerWebHookName) }
52 |
53 | // webhook was not found
54 | // create the webhook - this should be more likely be part
55 | // of the sonarqube configuration automation
56 | if(foundHook == null) {
57 | error "No webhook found with name ${input.buildServerWebHookName}. Please create one in SonarQube."
58 | }
59 |
60 | echo "Build Server Webhook found. Continuing SonarQube analysis."
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/vars/sonarqubeStaticAnalysis.txt:
--------------------------------------------------------------------------------
1 | # sonarqubeStaticAnalysis
2 |
3 | ## Summary
4 |
5 | This function will:
6 | - validate that a build server webhook has been configured in SonarQube
7 | - run the sonar:sonar maven goal for the configured pom file
8 | - wait for the quality gate status to be OK.
9 |
10 | The pipeline will be stopped if the webhook has not been configured or the quality gate fails. Be advised that the
11 | SonarQube deployment @ https://github.com/redhat-cop/containers-quickstarts/tree/master/sonarqube
12 | will create this webhook for you.
13 |
14 | ## Usage
15 |
16 | ### Requirements
17 |
18 | Requires Jenkins agent with:
19 | - OC
20 | - Maven
21 | - SonarQube server and Jenkins plugin
22 |
23 | ### Parameters
24 |
25 | The method supports the following parameters:
26 | ```groovy
27 | // sonarqubeStaticAnalysis.groovy#L4-L7
28 |
29 | //Optional
30 | String pomFile = "pom.xml"
31 | String buildServerWebHookName = "jenkins"
32 | String curlOptions = ""
33 | ```
34 |
35 | ### Example
36 |
37 | ```groovy
38 | // ../test/Jenkinsfile-sonarqubeStaticAnalysis#L84-L92
39 |
40 | stage("TEST: Can run sonarqube static analysis") {
41 | sh "git clone https://github.com/redhat-cop/pipeline-library.git"
42 |
43 | dir ("pipeline-library") {
44 | sonarqubeStaticAnalysis([
45 | curlOptions: "--insecure"
46 | ])
47 | }
48 | }
49 | ```
50 |
51 | ### Local vs Remote cluster support
52 |
53 | As the underlying technology used is the [openshift-client-plugin](https://github.com/openshift/jenkins-client-plugin),
54 | the ability to connect to a the local cluster, a cluster via URL/Token or using
55 | [Jenkins configuration](https://github.com/openshift/jenkins-client-plugin#configuring-an-openshift-cluster) is as easy
56 | as setting the clusterAPI and clusterToken parameters.
--------------------------------------------------------------------------------
/vars/tagAndDeploy.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | class TagAndDeployInput implements Serializable {
4 | //Required
5 | String imageName = ''
6 | String imageNamespace = ''
7 | String imageVersion = ''
8 | String registryFQDN = ''
9 | String deployDestinationVersionTag = ''
10 |
11 | //Optional
12 | String deployDestinationProjectName = ""
13 | String tagDestinationTLSVerify = "true"
14 | String tagSourceTLSVerify = "true"
15 | String tagAuthFile = "/var/run/secrets/kubernetes.io/dockerconfigjson/.dockerconfigjson"
16 | String tagDestinationCertDir = "/run/secrets/kubernetes.io/serviceaccount/"
17 | String tagSourceCertDir = "/run/secrets/kubernetes.io/serviceaccount/"
18 |
19 | //Optional - Platform
20 | String clusterAPI = ""
21 | String clusterToken = ""
22 | Integer loglevel = 0
23 | }
24 |
25 | def call(Map input) {
26 | call(new TagAndDeployInput(input))
27 | }
28 |
29 | def call(TagAndDeployInput input) {
30 | assert input.imageName?.trim() : "Param imageName should be defined."
31 | assert input.imageNamespace?.trim() : "Param imageNamespace should be defined."
32 | assert input.imageVersion?.trim() : "Param imageVersion should be defined."
33 | assert input.registryFQDN?.trim() : "Param registryFQDN should be defined."
34 | assert input.deployDestinationVersionTag?.trim() : "Param deployDestinationVersionTag should be defined."
35 |
36 | def authFileArg = input.tagAuthFile?.trim()?.length() <= 0 ? "" : "--authfile=${input.tagAuthFile}"
37 | def srcTlsVerifyArg = input.tagSourceTLSVerify?.trim()?.length() <= 0 ? "" : "--src-tls-verify=${input.tagSourceTLSVerify}"
38 | def destTlsVerifyArg = input.tagDestinationTLSVerify?.trim()?.length() <= 0 ? "" : "--dest-tls-verify=${input.tagDestinationTLSVerify}"
39 | def destCertDirArg = input.tagDestinationCertDir?.trim()?.length() <= 0 ? "" : "--dest-cert-dir=${input.tagDestinationCertDir}"
40 | def srcCertDirArg = input.tagSourceCertDir?.trim()?.length() <= 0 ? "" : "--src-cert-dir=${input.tagSourceCertDir}"
41 |
42 | def source = "docker://${input.registryFQDN}/${input.imageNamespace}/${input.imageName}:${input.imageVersion}"
43 | def destination = "docker://${input.registryFQDN}/${input.imageNamespace}/${input.imageName}:${input.deployDestinationVersionTag}"
44 |
45 | echo "Attempting to tag; ${source} -> ${destination}"
46 |
47 | sh "skopeo copy $authFileArg $srcTlsVerifyArg $destTlsVerifyArg $destCertDirArg $srcCertDirArg $source $destination"
48 |
49 | rollout(
50 | clusterAPI : input.clusterAPI,
51 | clusterToken : input.clusterToken,
52 | projectName : input.deployDestinationProjectName,
53 | resourceKindAndName: "deploymentconfig/${input.imageName}",
54 | loglevel: input.loglevel
55 | )
56 | }
57 |
--------------------------------------------------------------------------------
/vars/tagAndDeploy.txt:
--------------------------------------------------------------------------------
1 | # tagAndDeploy
2 |
3 | ## Summary
4 |
5 | Tag and deploy an image.
6 |
7 | ## Usage
8 |
9 | ### Requirements
10 |
11 | Requires Jenkins agent with:
12 | - OC
13 | - Skopeo
14 |
15 | ### Parameters
16 |
17 | The method supports the following parameters:
18 | ```groovy
19 | // tagAndDeploy.groovy#L4-L22
20 |
21 | //Required
22 | String imageName = ''
23 | String imageNamespace = ''
24 | String imageVersion = ''
25 | String registryFQDN = ''
26 | String deployDestinationVersionTag = ''
27 |
28 | //Optional
29 | String deployDestinationProjectName = ""
30 | String tagDestinationTLSVerify = "true"
31 | String tagSourceTLSVerify = "true"
32 | String tagAuthFile = "/var/run/secrets/kubernetes.io/dockerconfigjson/.dockerconfigjson"
33 | String tagDestinationCertDir = "/run/secrets/kubernetes.io/serviceaccount/"
34 | String tagSourceCertDir = "/run/secrets/kubernetes.io/serviceaccount/"
35 |
36 | //Optional - Platform
37 | String clusterAPI = ""
38 | String clusterToken = ""
39 | Integer loglevel = 0
40 | ```
41 |
42 | ### Example
43 |
44 | ```groovy
45 | // ../test/Jenkinsfile-tagAndDeploy#L39-L48
46 |
47 | stage("TEST: Can tag and deploy") {
48 | tagAndDeploy([
49 | registryFQDN : "${dockerRegistry}",
50 | imageNamespace : "pipelinelib-testing",
51 | imageName : "taganddeploy",
52 | imageVersion : "latest",
53 | deployDestinationVersionTag: "v2",
54 | deployDestinationProjectName: "pipelinelib-testing"
55 | ])
56 | }
57 | ```
58 |
59 | ### Local vs Remote cluster support
60 |
61 | As the underlying technology used is the [openshift-client-plugin](https://github.com/openshift/jenkins-client-plugin),
62 | the ability to connect to a the local cluster, a cluster via URL/Token or using
63 | [Jenkins configuration](https://github.com/openshift/jenkins-client-plugin#configuring-an-openshift-cluster) is as easy
64 | as setting the clusterAPI and clusterToken parameters.
65 |
--------------------------------------------------------------------------------
/vars/tagImage.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | class TagImageInput implements Serializable {
4 | //Required
5 | String sourceImagePath = ""
6 | String sourceImageName = ""
7 | String sourceImageTag = "latest"
8 | String toImagePath
9 |
10 | //Optional
11 | String toImageName = ""
12 | String toImageTag = ""
13 |
14 | //Optional - Platform
15 | String clusterAPI = ""
16 | String clusterToken = ""
17 | Integer loglevel = 0
18 |
19 | TagImageInput init() {
20 | if(!toImageName?.trim()) toImageName = sourceImageName
21 | if(!toImageTag?.trim()) toImageTag = sourceImageTag
22 | return this
23 | }
24 | }
25 |
26 | def call(Map input) {
27 | call(new TagImageInput(input).init())
28 | }
29 |
30 | def call(TagImageInput input) {
31 | assert input.sourceImageName?.trim() : "Param sourceImageName should be defined."
32 | assert input.sourceImagePath?.trim() : "Param sourceImagePath should be defined."
33 | assert input.sourceImageTag?.trim() : "Param sourceImageTag should be defined."
34 | assert input.toImagePath?.trim() : "Param toImagePath should be defined."
35 |
36 | openshift.loglevel(input.loglevel)
37 |
38 | openshift.withCluster(input.clusterAPI, input.clusterToken) {
39 | def source = "${input.sourceImagePath}/${input.sourceImageName}:${input.sourceImageTag}"
40 | def destination = "${input.toImagePath}/${input.toImageName}:${input.toImageTag}"
41 |
42 | echo "Attempting to tag; ${source} -> ${destination}"
43 |
44 | openshift.tag(source,destination)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/vars/tagImage.txt:
--------------------------------------------------------------------------------
1 | # tagImage
2 |
3 | ## Summary
4 |
5 | (Tag)[https://docs.openshift.com/container-platform/3.11/dev_guide/managing_images.html#tagging-images] an image.
6 |
7 | ## Usage
8 |
9 | ### Requirements
10 |
11 | Requires Jenkins agent with:
12 | - OC
13 |
14 | ### Parameters
15 |
16 | The method supports the following parameters:
17 | ```groovy
18 | // tagImage.groovy#L4-L17
19 |
20 | //Required
21 | String sourceImagePath = ""
22 | String sourceImageName = ""
23 | String sourceImageTag = "latest"
24 | String toImagePath
25 |
26 | //Optional
27 | String toImageName = ""
28 | String toImageTag = ""
29 |
30 | //Optional - Platform
31 | String clusterAPI = ""
32 | String clusterToken = ""
33 | Integer loglevel = 0
34 | ```
35 |
36 | ### Example
37 |
38 | ```groovy
39 | // ../test/Jenkinsfile-tagImage#L5-L14
40 |
41 | stage("TEST: Can tag image") {
42 | tagImage([
43 | sourceImagePath: "openshift",
44 | sourceImageName: "jenkins",
45 | sourceImageTag : "2",
46 | toImagePath: "pipelinelib-testing",
47 | toImageName : "tagimage",
48 | toImageTag : "2"
49 | ])
50 | }
51 | ```
52 |
53 | ### Local vs Remote cluster support
54 |
55 | As the underlying technology used is the [openshift-client-plugin](https://github.com/openshift/jenkins-client-plugin),
56 | the ability to connect to a the local cluster, a cluster via URL/Token or using
57 | [Jenkins configuration](https://github.com/openshift/jenkins-client-plugin#configuring-an-openshift-cluster) is as easy
58 | as setting the clusterAPI and clusterToken parameters.
--------------------------------------------------------------------------------
/vars/verifyDeployment.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | class ClusterInput implements Serializable {
4 | //Required
5 | String targetApp
6 |
7 | //Optional - Platform
8 | String clusterUrl = ""
9 | String clusterAPI = ""
10 | String clusterToken = ""
11 | String projectName = ""
12 | Integer loglevel = 0
13 | }
14 |
15 | // verify deployment
16 | def call(Map input) {
17 | call(new ClusterInput(input))
18 | }
19 |
20 | def call(ClusterInput input) {
21 | echo "verifyDeployment has been deprecated. Please call rollout with latest:false to verify a deployment"
22 | assert input.targetApp?.trim(): "Param targetApp should be defined."
23 |
24 | openshift.loglevel(input.loglevel)
25 |
26 | if (input.clusterUrl?.trim().length() > 0) {
27 | error "clusterUrl is deprecated and will be removed in the next release. Please use 'clusterAPI'"
28 | }
29 |
30 | rollout([
31 | clusterAPI : input.clusterAPI,
32 | clusterToken : input.clusterToken,
33 | projectName : input.projectName,
34 | resourceKindAndName: "dc/${input.targetApp}",
35 | latest : false
36 | ])
37 | }
38 |
--------------------------------------------------------------------------------
/vars/verifyDeployment.txt:
--------------------------------------------------------------------------------
1 | # verifyDeployment
2 |
3 | ## Summary
4 | DEPRECATION NOTICE
5 | This method has been deprecated in favor of the 'rollout' method in this repository. Calling that method with the
6 | 'latest' flag set to false will replicate the behavior of this method.
7 |
8 | Verify a DeploymentConfig has deployed successfully.
9 |
10 | ## Usage
11 |
12 | ### Requirements
13 |
14 | Requires Jenkins agent with:
15 | - OC
16 |
17 | ### Parameters
18 |
19 | The method supports the following parameters:
20 | ```groovy
21 | // verifyDeployment.groovy#L4-L12
22 |
23 | //Required
24 | String targetApp
25 |
26 | //Optional - Platform
27 | String clusterUrl = ""
28 | String clusterAPI = ""
29 | String clusterToken = ""
30 | String projectName = ""
31 | Integer loglevel = 0
32 | ```
33 |
34 | ### Example
35 |
36 | ```groovy
37 | // ../test/Jenkinsfile-verifyDeployment#L16-L20
38 |
39 | stage("TEST: Can verify deployment") {
40 | verifyDeployment([
41 | targetApp: "verifydeployment"
42 | ])
43 | }
44 | ```
45 |
46 | ### Local vs Remote cluster support
47 |
48 | As the underlying technology used is the [openshift-client-plugin](https://github.com/openshift/jenkins-client-plugin),
49 | the ability to connect to a the local cluster, a cluster via URL/Token or using
50 | [Jenkins configuration](https://github.com/openshift/jenkins-client-plugin#configuring-an-openshift-cluster) is as easy
51 | as setting the clusterAPI and clusterToken parameters.
52 |
--------------------------------------------------------------------------------
/vars/verifyService.groovy:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env groovy
2 |
3 | class VerifyServiceInput implements Serializable {
4 | //Required
5 | String serviceName = ""
6 |
7 | //Optional - Platform
8 | String clusterAPI = ""
9 | String clusterToken = ""
10 | String projectName = ""
11 | Integer loglevel = 0
12 | }
13 |
14 | def call(Map input) {
15 | call(new VerifyServiceInput(input))
16 | }
17 |
18 | def call(VerifyServiceInput input) {
19 | assert input.serviceName?.trim(): "Param serviceName should be defined."
20 |
21 | openshift.loglevel(input.loglevel)
22 |
23 | openshift.withCluster(input.clusterAPI, input.clusterToken) {
24 | openshift.withProject(input.projectName) {
25 | def connected = openshift.verifyService(input.serviceName)
26 | if (!connected) {
27 | error "Failed to connect to service: '${input.serviceName}' in ${openshift.project()}"
28 | }
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/vars/verifyService.txt:
--------------------------------------------------------------------------------
1 | # verifyService
2 |
3 | ## Summary
4 |
5 | Verify service has endpoints accepting connections.
6 |
7 | ## Usage
8 |
9 | ### Requirements
10 |
11 | Requires Jenkins agent with:
12 | - OC
13 |
14 | ### Parameters
15 |
16 | The method supports the following parameters:
17 | ```java
18 | // verifyService.groovy#L4-L11
19 |
20 | //Required
21 | String serviceName = ""
22 |
23 | //Optional - Platform
24 | String clusterAPI = ""
25 | String clusterToken = ""
26 | String projectName = ""
27 | Integer loglevel = 0
28 | ```
29 |
30 | ### Example
31 |
32 | ```java
33 | // ../test/Jenkinsfile-verifyService#L19-L23
34 |
35 | stage("TEST: Can verify service") {
36 | verifyService([
37 | serviceName: "verifyservice"
38 | ])
39 | }
40 | ```
41 |
42 | ### Local vs Remote cluster support
43 |
44 | As the method attempts to call service endpoints within the OCP SDN, the Jenkins Agent must be running on the cluster it is testing.
--------------------------------------------------------------------------------