Deploy Jenkins
@@ -844,8 +846,6 @@
-
-
Configuration
diff --git a/docs/docs/getting-started/latest/index.xml b/docs/docs/getting-started/latest/index.xml
index 5d3564a08..d6501db16 100644
--- a/docs/docs/getting-started/latest/index.xml
+++ b/docs/docs/getting-started/latest/index.xml
@@ -240,7 +240,7 @@ spec:
targets: "cicd/jobs/*.jenkins"
description: "Jenkins Operator repository"
repositoryBranch: master
- repositoryUrl: ssh://git@github.com:jenkinsci/kubernetes-operator.git</code></pre>
+ repositoryUrl: git@github.com:jenkinsci/kubernetes-operator.git</code></pre>
<p>and create a Kubernetes Secret (name of secret should be the same from <code>credentialID</code> field):</p>
<pre><code>apiVersion: v1
kind: Secret
@@ -403,14 +403,17 @@ stringData:
Plugin’s configuration is applied as groovy scripts or the <a href="https://github.com/jenkinsci/configuration-as-code-plugin">configuration as code plugin</a>.
Any plugin working for Jenkins can be installed by the Jenkins Operator.</p>
-<p>Pre-installed plugins:
-* configuration-as-code v1.47
-* git v4.5.0
-* job-dsl v1.77
-* kubernetes-credentials-provider v0.15
-* kubernetes v1.29.0
-* workflow-aggregator v2.6
-* workflow-job v2.40</p>
+<p>Pre-installed plugins:</p>
+
+<ul>
+<li>configuration-as-code v1.51</li>
+<li>git v4.7.2</li>
+<li>job-dsl v1.77</li>
+<li>kubernetes-credentials-provider v0.18-1</li>
+<li>kubernetes v1.30.0</li>
+<li>workflow-aggregator v2.6</li>
+<li>workflow-job v2.41</li>
+</ul>
<p>Rest of the plugins can be found in <a href="https://plugins.jenkins.io/">plugins repository</a>.</p>
@@ -435,19 +438,19 @@ Any plugin working for Jenkins can be installed by the Jenkins Operator.</p&g
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>master<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>basePlugins<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>kubernetes<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.28.6"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.30.0"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>workflow-job<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"2.40"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>workflow-aggregator<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"2.6"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>git<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"4.5.0"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"4.7.2"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>job-dsl<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.77"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>configuration-as-code<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.46"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.51"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>kubernetes-credentials-provider<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"0.15"</span></code></pre></div>
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"0.18-1"</span></code></pre></div>
<p>You can change their versions.</p>
<p>The <strong>Jenkins Operator</strong> will then automatically install plugins after the Jenkins master pod restart.</p>
diff --git a/docs/docs/getting-started/v0.5.x/index.html b/docs/docs/getting-started/v0.5.x/index.html
index 1d17315c5..bed9ab636 100644
--- a/docs/docs/getting-started/v0.5.x/index.html
+++ b/docs/docs/getting-started/v0.5.x/index.html
@@ -824,6 +824,8 @@ First Steps
+
+
Deploy Jenkins
@@ -846,8 +848,6 @@
-
-
Configuration
diff --git a/docs/docs/index.html b/docs/docs/index.html
index 001c8b57a..c8d69c8ed 100644
--- a/docs/docs/index.html
+++ b/docs/docs/index.html
@@ -789,10 +789,6 @@ Documentation
-
-
-
-
Installation
@@ -832,6 +828,10 @@
+
+
+
+
diff --git a/docs/docs/index.xml b/docs/docs/index.xml
index 6024f26d8..77dc07336 100644
--- a/docs/docs/index.xml
+++ b/docs/docs/index.xml
@@ -651,7 +651,7 @@ spec:
targets: "cicd/jobs/*.jenkins"
description: "Jenkins Operator repository"
repositoryBranch: master
- repositoryUrl: ssh://git@github.com:jenkinsci/kubernetes-operator.git</code></pre>
+ repositoryUrl: git@github.com:jenkinsci/kubernetes-operator.git</code></pre>
<p>and create a Kubernetes Secret (name of secret should be the same from <code>credentialID</code> field):</p>
<pre><code>apiVersion: v1
kind: Secret
@@ -2167,14 +2167,17 @@ stringData:
Plugin’s configuration is applied as groovy scripts or the <a href="https://github.com/jenkinsci/configuration-as-code-plugin">configuration as code plugin</a>.
Any plugin working for Jenkins can be installed by the Jenkins Operator.</p>
-<p>Pre-installed plugins:
-* configuration-as-code v1.47
-* git v4.5.0
-* job-dsl v1.77
-* kubernetes-credentials-provider v0.15
-* kubernetes v1.29.0
-* workflow-aggregator v2.6
-* workflow-job v2.40</p>
+<p>Pre-installed plugins:</p>
+
+<ul>
+<li>configuration-as-code v1.51</li>
+<li>git v4.7.2</li>
+<li>job-dsl v1.77</li>
+<li>kubernetes-credentials-provider v0.18-1</li>
+<li>kubernetes v1.30.0</li>
+<li>workflow-aggregator v2.6</li>
+<li>workflow-job v2.41</li>
+</ul>
<p>Rest of the plugins can be found in <a href="https://plugins.jenkins.io/">plugins repository</a>.</p>
@@ -2199,19 +2202,19 @@ Any plugin working for Jenkins can be installed by the Jenkins Operator.</p&g
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>master<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>basePlugins<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>kubernetes<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.28.6"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.30.0"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>workflow-job<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"2.40"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>workflow-aggregator<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"2.6"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>git<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"4.5.0"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"4.7.2"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>job-dsl<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.77"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>configuration-as-code<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.46"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.51"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>kubernetes-credentials-provider<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"0.15"</span></code></pre></div>
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"0.18-1"</span></code></pre></div>
<p>You can change their versions.</p>
<p>The <strong>Jenkins Operator</strong> will then automatically install plugins after the Jenkins master pod restart.</p>
diff --git a/docs/docs/installation/index.html b/docs/docs/installation/index.html
index eb6372364..4aa60183a 100644
--- a/docs/docs/installation/index.html
+++ b/docs/docs/installation/index.html
@@ -26,7 +26,7 @@
" />
-
+
@@ -766,6 +766,8 @@
+
Note on Operator’s nightly built images
+Note on Jenkins home Volume
@@ -808,18 +810,21 @@ Installation
This document describes installation procedure for Jenkins Operator.
-All container images can be found at virtuslab/jenkins-operator
+All container images can be found at virtuslab/jenkins-operator Docker Hub repository.
Requirements
-To run Jenkins Operator, you will need:
-- access to a Kubernetes cluster version 1.17+
-- kubectl
version 1.17+
+To run Jenkins Operator, you will need:
-Listed below are the two ways to deploy Jenkins Operator. For details on how to customize your Jenkins instance, refer to Getting Started
+
+- access to a Kubernetes cluster version
1.17+
+kubectl
version 1.17+
+
+
+Listed below are the two ways to deploy Jenkins Operator. For details on how to customize your Jenkins instance, refer to Getting Started.
Deploy Jenkins Operator using YAML’s
@@ -1649,6 +1654,18 @@ Configuring operator deployment
+Note on Operator’s nightly built images
+
+If you wish to use the newest, not yet released version of the Operator, you can use one of nightly built snapshot images, however the maintainers of this project cannot guarantee their stability.
+
+You can find nightly built images by heading to virtuslab/jenkins-operator Docker Hub repository and looking for images with tag in the form of “{git-hash}”, {git-hash} being the hash of master branch commit that you want to use snapshot of.
+
+Note on Jenkins home Volume
+
+Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users. One of the key points of this design is maintaining an immutable state of Jenkins.
+
+One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume as Jenkins home directory. It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory, as attempting to do so will result in Operator error.
+
@@ -1805,7 +1822,7 @@ Configuring operator deployment
- Last modified October 5, 2020
+ Last modified July 30, 2021
diff --git a/docs/docs/installation/index.xml b/docs/docs/installation/index.xml
index 9bc06edf8..37e38d051 100644
--- a/docs/docs/installation/index.xml
+++ b/docs/docs/installation/index.xml
@@ -4,7 +4,7 @@
https://jenkinsci.github.io/kubernetes-operator/docs/installation/
Recent Hugo news from gohugo.io
Hugo -- gohugo.io
- Mon, 05 Oct 2020 00:00:00 +0000
+ Fri, 30 Jul 2021 00:00:00 +0000
https://jenkinsci.github.io/kubernetes-operator/img/hugo.png
GoHugo.io
diff --git a/docs/sitemap.xml b/docs/sitemap.xml
index efa05ade3..b751f91fc 100644
--- a/docs/sitemap.xml
+++ b/docs/sitemap.xml
@@ -3,18 +3,18 @@
xmlns:xhtml="http://www.w3.org/1999/xhtml">
- https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/deploy-jenkins/
- 2021-01-25T00:00:00+00:00
+ https://jenkinsci.github.io/kubernetes-operator/docs/installation/
+ 2021-07-30T00:00:00+00:00
- https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/v0.5.x/deploy-jenkins/
+ https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/deploy-jenkins/
2021-01-25T00:00:00+00:00
- https://jenkinsci.github.io/kubernetes-operator/docs/installation/
- 2020-10-05T00:00:00+00:00
+ https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/v0.5.x/deploy-jenkins/
+ 2021-01-25T00:00:00+00:00
@@ -369,7 +369,7 @@
https://jenkinsci.github.io/kubernetes-operator/docs/developer-guide/
- 2021-06-10T00:00:00+00:00
+ 2021-07-30T00:00:00+00:00
diff --git a/website/package-lock.json b/website/package-lock.json
index 57c68fa43..fabb2bfa4 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -330,9 +330,9 @@
"dev": true
},
"caniuse-lite": {
- "version": "1.0.30001245",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001245.tgz",
- "integrity": "sha512-768fM9j1PKXpOCKws6eTo3RHmvTUsG9UrpT4WoREFeZgJBTi4/X9g565azS/rVUGtqb8nt7FjLeF5u4kukERnA==",
+ "version": "1.0.30001248",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001248.tgz",
+ "integrity": "sha512-NwlQbJkxUFJ8nMErnGtT0QTM2TJ33xgz4KXJSMIrjXIbDVdaYueGyjOrLKRtJC+rTiWfi6j5cnZN1NBiSBJGNw==",
"dev": true
},
"chalk": {
@@ -568,9 +568,9 @@
}
},
"electron-to-chromium": {
- "version": "1.3.780",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.780.tgz",
- "integrity": "sha512-2KQ9OYm9WMUNpAPA/4aerURl3hwRc9tNlpsiEj3Y8Gf7LVf26NzyLIX2v0hSagQwrS9+cWab+28A2GPKDoVNRA==",
+ "version": "1.3.792",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.792.tgz",
+ "integrity": "sha512-RM2O2xrNarM7Cs+XF/OE2qX/aBROyOZqqgP+8FXMXSuWuUqCfUUzg7NytQrzZU3aSqk1Qq6zqnVkJsbfMkIatg==",
"dev": true
},
"end-of-stream": {
From 37d0eac4e394d314bef2666aee850ed85b8312d8 Mon Sep 17 00:00:00 2001
From: sharmapulkit04
Date: Wed, 4 Aug 2021 16:06:14 +0530
Subject: [PATCH 13/26] Reimplemented the validation logic with caching the
security warnings - Reimplemented the validator interface - Updated manifests
to allocate more resources
---
Dockerfile | 2 +-
api/v1alpha2/jenkins_webhook.go | 268 ++++++++++++------
.../samples/jenkins.io_v1alpha2_jenkins.yaml | 71 ++++-
main.go | 3 +
webhook/all_in_one_v1alpha2.yaml | 9 +-
webhook/operator.yaml | 12 +-
webhook/webhook.yaml | 2 +-
7 files changed, 274 insertions(+), 93 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index ff840ea45..caaced1d7 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -19,6 +19,7 @@ COPY internal/ internal/
COPY pkg/ pkg/
COPY version/ version/
COPY main.go main.go
+RUN mkdir plugins/
# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -ldflags "-w $CTIMEVAR" -o manager main.go
@@ -29,5 +30,4 @@ FROM gcr.io/distroless/static:nonroot
WORKDIR /
COPY --from=builder /workspace/manager .
USER 65532:65532
-
ENTRYPOINT ["/manager"]
diff --git a/api/v1alpha2/jenkins_webhook.go b/api/v1alpha2/jenkins_webhook.go
index 494fdb802..97af23c99 100644
--- a/api/v1alpha2/jenkins_webhook.go
+++ b/api/v1alpha2/jenkins_webhook.go
@@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
+ http://www.apache.org/lictenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,10 +17,13 @@ limitations under the License.
package v1alpha2
import (
+ "compress/gzip"
"encoding/json"
"errors"
+ "io"
"io/ioutil"
"net/http"
+ "os"
"time"
"github.com/jenkinsci/kubernetes-operator/pkg/plugins"
@@ -32,8 +35,16 @@ import (
"sigs.k8s.io/controller-runtime/pkg/webhook"
)
-// log is for logging in this package.
-var jenkinslog = logf.Log.WithName("jenkins-resource")
+var (
+ jenkinslog = logf.Log.WithName("jenkins-resource") // log is for logging in this package.
+ isRetrieved bool = false // For checking whether the data file is downloaded and extracted or not
+)
+
+const (
+ hosturl string = "https://ci.jenkins.io/job/Infra/job/plugin-site-api/job/generate-data/lastSuccessfulBuild/artifact/plugins.json.gzip" // Url for downloading the plugins file
+ compressedFile string = "/tmp/plugins.json.gzip" // location where the gzip file will be downloaded
+ pluginDataFile string = "/tmp/plugins.json" // location where the file will be extracted
+)
func (in *Jenkins) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
@@ -72,8 +83,13 @@ func (in *Jenkins) ValidateDelete() error {
return nil
}
-type Warnings struct {
- Warnings []Warning `json:"securityWarnings"`
+type PluginsInfo struct {
+ Plugins []PluginInfo `json:"plugins"`
+}
+
+type PluginInfo struct {
+ Name string `json:"name"`
+ SecurityWarnings []Warning `json:"securityWarnings"`
}
type Warning struct {
@@ -83,109 +99,203 @@ type Warning struct {
URL string `json:"url"`
Active bool `json:"active"`
}
+
type Version struct {
FirstVersion string `json:"firstVersion"`
LastVersion string `json:"lastVersion"`
}
-const APIURL string = "https://plugins.jenkins.io/api/plugin/"
-
-func MakeSemanticVersion(version string) string {
- version = "v" + version
- return semver.Canonical(version)
+type PluginData struct {
+ Version string
+ Kind string
}
-func CompareVersions(firstVersion string, lastVersion string, pluginVersion string) bool {
- firstSemVer := MakeSemanticVersion(firstVersion)
- lastSemVer := MakeSemanticVersion(lastVersion)
- pluginSemVer := MakeSemanticVersion(pluginVersion)
- if semver.Compare(pluginSemVer, firstSemVer) == -1 || semver.Compare(pluginSemVer, lastSemVer) == 1 {
- return false
- }
- return true
-}
+// Validates security warnings for both updating and creating a Jenkins CR
+func Validate(r Jenkins) error {
-func CheckSecurityWarnings(pluginName string, pluginVersion string) (bool, error) {
- jenkinslog.Info("checking security warnings", "plugin: ", pluginName)
- pluginURL := APIURL + pluginName
- client := &http.Client{
- Timeout: time.Second * 30,
- }
- request, err := http.NewRequest("GET", pluginURL, nil)
- if err != nil {
- return false, err
- }
- request.Header.Add("Accept", "application/json")
- request.Header.Add("Content-Type", "application/json")
- response, err := client.Do(request)
- if err != nil {
- return false, err
- }
- defer response.Body.Close()
- bodyBytes, err := ioutil.ReadAll(response.Body)
+ pluginset := make(map[string]PluginData)
+ var warningmsg string
+ basePlugins := plugins.BasePlugins()
+ temp, err := NewPluginsInfo()
+ AllPluginData := *temp
if err != nil {
- return false, err
+ return err
}
- securityWarnings := Warnings{}
- jsonErr := json.Unmarshal(bodyBytes, &securityWarnings)
- if jsonErr != nil {
- return false, err
+ for _, plugin := range basePlugins {
+ // Only Update the map if the plugin is not present or a lower version is being used
+ if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
+ jenkinslog.Info("Validate", plugin.Name, plugin.Version)
+ pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "base"}
+ }
}
- jenkinslog.Info("Validate()", "warnings", securityWarnings)
+ for _, plugin := range r.Spec.Master.Plugins {
+ if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
+ jenkinslog.Info("Validate", plugin.Name, plugin.Version)
+ pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "user-defined"}
+ }
+ }
- for _, warning := range securityWarnings.Warnings {
- for _, version := range warning.Versions {
- firstVersion := version.FirstVersion
- lastVersion := version.LastVersion
- if len(firstVersion) == 0 {
- firstVersion = "0" // setting default value in case of empty string
- }
- if len(lastVersion) == 0 {
- lastVersion = pluginVersion // setting default value in case of empty string
+ jenkinslog.Info("Checking through all the warnings")
+ for _, plugin := range AllPluginData.Plugins {
+
+ if pluginData, ispresent := pluginset[plugin.Name]; ispresent {
+ jenkinslog.Info("Checking for plugin", "name", plugin.Name)
+ for _, warning := range plugin.SecurityWarnings {
+ for _, version := range warning.Versions {
+ firstVersion := version.FirstVersion
+ lastVersion := version.LastVersion
+ if len(firstVersion) == 0 {
+ firstVersion = "0" // setting default value in case of empty string
+ }
+ if len(lastVersion) == 0 {
+ lastVersion = pluginData.Version // setting default value in case of empty string
+ }
+
+ if CompareVersions(firstVersion, lastVersion, pluginData.Version) {
+ jenkinslog.Info("security Vulnerabilities detected", "message", warning.Message, "Check security Advisory", warning.URL)
+ warningmsg += "Security Vulnerabilities detected in " + pluginData.Kind + " plugin " + plugin.Name + "\n"
+
+ }
+
+ }
}
- if CompareVersions(firstVersion, lastVersion, pluginVersion) {
- jenkinslog.Info("security Vulnerabilities detected", "message", warning.Message, "Check security Advisory", warning.URL)
- return true, nil
- }
}
+
}
- return false, nil
-}
+ if len(warningmsg) > 0 {
+ return errors.New(warningmsg)
+ }
-func Validate(r Jenkins) error {
- basePlugins := plugins.BasePlugins()
- var warnings string = ""
+ return nil
- for _, plugin := range basePlugins {
- name := plugin.Name
- version := plugin.Version
- hasWarnings, err := CheckSecurityWarnings(name, version)
- if err != nil {
- return err
- }
- if hasWarnings {
- warnings += "Security Vulnerabilities detected in base plugin:" + name
+}
+
+// Returns an object containing information of all the plugins present in the security center
+func NewPluginsInfo() (*PluginsInfo, error) {
+ var AllPluginData PluginsInfo
+ for i := 0; i < 28; i++ {
+ if isRetrieved {
+ break
}
+ time.Sleep(1 * time.Second)
+ }
+ if !isRetrieved {
+ jenkinslog.Info("Plugins Data file hasn't been downloaded and extracted")
+ return &AllPluginData, errors.New("plugins data file not found")
}
- for _, plugin := range r.Spec.Master.Plugins {
- name := plugin.Name
- version := plugin.Version
- hasWarnings, err := CheckSecurityWarnings(name, version)
+ jsonFile, err := os.Open(pluginDataFile)
+ if err != nil {
+ jenkinslog.Info("Failed to open the Plugins Data File")
+ return &AllPluginData, err
+ }
+ defer jsonFile.Close()
+
+ byteValue, err := ioutil.ReadAll(jsonFile)
+ if err != nil {
+ jenkinslog.Info("Failed to convert the JSON file into a byte array")
+ return &AllPluginData, err
+ }
+ err = json.Unmarshal(byteValue, &AllPluginData)
+ if err != nil {
+ jenkinslog.Info("Failed to decode the Plugin JSON data file")
+ return &AllPluginData, err
+ }
+
+ return &AllPluginData, nil
+}
+
+// Downloads and extracts the JSON file in every 12 hours
+func RetrieveDataFile() {
+ for {
+ jenkinslog.Info("Retreiving file", "Host Url", hosturl)
+ err := Download()
if err != nil {
- return err
+ jenkinslog.Info("Retrieving File", "Error while downloading", err)
+ continue
}
- if hasWarnings {
- warnings += "Security Vulnerabilities detected in the user defined plugin: " + name
+
+ jenkinslog.Info("Retrieve File", "Successfully downloaded", compressedFile)
+ err = Extract()
+ if err != nil {
+ jenkinslog.Info("Retreive File", "Error while extracting", err)
+ continue
}
+ jenkinslog.Info("Retreive File", "Successfully extracted", pluginDataFile)
+ isRetrieved = true
+ time.Sleep(12 * time.Hour)
+
}
- if len(warnings) > 0 {
- return errors.New(warnings)
+}
+
+func Download() error {
+
+ out, err := os.Create(compressedFile)
+ if err != nil {
+ return err
+ }
+ defer out.Close()
+
+ client := http.Client{
+ Timeout: 2000 * time.Second,
+ }
+
+ resp, err := client.Get(hosturl)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ jenkinslog.Info("Successfully Downloaded")
+ _, err = io.Copy(out, resp.Body)
+ if err != nil {
+ return err
}
return nil
+
+}
+
+func Extract() error {
+ reader, err := os.Open(compressedFile)
+
+ if err != nil {
+ return err
+ }
+ defer reader.Close()
+ archive, err := gzip.NewReader(reader)
+ if err != nil {
+ return err
+ }
+
+ defer archive.Close()
+ writer, err := os.Create(pluginDataFile)
+ if err != nil {
+ return err
+ }
+ defer writer.Close()
+
+ _, err = io.Copy(writer, archive)
+ return err
+
+}
+
+// returns a semantic version that can be used for comparision
+func MakeSemanticVersion(version string) string {
+ version = "v" + version
+ return semver.Canonical(version)
+}
+
+// Compare if the current version lies between first version and last version
+func CompareVersions(firstVersion string, lastVersion string, pluginVersion string) bool {
+ firstSemVer := MakeSemanticVersion(firstVersion)
+ lastSemVer := MakeSemanticVersion(lastVersion)
+ pluginSemVer := MakeSemanticVersion(pluginVersion)
+ if semver.Compare(pluginSemVer, firstSemVer) == -1 || semver.Compare(pluginSemVer, lastSemVer) == 1 {
+ return false
+ }
+ return true
}
diff --git a/config/samples/jenkins.io_v1alpha2_jenkins.yaml b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
index b451d5dab..be33732a9 100644
--- a/config/samples/jenkins.io_v1alpha2_jenkins.yaml
+++ b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
@@ -1,8 +1,8 @@
apiVersion: jenkins.io/v1alpha2
kind: Jenkins
metadata:
- name: example
- namespace: default
+ name: example-8
+ namespace: default
spec:
configurationAsCode:
configurations: []
@@ -14,6 +14,7 @@ spec:
name: ""
jenkinsAPISettings:
authorizationStrategy: createUser
+ ValidateSecurityWarnings: true
master:
disableCSRFProtection: false
containers:
@@ -47,6 +48,72 @@ spec:
requests:
cpu: "1"
memory: 500Mi
+ plugins:
+ - name: mailer
+ version: "1.19"
+ - name: script-security
+ version: "1.18"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: credentials
+ version: "2.1"
+ - name: ssh-credentials
+ version: "1.1"
+ - name: junit
+ version: "1.2"
+ - name: matrix-project
+ version: "1.1"
+ - name: git-client
+ version: "2.8.4"
+ - name: pipeline-model-definition
+ version: "1.3.0"
+ - name: favorite
+ version: "2"
+ - name: workflow-cps
+ version: "2"
+
seedJobs:
- id: jenkins-operator
targets: "cicd/jobs/*.jenkins"
diff --git a/main.go b/main.go
index 8bc382ead..3cd399f6a 100644
--- a/main.go
+++ b/main.go
@@ -95,6 +95,9 @@ func main() {
opts := zap.Options{
Development: true,
}
+
+ go v1alpha2.RetrieveDataFile()
+
opts.BindFlags(flag.CommandLine)
flag.Parse()
diff --git a/webhook/all_in_one_v1alpha2.yaml b/webhook/all_in_one_v1alpha2.yaml
index e53fc659f..0d878dd2d 100644
--- a/webhook/all_in_one_v1alpha2.yaml
+++ b/webhook/all_in_one_v1alpha2.yaml
@@ -222,6 +222,7 @@ subjects:
- kind: ServiceAccount
name: jenkins-operator
---
+---
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -246,7 +247,7 @@ spec:
- /manager
args:
- --leader-elect
- image: jenkins-operator:6f33fe82-dirty
+ image: jenkins-operator:52fe5fe9-dirty
name: jenkins-operator
imagePullPolicy: IfNotPresent
securityContext:
@@ -278,12 +279,12 @@ spec:
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
- readOnly: true
+ readOnly: false
volumes:
- name: cert
secret:
defaultMode: 420
- secretName: webhook-server-cert
+ secretName: webhook-server-cert
terminationGracePeriodSeconds: 10
---
apiVersion: cert-manager.io/v1
@@ -315,7 +316,6 @@ spec:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
- creationTimestamp: null
name: validating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: default/webhook-certificate
@@ -330,6 +330,7 @@ webhooks:
path: /validate-jenkins-io-v1alpha2-jenkins
failurePolicy: Fail
name: vjenkins.kb.io
+ timeoutSeconds: 30
rules:
- apiGroups:
- jenkins.io
diff --git a/webhook/operator.yaml b/webhook/operator.yaml
index 81cbdf98e..c056ba8e0 100644
--- a/webhook/operator.yaml
+++ b/webhook/operator.yaml
@@ -1,3 +1,4 @@
+---
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -41,11 +42,11 @@ spec:
periodSeconds: 10
resources:
limits:
- cpu: 100m
- memory: 30Mi
+ cpu: 200m
+ memory: 200Mi
requests:
cpu: 100m
- memory: 20Mi
+ memory: 80Mi
env:
- name: WATCH_NAMESPACE
valueFrom:
@@ -53,12 +54,11 @@ spec:
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
- name: cert
- readOnly: true
+ name: cert
volumes:
- name: cert
secret:
defaultMode: 420
- secretName: webhook-server-cert
+ secretName: webhook-server-cert
terminationGracePeriodSeconds: 10
---
diff --git a/webhook/webhook.yaml b/webhook/webhook.yaml
index 3a86ab0b1..9cc2a2b74 100644
--- a/webhook/webhook.yaml
+++ b/webhook/webhook.yaml
@@ -1,7 +1,6 @@
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
- creationTimestamp: null
name: validating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: default/webhook-certificate
@@ -16,6 +15,7 @@ webhooks:
path: /validate-jenkins-io-v1alpha2-jenkins
failurePolicy: Fail
name: vjenkins.kb.io
+ timeoutSeconds: 30
rules:
- apiGroups:
- jenkins.io
From 8453b3e9fecfa8ad7fe06732923476c424f7e8c4 Mon Sep 17 00:00:00 2001
From: Szymon Fugas
Date: Thu, 5 Aug 2021 17:27:19 +0200
Subject: [PATCH 14/26] Add an issue template for documentation (#613)
---
.github/ISSUE_TEMPLATE/documentation.md | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100644 .github/ISSUE_TEMPLATE/documentation.md
diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md
new file mode 100644
index 000000000..a0ed0b42c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/documentation.md
@@ -0,0 +1,14 @@
+---
+name: "📚 Documentation issue"
+about: Suggest changes to project's documentation
+title: ''
+labels: 'documentation'
+projects: ''
+assignees: ''
+---
+
+**Relevant links*
+Link(s) to the section(s) of documentation that are outdated or otherwise wrong
+
+**Description**
+Description of the changes you would like to see
\ No newline at end of file
From 858f0f4c7289bd518ac419d57116907940109429 Mon Sep 17 00:00:00 2001
From: Szymon Fugas
Date: Thu, 5 Aug 2021 17:28:01 +0200
Subject: [PATCH 15/26] Docs: add info on restricted volumeMounts other than
jenkins-home(#612)
* Update note in installation docs
* Update Helm chart default values.yaml
* Update schema
---
chart/jenkins-operator/values.yaml | 5 +++--
.../en/docs/Getting Started/latest/schema.md | 7 ++++++-
.../content/en/docs/Installation/_index.md | 20 +++++++++++++++----
3 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/chart/jenkins-operator/values.yaml b/chart/jenkins-operator/values.yaml
index 1c92fb900..60c992cd2 100644
--- a/chart/jenkins-operator/values.yaml
+++ b/chart/jenkins-operator/values.yaml
@@ -120,8 +120,9 @@ jenkins:
claimName: jenkins-backup
# volumeMounts are mounts for Jenkins pod
- # Note that attempting to overwrite default mount settings for Jenkins home directory will result in Operator error
- # See https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-jenkins-home-volume
+ # Note that attempting to overwrite default mount settings for restricted,
+ # non-configurable volumeMounts will result in Operator error
+ # See https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts for details
volumeMounts: []
# defines authorization strategy of the operator for the Jenkins API
diff --git a/website/content/en/docs/Getting Started/latest/schema.md b/website/content/en/docs/Getting Started/latest/schema.md
index 2a1444c7d..58638cbd2 100644
--- a/website/content/en/docs/Getting Started/latest/schema.md
+++ b/website/content/en/docs/Getting Started/latest/schema.md
@@ -661,7 +661,12 @@ Values defined by an Env with a duplicate key will take precedence.
(Optional)
-Pod volumes to mount into the container’s filesystem.
+
+Pod volumes to mount into the container’s filesystem. More info:
+
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+
+
diff --git a/website/content/en/docs/Installation/_index.md b/website/content/en/docs/Installation/_index.md
index fcd6ba282..17b8df645 100644
--- a/website/content/en/docs/Installation/_index.md
+++ b/website/content/en/docs/Installation/_index.md
@@ -883,7 +883,19 @@ If you wish to use the newest, not yet released version of the Operator, you can
You can find nightly built images by heading to [virtuslab/jenkins-operator](https://hub.docker.com/r/virtuslab/jenkins-operator) Docker Hub repository and looking for images with tag in the form of "{git-hash}", {git-hash} being the hash of master branch commit that you want to use snapshot of.
-## Note on Jenkins home Volume
-Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users. One of the key points of this design is maintaining an immutable state of Jenkins.
-
-One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume as Jenkins home directory. It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory, as attempting to do so will result in Operator error.
\ No newline at end of file
+## Note on restricted Jenkins controller pod volumeMounts
+Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users.
+One of the key points of this design is maintaining an immutable state of Jenkins.
+
+One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume
+(jenkins-home) as Jenkins home directory.
+It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory,
+as attempting to do so will result in Operator error.
+
+jenkins-home is not the only Jenkins controller pod volumeMount that is non-configurable and managed by Operator,
+below is the full list of those volumeMounts:
+
+* jenkins-home
+* scripts
+* init-configuration
+* operator-credentials
\ No newline at end of file
From b82fc7c7640a28a6b4912b533b9534d7e81288bb Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 6 Aug 2021 10:03:57 +0200
Subject: [PATCH 16/26] Auto-updated docs (#616)
Co-authored-by: Sig00rd
---
docs/docs/getting-started/latest/index.xml | 7 ++++-
.../getting-started/latest/schema/index.html | 9 ++++--
docs/docs/index.xml | 7 ++++-
docs/docs/installation/index.html | 22 +++++++++++---
website/package-lock.json | 30 +++++++++----------
5 files changed, 52 insertions(+), 23 deletions(-)
diff --git a/docs/docs/getting-started/latest/index.xml b/docs/docs/getting-started/latest/index.xml
index d6501db16..0b4fccb10 100644
--- a/docs/docs/getting-started/latest/index.xml
+++ b/docs/docs/getting-started/latest/index.xml
@@ -1679,7 +1679,12 @@ Values defined by an Env with a duplicate key will take precedence.</p>
</td>
<td>
<em>(Optional)</em>
-<p>Pod volumes to mount into the container’s filesystem.</p>
+<p>
+Pod volumes to mount into the container’s filesystem. More info:
+<a href="https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts">
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+</a>
+</p>
</td>
</tr>
<tr>
diff --git a/docs/docs/getting-started/latest/schema/index.html b/docs/docs/getting-started/latest/schema/index.html
index 59ee07c21..f31e941da 100644
--- a/docs/docs/getting-started/latest/schema/index.html
+++ b/docs/docs/getting-started/latest/schema/index.html
@@ -32,7 +32,7 @@
">
-
+
@@ -1471,7 +1471,12 @@
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+
+
diff --git a/docs/docs/index.xml b/docs/docs/index.xml
index 77dc07336..5f1c71ccd 100644
--- a/docs/docs/index.xml
+++ b/docs/docs/index.xml
@@ -6194,7 +6194,12 @@ Values defined by an Env with a duplicate key will take precedence.</p>
</td>
<td>
<em>(Optional)</em>
-<p>Pod volumes to mount into the container’s filesystem.</p>
+<p>
+Pod volumes to mount into the container’s filesystem. More info:
+<a href="https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts">
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+</a>
+</p>
</td>
</tr>
<tr>
diff --git a/docs/docs/installation/index.html b/docs/docs/installation/index.html
index 4aa60183a..728a3edb5 100644
--- a/docs/docs/installation/index.html
+++ b/docs/docs/installation/index.html
@@ -767,7 +767,7 @@
Configuring operator deployment
Note on Operator’s nightly built images
-Note on Jenkins home Volume
+Note on restricted Jenkins controller pod volumeMounts
@@ -1660,11 +1660,25 @@ Note on Operator’s nightl
You can find nightly built images by heading to virtuslab/jenkins-operator Docker Hub repository and looking for images with tag in the form of “{git-hash}”, {git-hash} being the hash of master branch commit that you want to use snapshot of.
-Note on Jenkins home Volume
+Note on restricted Jenkins controller pod volumeMounts
-Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users. One of the key points of this design is maintaining an immutable state of Jenkins.
+Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users.
+One of the key points of this design is maintaining an immutable state of Jenkins.
-One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume as Jenkins home directory. It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory, as attempting to do so will result in Operator error.
+One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume
+(jenkins-home) as Jenkins home directory.
+It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory,
+as attempting to do so will result in Operator error.
+
+jenkins-home is not the only Jenkins controller pod volumeMount that is non-configurable and managed by Operator,
+below is the full list of those volumeMounts:
+
+
+- jenkins-home
+- scripts
+- init-configuration
+- operator-credentials
+
diff --git a/website/package-lock.json b/website/package-lock.json
index fabb2bfa4..196e451f1 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -288,16 +288,16 @@
}
},
"browserslist": {
- "version": "4.16.6",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
- "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
+ "version": "4.16.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.7.tgz",
+ "integrity": "sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA==",
"dev": true,
"requires": {
- "caniuse-lite": "^1.0.30001219",
+ "caniuse-lite": "^1.0.30001248",
"colorette": "^1.2.2",
- "electron-to-chromium": "^1.3.723",
+ "electron-to-chromium": "^1.3.793",
"escalade": "^3.1.1",
- "node-releases": "^1.1.71"
+ "node-releases": "^1.1.73"
}
},
"cache-base": {
@@ -330,9 +330,9 @@
"dev": true
},
"caniuse-lite": {
- "version": "1.0.30001248",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001248.tgz",
- "integrity": "sha512-NwlQbJkxUFJ8nMErnGtT0QTM2TJ33xgz4KXJSMIrjXIbDVdaYueGyjOrLKRtJC+rTiWfi6j5cnZN1NBiSBJGNw==",
+ "version": "1.0.30001249",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001249.tgz",
+ "integrity": "sha512-vcX4U8lwVXPdqzPWi6cAJ3FnQaqXbBqy/GZseKNQzRj37J7qZdGcBtxq/QLFNLLlfsoXLUdHw8Iwenri86Tagw==",
"dev": true
},
"chalk": {
@@ -568,9 +568,9 @@
}
},
"electron-to-chromium": {
- "version": "1.3.792",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.792.tgz",
- "integrity": "sha512-RM2O2xrNarM7Cs+XF/OE2qX/aBROyOZqqgP+8FXMXSuWuUqCfUUzg7NytQrzZU3aSqk1Qq6zqnVkJsbfMkIatg==",
+ "version": "1.3.796",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.796.tgz",
+ "integrity": "sha512-agwJFgM0FUC1UPPbQ4aII3HamaaJ09fqWGAWYHmzxDWqdmTleCHyyA0kt3fJlTd5M440IaeuBfzXzXzCotnZcQ==",
"dev": true
},
"end-of-stream": {
@@ -1338,9 +1338,9 @@
"dev": true
},
"nan": {
- "version": "2.14.2",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
- "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
+ "version": "2.15.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
+ "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==",
"dev": true,
"optional": true
},
From b400a420e55209fcb9ee14f7cc85121737cd10d3 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 6 Aug 2021 13:06:12 +0200
Subject: [PATCH 17/26] Auto-updated docs (#617)
Co-authored-by: Sig00rd
---
website/package-lock.json | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/website/package-lock.json b/website/package-lock.json
index 196e451f1..334ea961a 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -568,9 +568,9 @@
}
},
"electron-to-chromium": {
- "version": "1.3.796",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.796.tgz",
- "integrity": "sha512-agwJFgM0FUC1UPPbQ4aII3HamaaJ09fqWGAWYHmzxDWqdmTleCHyyA0kt3fJlTd5M440IaeuBfzXzXzCotnZcQ==",
+ "version": "1.3.798",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.798.tgz",
+ "integrity": "sha512-fwsr6oXAORoV9a6Ak2vMCdXfmHIpAGgpOGesulS1cbGgJmrMl3H+GicUyRG3t+z9uHTMrIuMTleFDW+EUFYT3g==",
"dev": true
},
"end-of-stream": {
@@ -925,9 +925,9 @@
}
},
"graceful-fs": {
- "version": "4.2.6",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
- "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
+ "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
"dev": true
},
"has-flag": {
From 1d2651d43fb1616aa49611554fd678c4888b9bd5 Mon Sep 17 00:00:00 2001
From: sharmapulkit04
Date: Fri, 6 Aug 2021 19:01:27 +0530
Subject: [PATCH 18/26] Updated Validation logic - Defined a security manager
struct to cache all the plugin data - Added flag to make validating security
warnings optional while deploying the operator
---
api/v1alpha2/jenkins_webhook.go | 197 ++++++++++--------
.../samples/jenkins.io_v1alpha2_jenkins.yaml | 74 +------
main.go | 14 +-
webhook/all_in_one_v1alpha2.yaml | 11 +-
webhook/operator.yaml | 1 +
5 files changed, 129 insertions(+), 168 deletions(-)
diff --git a/api/v1alpha2/jenkins_webhook.go b/api/v1alpha2/jenkins_webhook.go
index 97af23c99..56750fc28 100644
--- a/api/v1alpha2/jenkins_webhook.go
+++ b/api/v1alpha2/jenkins_webhook.go
@@ -36,14 +36,9 @@ import (
)
var (
- jenkinslog = logf.Log.WithName("jenkins-resource") // log is for logging in this package.
- isRetrieved bool = false // For checking whether the data file is downloaded and extracted or not
-)
-
-const (
- hosturl string = "https://ci.jenkins.io/job/Infra/job/plugin-site-api/job/generate-data/lastSuccessfulBuild/artifact/plugins.json.gzip" // Url for downloading the plugins file
- compressedFile string = "/tmp/plugins.json.gzip" // location where the gzip file will be downloaded
- pluginDataFile string = "/tmp/plugins.json" // location where the file will be extracted
+ jenkinslog = logf.Log.WithName("jenkins-resource") // log is for logging in this package.
+ PluginsDataManager PluginDataManager = *NewPluginsDataManager()
+ _ webhook.Validator = &Jenkins{}
)
func (in *Jenkins) SetupWebhookWithManager(mgr ctrl.Manager) error {
@@ -57,8 +52,6 @@ func (in *Jenkins) SetupWebhookWithManager(mgr ctrl.Manager) error {
// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation.
// +kubebuilder:webhook:path=/validate-jenkins-io-jenkins-io-v1alpha2-jenkins,mutating=false,failurePolicy=fail,sideEffects=None,groups=jenkins.io.jenkins.io,resources=jenkins,verbs=create;update,versions=v1alpha2,name=vjenkins.kb.io,admissionReviewVersions={v1,v1beta1}
-var _ webhook.Validator = &Jenkins{}
-
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
func (in *Jenkins) ValidateCreate() error {
if in.Spec.ValidateSecurityWarnings {
@@ -83,6 +76,15 @@ func (in *Jenkins) ValidateDelete() error {
return nil
}
+type PluginDataManager struct {
+ pluginDataCache PluginsInfo
+ hosturl string
+ compressedFilePath string
+ pluginDataFile string
+ iscached bool
+ maxattempts int
+}
+
type PluginsInfo struct {
Plugins []PluginInfo `json:"plugins"`
}
@@ -112,36 +114,27 @@ type PluginData struct {
// Validates security warnings for both updating and creating a Jenkins CR
func Validate(r Jenkins) error {
-
pluginset := make(map[string]PluginData)
- var warningmsg string
+ var faultybaseplugins string
+ var faultyuserplugins string
basePlugins := plugins.BasePlugins()
- temp, err := NewPluginsInfo()
- AllPluginData := *temp
- if err != nil {
- return err
- }
for _, plugin := range basePlugins {
// Only Update the map if the plugin is not present or a lower version is being used
if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
- jenkinslog.Info("Validate", plugin.Name, plugin.Version)
pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "base"}
}
}
for _, plugin := range r.Spec.Master.Plugins {
if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
- jenkinslog.Info("Validate", plugin.Name, plugin.Version)
pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "user-defined"}
}
}
- jenkinslog.Info("Checking through all the warnings")
- for _, plugin := range AllPluginData.Plugins {
-
+ for _, plugin := range PluginsDataManager.pluginDataCache.Plugins {
if pluginData, ispresent := pluginset[plugin.Name]; ispresent {
- jenkinslog.Info("Checking for plugin", "name", plugin.Name)
+ var hasvulnerabilities bool
for _, warning := range plugin.SecurityWarnings {
for _, version := range warning.Versions {
firstVersion := version.FirstVersion
@@ -154,113 +147,121 @@ func Validate(r Jenkins) error {
}
if CompareVersions(firstVersion, lastVersion, pluginData.Version) {
- jenkinslog.Info("security Vulnerabilities detected", "message", warning.Message, "Check security Advisory", warning.URL)
- warningmsg += "Security Vulnerabilities detected in " + pluginData.Kind + " plugin " + plugin.Name + "\n"
-
+ jenkinslog.Info("Security Vulnerability detected in "+pluginData.Kind+" "+plugin.Name+":"+pluginData.Version, "Warning message", warning.Message, "For more details,check security advisory", warning.URL)
+ hasvulnerabilities = true
}
-
}
}
+ if hasvulnerabilities {
+ if pluginData.Kind == "base" {
+ faultybaseplugins += plugin.Name + ":" + pluginData.Version + "\n"
+ } else {
+ faultyuserplugins += plugin.Name + ":" + pluginData.Version + "\n"
+ }
+ }
}
-
}
-
- if len(warningmsg) > 0 {
- return errors.New(warningmsg)
+ if len(faultybaseplugins) > 0 || len(faultyuserplugins) > 0 {
+ var errormsg string
+ if len(faultybaseplugins) > 0 {
+ errormsg += "Security vulnerabilities detected in the following base plugins: \n" + faultybaseplugins
+ }
+ if len(faultyuserplugins) > 0 {
+ errormsg += "Security vulnerabilities detected in the following user-defined plugins: \n" + faultyuserplugins
+ }
+ return errors.New(errormsg)
}
return nil
-
}
-// Returns an object containing information of all the plugins present in the security center
-func NewPluginsInfo() (*PluginsInfo, error) {
- var AllPluginData PluginsInfo
- for i := 0; i < 28; i++ {
- if isRetrieved {
- break
- }
- time.Sleep(1 * time.Second)
- }
- if !isRetrieved {
- jenkinslog.Info("Plugins Data file hasn't been downloaded and extracted")
- return &AllPluginData, errors.New("plugins data file not found")
+func NewPluginsDataManager() *PluginDataManager {
+ return &PluginDataManager{
+ hosturl: "https://ci.jenkins.io/job/Infra/job/plugin-site-api/job/generate-data/lastSuccessfulBuild/artifact/plugins.json.gzip",
+ compressedFilePath: "/tmp/plugins.json.gzip",
+ pluginDataFile: "/tmp/plugins.json",
+ iscached: false,
+ maxattempts: 5,
}
+}
- jsonFile, err := os.Open(pluginDataFile)
- if err != nil {
- jenkinslog.Info("Failed to open the Plugins Data File")
- return &AllPluginData, err
- }
- defer jsonFile.Close()
+// Downloads extracts and caches the JSON data in every 12 hours
+func (in *PluginDataManager) CachePluginData(ch chan bool) {
+ for {
+ jenkinslog.Info("Initializing/Updating the plugin data cache")
+ var isdownloaded, isextracted, iscached bool
+ var err error
+ for i := 0; i < in.maxattempts; i++ {
+ err = in.Download()
+ if err == nil {
+ isdownloaded = true
+ break
+ }
+ }
- byteValue, err := ioutil.ReadAll(jsonFile)
- if err != nil {
- jenkinslog.Info("Failed to convert the JSON file into a byte array")
- return &AllPluginData, err
- }
- err = json.Unmarshal(byteValue, &AllPluginData)
- if err != nil {
- jenkinslog.Info("Failed to decode the Plugin JSON data file")
- return &AllPluginData, err
- }
+ if isdownloaded {
+ for i := 0; i < in.maxattempts; i++ {
+ err = in.Extract()
+ if err == nil {
+ isextracted = true
+ break
+ }
+ }
+ } else {
+ jenkinslog.Info("Cache Plugin Data", "failed to download file", err)
+ }
- return &AllPluginData, nil
-}
+ if isextracted {
+ for i := 0; i < in.maxattempts; i++ {
+ err = in.Cache()
+ if err == nil {
+ iscached = true
+ break
+ }
+ }
-// Downloads and extracts the JSON file in every 12 hours
-func RetrieveDataFile() {
- for {
- jenkinslog.Info("Retreiving file", "Host Url", hosturl)
- err := Download()
- if err != nil {
- jenkinslog.Info("Retrieving File", "Error while downloading", err)
- continue
+ if !iscached {
+ jenkinslog.Info("Cache Plugin Data", "failed to read plugin data file", err)
+ }
+ } else {
+ jenkinslog.Info("Cache Plugin Data", "failed to extract file", err)
}
- jenkinslog.Info("Retrieve File", "Successfully downloaded", compressedFile)
- err = Extract()
- if err != nil {
- jenkinslog.Info("Retreive File", "Error while extracting", err)
- continue
+ if !in.iscached {
+ ch <- iscached
}
- jenkinslog.Info("Retreive File", "Successfully extracted", pluginDataFile)
- isRetrieved = true
+ in.iscached = in.iscached || iscached
time.Sleep(12 * time.Hour)
-
}
}
-func Download() error {
-
- out, err := os.Create(compressedFile)
+func (in *PluginDataManager) Download() error {
+ out, err := os.Create(in.compressedFilePath)
if err != nil {
return err
}
defer out.Close()
client := http.Client{
- Timeout: 2000 * time.Second,
+ Timeout: 1000 * time.Second,
}
- resp, err := client.Get(hosturl)
+ resp, err := client.Get(in.hosturl)
if err != nil {
return err
}
defer resp.Body.Close()
- jenkinslog.Info("Successfully Downloaded")
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
-
}
-func Extract() error {
- reader, err := os.Open(compressedFile)
+func (in *PluginDataManager) Extract() error {
+ reader, err := os.Open(in.compressedFilePath)
if err != nil {
return err
@@ -272,7 +273,7 @@ func Extract() error {
}
defer archive.Close()
- writer, err := os.Create(pluginDataFile)
+ writer, err := os.Create(in.pluginDataFile)
if err != nil {
return err
}
@@ -280,10 +281,28 @@ func Extract() error {
_, err = io.Copy(writer, archive)
return err
+}
+// Loads the JSON data into memory and stores it
+func (in *PluginDataManager) Cache() error {
+ jsonFile, err := os.Open(in.pluginDataFile)
+ if err != nil {
+ return err
+ }
+ defer jsonFile.Close()
+
+ byteValue, err := ioutil.ReadAll(jsonFile)
+ if err != nil {
+ return err
+ }
+ err = json.Unmarshal(byteValue, &in.pluginDataCache)
+ if err != nil {
+ return err
+ }
+ return nil
}
-// returns a semantic version that can be used for comparision
+// returns a semantic version that can be used for comparison
func MakeSemanticVersion(version string) string {
version = "v" + version
return semver.Canonical(version)
diff --git a/config/samples/jenkins.io_v1alpha2_jenkins.yaml b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
index be33732a9..49f39c931 100644
--- a/config/samples/jenkins.io_v1alpha2_jenkins.yaml
+++ b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
@@ -1,8 +1,9 @@
+
apiVersion: jenkins.io/v1alpha2
kind: Jenkins
metadata:
- name: example-8
- namespace: default
+ name: example
+ namespace: default
spec:
configurationAsCode:
configurations: []
@@ -14,7 +15,6 @@ spec:
name: ""
jenkinsAPISettings:
authorizationStrategy: createUser
- ValidateSecurityWarnings: true
master:
disableCSRFProtection: false
containers:
@@ -48,75 +48,9 @@ spec:
requests:
cpu: "1"
memory: 500Mi
- plugins:
- - name: mailer
- version: "1.19"
- - name: script-security
- version: "1.18"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: credentials
- version: "2.1"
- - name: ssh-credentials
- version: "1.1"
- - name: junit
- version: "1.2"
- - name: matrix-project
- version: "1.1"
- - name: git-client
- version: "2.8.4"
- - name: pipeline-model-definition
- version: "1.3.0"
- - name: favorite
- version: "2"
- - name: workflow-cps
- version: "2"
-
seedJobs:
- id: jenkins-operator
targets: "cicd/jobs/*.jenkins"
description: "Jenkins Operator repository"
repositoryBranch: master
- repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
+ repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
\ No newline at end of file
diff --git a/main.go b/main.go
index 3cd399f6a..936862f1c 100644
--- a/main.go
+++ b/main.go
@@ -78,6 +78,7 @@ func main() {
var metricsAddr string
var enableLeaderElection bool
var probeAddr string
+ var ValidateSecurityWarnings bool
isRunningInCluster, err := resources.IsRunningInCluster()
if err != nil {
@@ -88,6 +89,7 @@ func main() {
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "leader-elect", isRunningInCluster, "Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
+ flag.BoolVar(&ValidateSecurityWarnings, "validate-security-warnings", false, "Enable validation for potential security warnings in jenkins custom resource plugins")
hostname := flag.String("jenkins-api-hostname", "", "Hostname or IP of Jenkins API. It can be service name, node IP or localhost.")
port := flag.Int("jenkins-api-port", 0, "The port on which Jenkins API is running. Note: If you want to use nodePort don't set this setting and --jenkins-api-use-nodeport must be true.")
useNodePort := flag.Bool("jenkins-api-use-nodeport", false, "Connect to Jenkins API using the service nodePort instead of service port. If you want to set this as true - don't set --jenkins-api-port.")
@@ -95,9 +97,6 @@ func main() {
opts := zap.Options{
Development: true,
}
-
- go v1alpha2.RetrieveDataFile()
-
opts.BindFlags(flag.CommandLine)
flag.Parse()
@@ -112,6 +111,15 @@ func main() {
}
logger.Info(fmt.Sprintf("Watch namespace: %v", namespace))
+ if ValidateSecurityWarnings {
+ ispluginsdatainitialized := make(chan bool)
+ go v1alpha2.PluginsDataManager.CachePluginData(ispluginsdatainitialized)
+
+ if !<-ispluginsdatainitialized {
+ fatal(errors.New("Unable to get the plugins data"), *debug)
+ }
+ }
+
// get a config to talk to the API server
cfg, err := config.GetConfig()
if err != nil {
diff --git a/webhook/all_in_one_v1alpha2.yaml b/webhook/all_in_one_v1alpha2.yaml
index 0d878dd2d..18afb8010 100644
--- a/webhook/all_in_one_v1alpha2.yaml
+++ b/webhook/all_in_one_v1alpha2.yaml
@@ -247,7 +247,7 @@ spec:
- /manager
args:
- --leader-elect
- image: jenkins-operator:52fe5fe9-dirty
+ image: jenkins-operator:37d0eac4-dirty
name: jenkins-operator
imagePullPolicy: IfNotPresent
securityContext:
@@ -266,11 +266,11 @@ spec:
periodSeconds: 10
resources:
limits:
- cpu: 100m
- memory: 30Mi
+ cpu: 200m
+ memory: 200Mi
requests:
cpu: 100m
- memory: 20Mi
+ memory: 80Mi
env:
- name: WATCH_NAMESPACE
valueFrom:
@@ -278,8 +278,7 @@ spec:
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
- name: cert
- readOnly: false
+ name: cert
volumes:
- name: cert
secret:
diff --git a/webhook/operator.yaml b/webhook/operator.yaml
index c056ba8e0..01093af2d 100644
--- a/webhook/operator.yaml
+++ b/webhook/operator.yaml
@@ -23,6 +23,7 @@ spec:
- /manager
args:
- --leader-elect
+ - --validate-security-warnings
image: {DOCKER_REGISTRY}:{GITCOMMIT}
name: jenkins-operator
imagePullPolicy: IfNotPresent
From 853f4857466922de550f934d459951b4a1e02341 Mon Sep 17 00:00:00 2001
From: Morten Birkelund
Date: Mon, 9 Aug 2021 14:57:00 +0200
Subject: [PATCH 19/26] Helm Chart: Remove empty priorityClassName from Jenkins
template (#618)
Also bump Helm Chart version to v0.5.2
---
chart/index.yaml | 10 ++++++++++
chart/jenkins-operator/Chart.yaml | 2 +-
.../jenkins-operator/jenkins-operator-0.5.2.tgz | Bin 0 -> 34161 bytes
chart/jenkins-operator/templates/jenkins.yaml | 2 --
4 files changed, 11 insertions(+), 3 deletions(-)
create mode 100644 chart/jenkins-operator/jenkins-operator-0.5.2.tgz
diff --git a/chart/index.yaml b/chart/index.yaml
index b7e1f5541..0044cbebe 100644
--- a/chart/index.yaml
+++ b/chart/index.yaml
@@ -1,6 +1,16 @@
apiVersion: v1
entries:
jenkins-operator:
+ - apiVersion: v2
+ appVersion: 0.6.0
+ created: "2021-06-11T13:50:32.677639006+02:00"
+ description: Kubernetes native operator which fully manages Jenkins on Kubernetes
+ digest: 48fbf15c3ffff7003623edcde0bec39dc37d0a62303f08066960d5fac799af90
+ icon: https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/assets/jenkins-operator-icon.png
+ name: jenkins-operator
+ urls:
+ - https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/chart/jenkins-operator/jenkins-operator-0.5.2.tgz
+ version: 0.5.2
- apiVersion: v2
appVersion: 0.6.0
created: "2021-06-11T13:50:32.677639006+02:00"
diff --git a/chart/jenkins-operator/Chart.yaml b/chart/jenkins-operator/Chart.yaml
index 9d8c137d7..d90d312a6 100644
--- a/chart/jenkins-operator/Chart.yaml
+++ b/chart/jenkins-operator/Chart.yaml
@@ -2,5 +2,5 @@ apiVersion: v2
appVersion: "0.6.0"
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
name: jenkins-operator
-version: 0.5.1
+version: 0.5.2
icon: https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/assets/jenkins-operator-icon.png
diff --git a/chart/jenkins-operator/jenkins-operator-0.5.2.tgz b/chart/jenkins-operator/jenkins-operator-0.5.2.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..c2f1afe9e0063a9c2e03b84b419cade3074dd85f
GIT binary patch
literal 34161
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
Configuration
diff --git a/docs/docs/getting-started/latest/index.xml b/docs/docs/getting-started/latest/index.xml
index 5d3564a08..d6501db16 100644
--- a/docs/docs/getting-started/latest/index.xml
+++ b/docs/docs/getting-started/latest/index.xml
@@ -240,7 +240,7 @@ spec:
targets: "cicd/jobs/*.jenkins"
description: "Jenkins Operator repository"
repositoryBranch: master
- repositoryUrl: ssh://git@github.com:jenkinsci/kubernetes-operator.git</code></pre>
+ repositoryUrl: git@github.com:jenkinsci/kubernetes-operator.git</code></pre>
<p>and create a Kubernetes Secret (name of secret should be the same from <code>credentialID</code> field):</p>
<pre><code>apiVersion: v1
kind: Secret
@@ -403,14 +403,17 @@ stringData:
Plugin’s configuration is applied as groovy scripts or the <a href="https://github.com/jenkinsci/configuration-as-code-plugin">configuration as code plugin</a>.
Any plugin working for Jenkins can be installed by the Jenkins Operator.</p>
-<p>Pre-installed plugins:
-* configuration-as-code v1.47
-* git v4.5.0
-* job-dsl v1.77
-* kubernetes-credentials-provider v0.15
-* kubernetes v1.29.0
-* workflow-aggregator v2.6
-* workflow-job v2.40</p>
+<p>Pre-installed plugins:</p>
+
+<ul>
+<li>configuration-as-code v1.51</li>
+<li>git v4.7.2</li>
+<li>job-dsl v1.77</li>
+<li>kubernetes-credentials-provider v0.18-1</li>
+<li>kubernetes v1.30.0</li>
+<li>workflow-aggregator v2.6</li>
+<li>workflow-job v2.41</li>
+</ul>
<p>Rest of the plugins can be found in <a href="https://plugins.jenkins.io/">plugins repository</a>.</p>
@@ -435,19 +438,19 @@ Any plugin working for Jenkins can be installed by the Jenkins Operator.</p&g
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>master<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>basePlugins<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>kubernetes<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.28.6"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.30.0"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>workflow-job<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"2.40"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>workflow-aggregator<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"2.6"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>git<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"4.5.0"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"4.7.2"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>job-dsl<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.77"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>configuration-as-code<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.46"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.51"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>kubernetes-credentials-provider<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"0.15"</span></code></pre></div>
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"0.18-1"</span></code></pre></div>
<p>You can change their versions.</p>
<p>The <strong>Jenkins Operator</strong> will then automatically install plugins after the Jenkins master pod restart.</p>
diff --git a/docs/docs/getting-started/v0.5.x/index.html b/docs/docs/getting-started/v0.5.x/index.html
index 1d17315c5..bed9ab636 100644
--- a/docs/docs/getting-started/v0.5.x/index.html
+++ b/docs/docs/getting-started/v0.5.x/index.html
@@ -824,6 +824,8 @@ First Steps
+
+
Deploy Jenkins
@@ -846,8 +848,6 @@
-
-
Configuration
diff --git a/docs/docs/index.html b/docs/docs/index.html
index 001c8b57a..c8d69c8ed 100644
--- a/docs/docs/index.html
+++ b/docs/docs/index.html
@@ -789,10 +789,6 @@ Documentation
-
-
-
-
Installation
@@ -832,6 +828,10 @@
+
+
+
+
diff --git a/docs/docs/index.xml b/docs/docs/index.xml
index 6024f26d8..77dc07336 100644
--- a/docs/docs/index.xml
+++ b/docs/docs/index.xml
@@ -651,7 +651,7 @@ spec:
targets: "cicd/jobs/*.jenkins"
description: "Jenkins Operator repository"
repositoryBranch: master
- repositoryUrl: ssh://git@github.com:jenkinsci/kubernetes-operator.git</code></pre>
+ repositoryUrl: git@github.com:jenkinsci/kubernetes-operator.git</code></pre>
<p>and create a Kubernetes Secret (name of secret should be the same from <code>credentialID</code> field):</p>
<pre><code>apiVersion: v1
kind: Secret
@@ -2167,14 +2167,17 @@ stringData:
Plugin’s configuration is applied as groovy scripts or the <a href="https://github.com/jenkinsci/configuration-as-code-plugin">configuration as code plugin</a>.
Any plugin working for Jenkins can be installed by the Jenkins Operator.</p>
-<p>Pre-installed plugins:
-* configuration-as-code v1.47
-* git v4.5.0
-* job-dsl v1.77
-* kubernetes-credentials-provider v0.15
-* kubernetes v1.29.0
-* workflow-aggregator v2.6
-* workflow-job v2.40</p>
+<p>Pre-installed plugins:</p>
+
+<ul>
+<li>configuration-as-code v1.51</li>
+<li>git v4.7.2</li>
+<li>job-dsl v1.77</li>
+<li>kubernetes-credentials-provider v0.18-1</li>
+<li>kubernetes v1.30.0</li>
+<li>workflow-aggregator v2.6</li>
+<li>workflow-job v2.41</li>
+</ul>
<p>Rest of the plugins can be found in <a href="https://plugins.jenkins.io/">plugins repository</a>.</p>
@@ -2199,19 +2202,19 @@ Any plugin working for Jenkins can be installed by the Jenkins Operator.</p&g
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>master<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>basePlugins<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>kubernetes<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.28.6"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.30.0"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>workflow-job<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"2.40"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>workflow-aggregator<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"2.6"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>git<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"4.5.0"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"4.7.2"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>job-dsl<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.77"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>configuration-as-code<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.46"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.51"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>kubernetes-credentials-provider<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"0.15"</span></code></pre></div>
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"0.18-1"</span></code></pre></div>
<p>You can change their versions.</p>
<p>The <strong>Jenkins Operator</strong> will then automatically install plugins after the Jenkins master pod restart.</p>
diff --git a/docs/docs/installation/index.html b/docs/docs/installation/index.html
index eb6372364..4aa60183a 100644
--- a/docs/docs/installation/index.html
+++ b/docs/docs/installation/index.html
@@ -26,7 +26,7 @@
" />
-
+
@@ -766,6 +766,8 @@
+
Note on Operator’s nightly built images
+Note on Jenkins home Volume
@@ -808,18 +810,21 @@ Installation
This document describes installation procedure for Jenkins Operator.
-All container images can be found at virtuslab/jenkins-operator
+All container images can be found at virtuslab/jenkins-operator Docker Hub repository.
Requirements
-To run Jenkins Operator, you will need:
-- access to a Kubernetes cluster version 1.17+
-- kubectl
version 1.17+
+To run Jenkins Operator, you will need:
-Listed below are the two ways to deploy Jenkins Operator. For details on how to customize your Jenkins instance, refer to Getting Started
+
+- access to a Kubernetes cluster version
1.17+
+kubectl
version 1.17+
+
+
+Listed below are the two ways to deploy Jenkins Operator. For details on how to customize your Jenkins instance, refer to Getting Started.
Deploy Jenkins Operator using YAML’s
@@ -1649,6 +1654,18 @@ Configuring operator deployment
+Note on Operator’s nightly built images
+
+If you wish to use the newest, not yet released version of the Operator, you can use one of nightly built snapshot images, however the maintainers of this project cannot guarantee their stability.
+
+You can find nightly built images by heading to virtuslab/jenkins-operator Docker Hub repository and looking for images with tag in the form of “{git-hash}”, {git-hash} being the hash of master branch commit that you want to use snapshot of.
+
+Note on Jenkins home Volume
+
+Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users. One of the key points of this design is maintaining an immutable state of Jenkins.
+
+One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume as Jenkins home directory. It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory, as attempting to do so will result in Operator error.
+
@@ -1805,7 +1822,7 @@ Configuring operator deployment
- Last modified October 5, 2020
+ Last modified July 30, 2021
diff --git a/docs/docs/installation/index.xml b/docs/docs/installation/index.xml
index 9bc06edf8..37e38d051 100644
--- a/docs/docs/installation/index.xml
+++ b/docs/docs/installation/index.xml
@@ -4,7 +4,7 @@
https://jenkinsci.github.io/kubernetes-operator/docs/installation/
Recent Hugo news from gohugo.io
Hugo -- gohugo.io
- Mon, 05 Oct 2020 00:00:00 +0000
+ Fri, 30 Jul 2021 00:00:00 +0000
https://jenkinsci.github.io/kubernetes-operator/img/hugo.png
GoHugo.io
diff --git a/docs/sitemap.xml b/docs/sitemap.xml
index efa05ade3..b751f91fc 100644
--- a/docs/sitemap.xml
+++ b/docs/sitemap.xml
@@ -3,18 +3,18 @@
xmlns:xhtml="http://www.w3.org/1999/xhtml">
- https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/deploy-jenkins/
- 2021-01-25T00:00:00+00:00
+ https://jenkinsci.github.io/kubernetes-operator/docs/installation/
+ 2021-07-30T00:00:00+00:00
- https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/v0.5.x/deploy-jenkins/
+ https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/deploy-jenkins/
2021-01-25T00:00:00+00:00
- https://jenkinsci.github.io/kubernetes-operator/docs/installation/
- 2020-10-05T00:00:00+00:00
+ https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/v0.5.x/deploy-jenkins/
+ 2021-01-25T00:00:00+00:00
@@ -369,7 +369,7 @@
https://jenkinsci.github.io/kubernetes-operator/docs/developer-guide/
- 2021-06-10T00:00:00+00:00
+ 2021-07-30T00:00:00+00:00
diff --git a/website/package-lock.json b/website/package-lock.json
index 57c68fa43..fabb2bfa4 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -330,9 +330,9 @@
"dev": true
},
"caniuse-lite": {
- "version": "1.0.30001245",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001245.tgz",
- "integrity": "sha512-768fM9j1PKXpOCKws6eTo3RHmvTUsG9UrpT4WoREFeZgJBTi4/X9g565azS/rVUGtqb8nt7FjLeF5u4kukERnA==",
+ "version": "1.0.30001248",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001248.tgz",
+ "integrity": "sha512-NwlQbJkxUFJ8nMErnGtT0QTM2TJ33xgz4KXJSMIrjXIbDVdaYueGyjOrLKRtJC+rTiWfi6j5cnZN1NBiSBJGNw==",
"dev": true
},
"chalk": {
@@ -568,9 +568,9 @@
}
},
"electron-to-chromium": {
- "version": "1.3.780",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.780.tgz",
- "integrity": "sha512-2KQ9OYm9WMUNpAPA/4aerURl3hwRc9tNlpsiEj3Y8Gf7LVf26NzyLIX2v0hSagQwrS9+cWab+28A2GPKDoVNRA==",
+ "version": "1.3.792",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.792.tgz",
+ "integrity": "sha512-RM2O2xrNarM7Cs+XF/OE2qX/aBROyOZqqgP+8FXMXSuWuUqCfUUzg7NytQrzZU3aSqk1Qq6zqnVkJsbfMkIatg==",
"dev": true
},
"end-of-stream": {
From 37d0eac4e394d314bef2666aee850ed85b8312d8 Mon Sep 17 00:00:00 2001
From: sharmapulkit04
Date: Wed, 4 Aug 2021 16:06:14 +0530
Subject: [PATCH 13/26] Reimplemented the validation logic with caching the
security warnings - Reimplemented the validator interface - Updated manifests
to allocate more resources
---
Dockerfile | 2 +-
api/v1alpha2/jenkins_webhook.go | 268 ++++++++++++------
.../samples/jenkins.io_v1alpha2_jenkins.yaml | 71 ++++-
main.go | 3 +
webhook/all_in_one_v1alpha2.yaml | 9 +-
webhook/operator.yaml | 12 +-
webhook/webhook.yaml | 2 +-
7 files changed, 274 insertions(+), 93 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index ff840ea45..caaced1d7 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -19,6 +19,7 @@ COPY internal/ internal/
COPY pkg/ pkg/
COPY version/ version/
COPY main.go main.go
+RUN mkdir plugins/
# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -ldflags "-w $CTIMEVAR" -o manager main.go
@@ -29,5 +30,4 @@ FROM gcr.io/distroless/static:nonroot
WORKDIR /
COPY --from=builder /workspace/manager .
USER 65532:65532
-
ENTRYPOINT ["/manager"]
diff --git a/api/v1alpha2/jenkins_webhook.go b/api/v1alpha2/jenkins_webhook.go
index 494fdb802..97af23c99 100644
--- a/api/v1alpha2/jenkins_webhook.go
+++ b/api/v1alpha2/jenkins_webhook.go
@@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
+ http://www.apache.org/lictenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,10 +17,13 @@ limitations under the License.
package v1alpha2
import (
+ "compress/gzip"
"encoding/json"
"errors"
+ "io"
"io/ioutil"
"net/http"
+ "os"
"time"
"github.com/jenkinsci/kubernetes-operator/pkg/plugins"
@@ -32,8 +35,16 @@ import (
"sigs.k8s.io/controller-runtime/pkg/webhook"
)
-// log is for logging in this package.
-var jenkinslog = logf.Log.WithName("jenkins-resource")
+var (
+ jenkinslog = logf.Log.WithName("jenkins-resource") // log is for logging in this package.
+ isRetrieved bool = false // For checking whether the data file is downloaded and extracted or not
+)
+
+const (
+ hosturl string = "https://ci.jenkins.io/job/Infra/job/plugin-site-api/job/generate-data/lastSuccessfulBuild/artifact/plugins.json.gzip" // Url for downloading the plugins file
+ compressedFile string = "/tmp/plugins.json.gzip" // location where the gzip file will be downloaded
+ pluginDataFile string = "/tmp/plugins.json" // location where the file will be extracted
+)
func (in *Jenkins) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
@@ -72,8 +83,13 @@ func (in *Jenkins) ValidateDelete() error {
return nil
}
-type Warnings struct {
- Warnings []Warning `json:"securityWarnings"`
+type PluginsInfo struct {
+ Plugins []PluginInfo `json:"plugins"`
+}
+
+type PluginInfo struct {
+ Name string `json:"name"`
+ SecurityWarnings []Warning `json:"securityWarnings"`
}
type Warning struct {
@@ -83,109 +99,203 @@ type Warning struct {
URL string `json:"url"`
Active bool `json:"active"`
}
+
type Version struct {
FirstVersion string `json:"firstVersion"`
LastVersion string `json:"lastVersion"`
}
-const APIURL string = "https://plugins.jenkins.io/api/plugin/"
-
-func MakeSemanticVersion(version string) string {
- version = "v" + version
- return semver.Canonical(version)
+type PluginData struct {
+ Version string
+ Kind string
}
-func CompareVersions(firstVersion string, lastVersion string, pluginVersion string) bool {
- firstSemVer := MakeSemanticVersion(firstVersion)
- lastSemVer := MakeSemanticVersion(lastVersion)
- pluginSemVer := MakeSemanticVersion(pluginVersion)
- if semver.Compare(pluginSemVer, firstSemVer) == -1 || semver.Compare(pluginSemVer, lastSemVer) == 1 {
- return false
- }
- return true
-}
+// Validates security warnings for both updating and creating a Jenkins CR
+func Validate(r Jenkins) error {
-func CheckSecurityWarnings(pluginName string, pluginVersion string) (bool, error) {
- jenkinslog.Info("checking security warnings", "plugin: ", pluginName)
- pluginURL := APIURL + pluginName
- client := &http.Client{
- Timeout: time.Second * 30,
- }
- request, err := http.NewRequest("GET", pluginURL, nil)
- if err != nil {
- return false, err
- }
- request.Header.Add("Accept", "application/json")
- request.Header.Add("Content-Type", "application/json")
- response, err := client.Do(request)
- if err != nil {
- return false, err
- }
- defer response.Body.Close()
- bodyBytes, err := ioutil.ReadAll(response.Body)
+ pluginset := make(map[string]PluginData)
+ var warningmsg string
+ basePlugins := plugins.BasePlugins()
+ temp, err := NewPluginsInfo()
+ AllPluginData := *temp
if err != nil {
- return false, err
+ return err
}
- securityWarnings := Warnings{}
- jsonErr := json.Unmarshal(bodyBytes, &securityWarnings)
- if jsonErr != nil {
- return false, err
+ for _, plugin := range basePlugins {
+ // Only Update the map if the plugin is not present or a lower version is being used
+ if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
+ jenkinslog.Info("Validate", plugin.Name, plugin.Version)
+ pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "base"}
+ }
}
- jenkinslog.Info("Validate()", "warnings", securityWarnings)
+ for _, plugin := range r.Spec.Master.Plugins {
+ if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
+ jenkinslog.Info("Validate", plugin.Name, plugin.Version)
+ pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "user-defined"}
+ }
+ }
- for _, warning := range securityWarnings.Warnings {
- for _, version := range warning.Versions {
- firstVersion := version.FirstVersion
- lastVersion := version.LastVersion
- if len(firstVersion) == 0 {
- firstVersion = "0" // setting default value in case of empty string
- }
- if len(lastVersion) == 0 {
- lastVersion = pluginVersion // setting default value in case of empty string
+ jenkinslog.Info("Checking through all the warnings")
+ for _, plugin := range AllPluginData.Plugins {
+
+ if pluginData, ispresent := pluginset[plugin.Name]; ispresent {
+ jenkinslog.Info("Checking for plugin", "name", plugin.Name)
+ for _, warning := range plugin.SecurityWarnings {
+ for _, version := range warning.Versions {
+ firstVersion := version.FirstVersion
+ lastVersion := version.LastVersion
+ if len(firstVersion) == 0 {
+ firstVersion = "0" // setting default value in case of empty string
+ }
+ if len(lastVersion) == 0 {
+ lastVersion = pluginData.Version // setting default value in case of empty string
+ }
+
+ if CompareVersions(firstVersion, lastVersion, pluginData.Version) {
+ jenkinslog.Info("security Vulnerabilities detected", "message", warning.Message, "Check security Advisory", warning.URL)
+ warningmsg += "Security Vulnerabilities detected in " + pluginData.Kind + " plugin " + plugin.Name + "\n"
+
+ }
+
+ }
}
- if CompareVersions(firstVersion, lastVersion, pluginVersion) {
- jenkinslog.Info("security Vulnerabilities detected", "message", warning.Message, "Check security Advisory", warning.URL)
- return true, nil
- }
}
+
}
- return false, nil
-}
+ if len(warningmsg) > 0 {
+ return errors.New(warningmsg)
+ }
-func Validate(r Jenkins) error {
- basePlugins := plugins.BasePlugins()
- var warnings string = ""
+ return nil
- for _, plugin := range basePlugins {
- name := plugin.Name
- version := plugin.Version
- hasWarnings, err := CheckSecurityWarnings(name, version)
- if err != nil {
- return err
- }
- if hasWarnings {
- warnings += "Security Vulnerabilities detected in base plugin:" + name
+}
+
+// Returns an object containing information of all the plugins present in the security center
+func NewPluginsInfo() (*PluginsInfo, error) {
+ var AllPluginData PluginsInfo
+ for i := 0; i < 28; i++ {
+ if isRetrieved {
+ break
}
+ time.Sleep(1 * time.Second)
+ }
+ if !isRetrieved {
+ jenkinslog.Info("Plugins Data file hasn't been downloaded and extracted")
+ return &AllPluginData, errors.New("plugins data file not found")
}
- for _, plugin := range r.Spec.Master.Plugins {
- name := plugin.Name
- version := plugin.Version
- hasWarnings, err := CheckSecurityWarnings(name, version)
+ jsonFile, err := os.Open(pluginDataFile)
+ if err != nil {
+ jenkinslog.Info("Failed to open the Plugins Data File")
+ return &AllPluginData, err
+ }
+ defer jsonFile.Close()
+
+ byteValue, err := ioutil.ReadAll(jsonFile)
+ if err != nil {
+ jenkinslog.Info("Failed to convert the JSON file into a byte array")
+ return &AllPluginData, err
+ }
+ err = json.Unmarshal(byteValue, &AllPluginData)
+ if err != nil {
+ jenkinslog.Info("Failed to decode the Plugin JSON data file")
+ return &AllPluginData, err
+ }
+
+ return &AllPluginData, nil
+}
+
+// Downloads and extracts the JSON file in every 12 hours
+func RetrieveDataFile() {
+ for {
+ jenkinslog.Info("Retreiving file", "Host Url", hosturl)
+ err := Download()
if err != nil {
- return err
+ jenkinslog.Info("Retrieving File", "Error while downloading", err)
+ continue
}
- if hasWarnings {
- warnings += "Security Vulnerabilities detected in the user defined plugin: " + name
+
+ jenkinslog.Info("Retrieve File", "Successfully downloaded", compressedFile)
+ err = Extract()
+ if err != nil {
+ jenkinslog.Info("Retreive File", "Error while extracting", err)
+ continue
}
+ jenkinslog.Info("Retreive File", "Successfully extracted", pluginDataFile)
+ isRetrieved = true
+ time.Sleep(12 * time.Hour)
+
}
- if len(warnings) > 0 {
- return errors.New(warnings)
+}
+
+func Download() error {
+
+ out, err := os.Create(compressedFile)
+ if err != nil {
+ return err
+ }
+ defer out.Close()
+
+ client := http.Client{
+ Timeout: 2000 * time.Second,
+ }
+
+ resp, err := client.Get(hosturl)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ jenkinslog.Info("Successfully Downloaded")
+ _, err = io.Copy(out, resp.Body)
+ if err != nil {
+ return err
}
return nil
+
+}
+
+func Extract() error {
+ reader, err := os.Open(compressedFile)
+
+ if err != nil {
+ return err
+ }
+ defer reader.Close()
+ archive, err := gzip.NewReader(reader)
+ if err != nil {
+ return err
+ }
+
+ defer archive.Close()
+ writer, err := os.Create(pluginDataFile)
+ if err != nil {
+ return err
+ }
+ defer writer.Close()
+
+ _, err = io.Copy(writer, archive)
+ return err
+
+}
+
+// returns a semantic version that can be used for comparision
+func MakeSemanticVersion(version string) string {
+ version = "v" + version
+ return semver.Canonical(version)
+}
+
+// Compare if the current version lies between first version and last version
+func CompareVersions(firstVersion string, lastVersion string, pluginVersion string) bool {
+ firstSemVer := MakeSemanticVersion(firstVersion)
+ lastSemVer := MakeSemanticVersion(lastVersion)
+ pluginSemVer := MakeSemanticVersion(pluginVersion)
+ if semver.Compare(pluginSemVer, firstSemVer) == -1 || semver.Compare(pluginSemVer, lastSemVer) == 1 {
+ return false
+ }
+ return true
}
diff --git a/config/samples/jenkins.io_v1alpha2_jenkins.yaml b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
index b451d5dab..be33732a9 100644
--- a/config/samples/jenkins.io_v1alpha2_jenkins.yaml
+++ b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
@@ -1,8 +1,8 @@
apiVersion: jenkins.io/v1alpha2
kind: Jenkins
metadata:
- name: example
- namespace: default
+ name: example-8
+ namespace: default
spec:
configurationAsCode:
configurations: []
@@ -14,6 +14,7 @@ spec:
name: ""
jenkinsAPISettings:
authorizationStrategy: createUser
+ ValidateSecurityWarnings: true
master:
disableCSRFProtection: false
containers:
@@ -47,6 +48,72 @@ spec:
requests:
cpu: "1"
memory: 500Mi
+ plugins:
+ - name: mailer
+ version: "1.19"
+ - name: script-security
+ version: "1.18"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: credentials
+ version: "2.1"
+ - name: ssh-credentials
+ version: "1.1"
+ - name: junit
+ version: "1.2"
+ - name: matrix-project
+ version: "1.1"
+ - name: git-client
+ version: "2.8.4"
+ - name: pipeline-model-definition
+ version: "1.3.0"
+ - name: favorite
+ version: "2"
+ - name: workflow-cps
+ version: "2"
+
seedJobs:
- id: jenkins-operator
targets: "cicd/jobs/*.jenkins"
diff --git a/main.go b/main.go
index 8bc382ead..3cd399f6a 100644
--- a/main.go
+++ b/main.go
@@ -95,6 +95,9 @@ func main() {
opts := zap.Options{
Development: true,
}
+
+ go v1alpha2.RetrieveDataFile()
+
opts.BindFlags(flag.CommandLine)
flag.Parse()
diff --git a/webhook/all_in_one_v1alpha2.yaml b/webhook/all_in_one_v1alpha2.yaml
index e53fc659f..0d878dd2d 100644
--- a/webhook/all_in_one_v1alpha2.yaml
+++ b/webhook/all_in_one_v1alpha2.yaml
@@ -222,6 +222,7 @@ subjects:
- kind: ServiceAccount
name: jenkins-operator
---
+---
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -246,7 +247,7 @@ spec:
- /manager
args:
- --leader-elect
- image: jenkins-operator:6f33fe82-dirty
+ image: jenkins-operator:52fe5fe9-dirty
name: jenkins-operator
imagePullPolicy: IfNotPresent
securityContext:
@@ -278,12 +279,12 @@ spec:
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
- readOnly: true
+ readOnly: false
volumes:
- name: cert
secret:
defaultMode: 420
- secretName: webhook-server-cert
+ secretName: webhook-server-cert
terminationGracePeriodSeconds: 10
---
apiVersion: cert-manager.io/v1
@@ -315,7 +316,6 @@ spec:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
- creationTimestamp: null
name: validating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: default/webhook-certificate
@@ -330,6 +330,7 @@ webhooks:
path: /validate-jenkins-io-v1alpha2-jenkins
failurePolicy: Fail
name: vjenkins.kb.io
+ timeoutSeconds: 30
rules:
- apiGroups:
- jenkins.io
diff --git a/webhook/operator.yaml b/webhook/operator.yaml
index 81cbdf98e..c056ba8e0 100644
--- a/webhook/operator.yaml
+++ b/webhook/operator.yaml
@@ -1,3 +1,4 @@
+---
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -41,11 +42,11 @@ spec:
periodSeconds: 10
resources:
limits:
- cpu: 100m
- memory: 30Mi
+ cpu: 200m
+ memory: 200Mi
requests:
cpu: 100m
- memory: 20Mi
+ memory: 80Mi
env:
- name: WATCH_NAMESPACE
valueFrom:
@@ -53,12 +54,11 @@ spec:
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
- name: cert
- readOnly: true
+ name: cert
volumes:
- name: cert
secret:
defaultMode: 420
- secretName: webhook-server-cert
+ secretName: webhook-server-cert
terminationGracePeriodSeconds: 10
---
diff --git a/webhook/webhook.yaml b/webhook/webhook.yaml
index 3a86ab0b1..9cc2a2b74 100644
--- a/webhook/webhook.yaml
+++ b/webhook/webhook.yaml
@@ -1,7 +1,6 @@
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
- creationTimestamp: null
name: validating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: default/webhook-certificate
@@ -16,6 +15,7 @@ webhooks:
path: /validate-jenkins-io-v1alpha2-jenkins
failurePolicy: Fail
name: vjenkins.kb.io
+ timeoutSeconds: 30
rules:
- apiGroups:
- jenkins.io
From 8453b3e9fecfa8ad7fe06732923476c424f7e8c4 Mon Sep 17 00:00:00 2001
From: Szymon Fugas
Date: Thu, 5 Aug 2021 17:27:19 +0200
Subject: [PATCH 14/26] Add an issue template for documentation (#613)
---
.github/ISSUE_TEMPLATE/documentation.md | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100644 .github/ISSUE_TEMPLATE/documentation.md
diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md
new file mode 100644
index 000000000..a0ed0b42c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/documentation.md
@@ -0,0 +1,14 @@
+---
+name: "📚 Documentation issue"
+about: Suggest changes to project's documentation
+title: ''
+labels: 'documentation'
+projects: ''
+assignees: ''
+---
+
+**Relevant links*
+Link(s) to the section(s) of documentation that are outdated or otherwise wrong
+
+**Description**
+Description of the changes you would like to see
\ No newline at end of file
From 858f0f4c7289bd518ac419d57116907940109429 Mon Sep 17 00:00:00 2001
From: Szymon Fugas
Date: Thu, 5 Aug 2021 17:28:01 +0200
Subject: [PATCH 15/26] Docs: add info on restricted volumeMounts other than
jenkins-home(#612)
* Update note in installation docs
* Update Helm chart default values.yaml
* Update schema
---
chart/jenkins-operator/values.yaml | 5 +++--
.../en/docs/Getting Started/latest/schema.md | 7 ++++++-
.../content/en/docs/Installation/_index.md | 20 +++++++++++++++----
3 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/chart/jenkins-operator/values.yaml b/chart/jenkins-operator/values.yaml
index 1c92fb900..60c992cd2 100644
--- a/chart/jenkins-operator/values.yaml
+++ b/chart/jenkins-operator/values.yaml
@@ -120,8 +120,9 @@ jenkins:
claimName: jenkins-backup
# volumeMounts are mounts for Jenkins pod
- # Note that attempting to overwrite default mount settings for Jenkins home directory will result in Operator error
- # See https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-jenkins-home-volume
+ # Note that attempting to overwrite default mount settings for restricted,
+ # non-configurable volumeMounts will result in Operator error
+ # See https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts for details
volumeMounts: []
# defines authorization strategy of the operator for the Jenkins API
diff --git a/website/content/en/docs/Getting Started/latest/schema.md b/website/content/en/docs/Getting Started/latest/schema.md
index 2a1444c7d..58638cbd2 100644
--- a/website/content/en/docs/Getting Started/latest/schema.md
+++ b/website/content/en/docs/Getting Started/latest/schema.md
@@ -661,7 +661,12 @@ Values defined by an Env with a duplicate key will take precedence.
(Optional)
-Pod volumes to mount into the container’s filesystem.
+
+Pod volumes to mount into the container’s filesystem. More info:
+
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+
+
diff --git a/website/content/en/docs/Installation/_index.md b/website/content/en/docs/Installation/_index.md
index fcd6ba282..17b8df645 100644
--- a/website/content/en/docs/Installation/_index.md
+++ b/website/content/en/docs/Installation/_index.md
@@ -883,7 +883,19 @@ If you wish to use the newest, not yet released version of the Operator, you can
You can find nightly built images by heading to [virtuslab/jenkins-operator](https://hub.docker.com/r/virtuslab/jenkins-operator) Docker Hub repository and looking for images with tag in the form of "{git-hash}", {git-hash} being the hash of master branch commit that you want to use snapshot of.
-## Note on Jenkins home Volume
-Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users. One of the key points of this design is maintaining an immutable state of Jenkins.
-
-One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume as Jenkins home directory. It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory, as attempting to do so will result in Operator error.
\ No newline at end of file
+## Note on restricted Jenkins controller pod volumeMounts
+Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users.
+One of the key points of this design is maintaining an immutable state of Jenkins.
+
+One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume
+(jenkins-home) as Jenkins home directory.
+It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory,
+as attempting to do so will result in Operator error.
+
+jenkins-home is not the only Jenkins controller pod volumeMount that is non-configurable and managed by Operator,
+below is the full list of those volumeMounts:
+
+* jenkins-home
+* scripts
+* init-configuration
+* operator-credentials
\ No newline at end of file
From b82fc7c7640a28a6b4912b533b9534d7e81288bb Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 6 Aug 2021 10:03:57 +0200
Subject: [PATCH 16/26] Auto-updated docs (#616)
Co-authored-by: Sig00rd
---
docs/docs/getting-started/latest/index.xml | 7 ++++-
.../getting-started/latest/schema/index.html | 9 ++++--
docs/docs/index.xml | 7 ++++-
docs/docs/installation/index.html | 22 +++++++++++---
website/package-lock.json | 30 +++++++++----------
5 files changed, 52 insertions(+), 23 deletions(-)
diff --git a/docs/docs/getting-started/latest/index.xml b/docs/docs/getting-started/latest/index.xml
index d6501db16..0b4fccb10 100644
--- a/docs/docs/getting-started/latest/index.xml
+++ b/docs/docs/getting-started/latest/index.xml
@@ -1679,7 +1679,12 @@ Values defined by an Env with a duplicate key will take precedence.</p>
</td>
<td>
<em>(Optional)</em>
-<p>Pod volumes to mount into the container’s filesystem.</p>
+<p>
+Pod volumes to mount into the container’s filesystem. More info:
+<a href="https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts">
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+</a>
+</p>
</td>
</tr>
<tr>
diff --git a/docs/docs/getting-started/latest/schema/index.html b/docs/docs/getting-started/latest/schema/index.html
index 59ee07c21..f31e941da 100644
--- a/docs/docs/getting-started/latest/schema/index.html
+++ b/docs/docs/getting-started/latest/schema/index.html
@@ -32,7 +32,7 @@
">
-
+
@@ -1471,7 +1471,12 @@
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+
+
diff --git a/docs/docs/index.xml b/docs/docs/index.xml
index 77dc07336..5f1c71ccd 100644
--- a/docs/docs/index.xml
+++ b/docs/docs/index.xml
@@ -6194,7 +6194,12 @@ Values defined by an Env with a duplicate key will take precedence.</p>
</td>
<td>
<em>(Optional)</em>
-<p>Pod volumes to mount into the container’s filesystem.</p>
+<p>
+Pod volumes to mount into the container’s filesystem. More info:
+<a href="https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts">
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+</a>
+</p>
</td>
</tr>
<tr>
diff --git a/docs/docs/installation/index.html b/docs/docs/installation/index.html
index 4aa60183a..728a3edb5 100644
--- a/docs/docs/installation/index.html
+++ b/docs/docs/installation/index.html
@@ -767,7 +767,7 @@
Configuring operator deployment
Note on Operator’s nightly built images
-Note on Jenkins home Volume
+Note on restricted Jenkins controller pod volumeMounts
@@ -1660,11 +1660,25 @@ Note on Operator’s nightl
You can find nightly built images by heading to virtuslab/jenkins-operator Docker Hub repository and looking for images with tag in the form of “{git-hash}”, {git-hash} being the hash of master branch commit that you want to use snapshot of.
-Note on Jenkins home Volume
+Note on restricted Jenkins controller pod volumeMounts
-Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users. One of the key points of this design is maintaining an immutable state of Jenkins.
+Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users.
+One of the key points of this design is maintaining an immutable state of Jenkins.
-One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume as Jenkins home directory. It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory, as attempting to do so will result in Operator error.
+One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume
+(jenkins-home) as Jenkins home directory.
+It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory,
+as attempting to do so will result in Operator error.
+
+jenkins-home is not the only Jenkins controller pod volumeMount that is non-configurable and managed by Operator,
+below is the full list of those volumeMounts:
+
+
+- jenkins-home
+- scripts
+- init-configuration
+- operator-credentials
+
diff --git a/website/package-lock.json b/website/package-lock.json
index fabb2bfa4..196e451f1 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -288,16 +288,16 @@
}
},
"browserslist": {
- "version": "4.16.6",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
- "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
+ "version": "4.16.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.7.tgz",
+ "integrity": "sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA==",
"dev": true,
"requires": {
- "caniuse-lite": "^1.0.30001219",
+ "caniuse-lite": "^1.0.30001248",
"colorette": "^1.2.2",
- "electron-to-chromium": "^1.3.723",
+ "electron-to-chromium": "^1.3.793",
"escalade": "^3.1.1",
- "node-releases": "^1.1.71"
+ "node-releases": "^1.1.73"
}
},
"cache-base": {
@@ -330,9 +330,9 @@
"dev": true
},
"caniuse-lite": {
- "version": "1.0.30001248",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001248.tgz",
- "integrity": "sha512-NwlQbJkxUFJ8nMErnGtT0QTM2TJ33xgz4KXJSMIrjXIbDVdaYueGyjOrLKRtJC+rTiWfi6j5cnZN1NBiSBJGNw==",
+ "version": "1.0.30001249",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001249.tgz",
+ "integrity": "sha512-vcX4U8lwVXPdqzPWi6cAJ3FnQaqXbBqy/GZseKNQzRj37J7qZdGcBtxq/QLFNLLlfsoXLUdHw8Iwenri86Tagw==",
"dev": true
},
"chalk": {
@@ -568,9 +568,9 @@
}
},
"electron-to-chromium": {
- "version": "1.3.792",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.792.tgz",
- "integrity": "sha512-RM2O2xrNarM7Cs+XF/OE2qX/aBROyOZqqgP+8FXMXSuWuUqCfUUzg7NytQrzZU3aSqk1Qq6zqnVkJsbfMkIatg==",
+ "version": "1.3.796",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.796.tgz",
+ "integrity": "sha512-agwJFgM0FUC1UPPbQ4aII3HamaaJ09fqWGAWYHmzxDWqdmTleCHyyA0kt3fJlTd5M440IaeuBfzXzXzCotnZcQ==",
"dev": true
},
"end-of-stream": {
@@ -1338,9 +1338,9 @@
"dev": true
},
"nan": {
- "version": "2.14.2",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
- "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
+ "version": "2.15.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
+ "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==",
"dev": true,
"optional": true
},
From b400a420e55209fcb9ee14f7cc85121737cd10d3 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 6 Aug 2021 13:06:12 +0200
Subject: [PATCH 17/26] Auto-updated docs (#617)
Co-authored-by: Sig00rd
---
website/package-lock.json | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/website/package-lock.json b/website/package-lock.json
index 196e451f1..334ea961a 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -568,9 +568,9 @@
}
},
"electron-to-chromium": {
- "version": "1.3.796",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.796.tgz",
- "integrity": "sha512-agwJFgM0FUC1UPPbQ4aII3HamaaJ09fqWGAWYHmzxDWqdmTleCHyyA0kt3fJlTd5M440IaeuBfzXzXzCotnZcQ==",
+ "version": "1.3.798",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.798.tgz",
+ "integrity": "sha512-fwsr6oXAORoV9a6Ak2vMCdXfmHIpAGgpOGesulS1cbGgJmrMl3H+GicUyRG3t+z9uHTMrIuMTleFDW+EUFYT3g==",
"dev": true
},
"end-of-stream": {
@@ -925,9 +925,9 @@
}
},
"graceful-fs": {
- "version": "4.2.6",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
- "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
+ "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
"dev": true
},
"has-flag": {
From 1d2651d43fb1616aa49611554fd678c4888b9bd5 Mon Sep 17 00:00:00 2001
From: sharmapulkit04
Date: Fri, 6 Aug 2021 19:01:27 +0530
Subject: [PATCH 18/26] Updated Validation logic - Defined a security manager
struct to cache all the plugin data - Added flag to make validating security
warnings optional while deploying the operator
---
api/v1alpha2/jenkins_webhook.go | 197 ++++++++++--------
.../samples/jenkins.io_v1alpha2_jenkins.yaml | 74 +------
main.go | 14 +-
webhook/all_in_one_v1alpha2.yaml | 11 +-
webhook/operator.yaml | 1 +
5 files changed, 129 insertions(+), 168 deletions(-)
diff --git a/api/v1alpha2/jenkins_webhook.go b/api/v1alpha2/jenkins_webhook.go
index 97af23c99..56750fc28 100644
--- a/api/v1alpha2/jenkins_webhook.go
+++ b/api/v1alpha2/jenkins_webhook.go
@@ -36,14 +36,9 @@ import (
)
var (
- jenkinslog = logf.Log.WithName("jenkins-resource") // log is for logging in this package.
- isRetrieved bool = false // For checking whether the data file is downloaded and extracted or not
-)
-
-const (
- hosturl string = "https://ci.jenkins.io/job/Infra/job/plugin-site-api/job/generate-data/lastSuccessfulBuild/artifact/plugins.json.gzip" // Url for downloading the plugins file
- compressedFile string = "/tmp/plugins.json.gzip" // location where the gzip file will be downloaded
- pluginDataFile string = "/tmp/plugins.json" // location where the file will be extracted
+ jenkinslog = logf.Log.WithName("jenkins-resource") // log is for logging in this package.
+ PluginsDataManager PluginDataManager = *NewPluginsDataManager()
+ _ webhook.Validator = &Jenkins{}
)
func (in *Jenkins) SetupWebhookWithManager(mgr ctrl.Manager) error {
@@ -57,8 +52,6 @@ func (in *Jenkins) SetupWebhookWithManager(mgr ctrl.Manager) error {
// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation.
// +kubebuilder:webhook:path=/validate-jenkins-io-jenkins-io-v1alpha2-jenkins,mutating=false,failurePolicy=fail,sideEffects=None,groups=jenkins.io.jenkins.io,resources=jenkins,verbs=create;update,versions=v1alpha2,name=vjenkins.kb.io,admissionReviewVersions={v1,v1beta1}
-var _ webhook.Validator = &Jenkins{}
-
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
func (in *Jenkins) ValidateCreate() error {
if in.Spec.ValidateSecurityWarnings {
@@ -83,6 +76,15 @@ func (in *Jenkins) ValidateDelete() error {
return nil
}
+type PluginDataManager struct {
+ pluginDataCache PluginsInfo
+ hosturl string
+ compressedFilePath string
+ pluginDataFile string
+ iscached bool
+ maxattempts int
+}
+
type PluginsInfo struct {
Plugins []PluginInfo `json:"plugins"`
}
@@ -112,36 +114,27 @@ type PluginData struct {
// Validates security warnings for both updating and creating a Jenkins CR
func Validate(r Jenkins) error {
-
pluginset := make(map[string]PluginData)
- var warningmsg string
+ var faultybaseplugins string
+ var faultyuserplugins string
basePlugins := plugins.BasePlugins()
- temp, err := NewPluginsInfo()
- AllPluginData := *temp
- if err != nil {
- return err
- }
for _, plugin := range basePlugins {
// Only Update the map if the plugin is not present or a lower version is being used
if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
- jenkinslog.Info("Validate", plugin.Name, plugin.Version)
pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "base"}
}
}
for _, plugin := range r.Spec.Master.Plugins {
if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
- jenkinslog.Info("Validate", plugin.Name, plugin.Version)
pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "user-defined"}
}
}
- jenkinslog.Info("Checking through all the warnings")
- for _, plugin := range AllPluginData.Plugins {
-
+ for _, plugin := range PluginsDataManager.pluginDataCache.Plugins {
if pluginData, ispresent := pluginset[plugin.Name]; ispresent {
- jenkinslog.Info("Checking for plugin", "name", plugin.Name)
+ var hasvulnerabilities bool
for _, warning := range plugin.SecurityWarnings {
for _, version := range warning.Versions {
firstVersion := version.FirstVersion
@@ -154,113 +147,121 @@ func Validate(r Jenkins) error {
}
if CompareVersions(firstVersion, lastVersion, pluginData.Version) {
- jenkinslog.Info("security Vulnerabilities detected", "message", warning.Message, "Check security Advisory", warning.URL)
- warningmsg += "Security Vulnerabilities detected in " + pluginData.Kind + " plugin " + plugin.Name + "\n"
-
+ jenkinslog.Info("Security Vulnerability detected in "+pluginData.Kind+" "+plugin.Name+":"+pluginData.Version, "Warning message", warning.Message, "For more details,check security advisory", warning.URL)
+ hasvulnerabilities = true
}
-
}
}
+ if hasvulnerabilities {
+ if pluginData.Kind == "base" {
+ faultybaseplugins += plugin.Name + ":" + pluginData.Version + "\n"
+ } else {
+ faultyuserplugins += plugin.Name + ":" + pluginData.Version + "\n"
+ }
+ }
}
-
}
-
- if len(warningmsg) > 0 {
- return errors.New(warningmsg)
+ if len(faultybaseplugins) > 0 || len(faultyuserplugins) > 0 {
+ var errormsg string
+ if len(faultybaseplugins) > 0 {
+ errormsg += "Security vulnerabilities detected in the following base plugins: \n" + faultybaseplugins
+ }
+ if len(faultyuserplugins) > 0 {
+ errormsg += "Security vulnerabilities detected in the following user-defined plugins: \n" + faultyuserplugins
+ }
+ return errors.New(errormsg)
}
return nil
-
}
-// Returns an object containing information of all the plugins present in the security center
-func NewPluginsInfo() (*PluginsInfo, error) {
- var AllPluginData PluginsInfo
- for i := 0; i < 28; i++ {
- if isRetrieved {
- break
- }
- time.Sleep(1 * time.Second)
- }
- if !isRetrieved {
- jenkinslog.Info("Plugins Data file hasn't been downloaded and extracted")
- return &AllPluginData, errors.New("plugins data file not found")
+func NewPluginsDataManager() *PluginDataManager {
+ return &PluginDataManager{
+ hosturl: "https://ci.jenkins.io/job/Infra/job/plugin-site-api/job/generate-data/lastSuccessfulBuild/artifact/plugins.json.gzip",
+ compressedFilePath: "/tmp/plugins.json.gzip",
+ pluginDataFile: "/tmp/plugins.json",
+ iscached: false,
+ maxattempts: 5,
}
+}
- jsonFile, err := os.Open(pluginDataFile)
- if err != nil {
- jenkinslog.Info("Failed to open the Plugins Data File")
- return &AllPluginData, err
- }
- defer jsonFile.Close()
+// Downloads extracts and caches the JSON data in every 12 hours
+func (in *PluginDataManager) CachePluginData(ch chan bool) {
+ for {
+ jenkinslog.Info("Initializing/Updating the plugin data cache")
+ var isdownloaded, isextracted, iscached bool
+ var err error
+ for i := 0; i < in.maxattempts; i++ {
+ err = in.Download()
+ if err == nil {
+ isdownloaded = true
+ break
+ }
+ }
- byteValue, err := ioutil.ReadAll(jsonFile)
- if err != nil {
- jenkinslog.Info("Failed to convert the JSON file into a byte array")
- return &AllPluginData, err
- }
- err = json.Unmarshal(byteValue, &AllPluginData)
- if err != nil {
- jenkinslog.Info("Failed to decode the Plugin JSON data file")
- return &AllPluginData, err
- }
+ if isdownloaded {
+ for i := 0; i < in.maxattempts; i++ {
+ err = in.Extract()
+ if err == nil {
+ isextracted = true
+ break
+ }
+ }
+ } else {
+ jenkinslog.Info("Cache Plugin Data", "failed to download file", err)
+ }
- return &AllPluginData, nil
-}
+ if isextracted {
+ for i := 0; i < in.maxattempts; i++ {
+ err = in.Cache()
+ if err == nil {
+ iscached = true
+ break
+ }
+ }
-// Downloads and extracts the JSON file in every 12 hours
-func RetrieveDataFile() {
- for {
- jenkinslog.Info("Retreiving file", "Host Url", hosturl)
- err := Download()
- if err != nil {
- jenkinslog.Info("Retrieving File", "Error while downloading", err)
- continue
+ if !iscached {
+ jenkinslog.Info("Cache Plugin Data", "failed to read plugin data file", err)
+ }
+ } else {
+ jenkinslog.Info("Cache Plugin Data", "failed to extract file", err)
}
- jenkinslog.Info("Retrieve File", "Successfully downloaded", compressedFile)
- err = Extract()
- if err != nil {
- jenkinslog.Info("Retreive File", "Error while extracting", err)
- continue
+ if !in.iscached {
+ ch <- iscached
}
- jenkinslog.Info("Retreive File", "Successfully extracted", pluginDataFile)
- isRetrieved = true
+ in.iscached = in.iscached || iscached
time.Sleep(12 * time.Hour)
-
}
}
-func Download() error {
-
- out, err := os.Create(compressedFile)
+func (in *PluginDataManager) Download() error {
+ out, err := os.Create(in.compressedFilePath)
if err != nil {
return err
}
defer out.Close()
client := http.Client{
- Timeout: 2000 * time.Second,
+ Timeout: 1000 * time.Second,
}
- resp, err := client.Get(hosturl)
+ resp, err := client.Get(in.hosturl)
if err != nil {
return err
}
defer resp.Body.Close()
- jenkinslog.Info("Successfully Downloaded")
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
-
}
-func Extract() error {
- reader, err := os.Open(compressedFile)
+func (in *PluginDataManager) Extract() error {
+ reader, err := os.Open(in.compressedFilePath)
if err != nil {
return err
@@ -272,7 +273,7 @@ func Extract() error {
}
defer archive.Close()
- writer, err := os.Create(pluginDataFile)
+ writer, err := os.Create(in.pluginDataFile)
if err != nil {
return err
}
@@ -280,10 +281,28 @@ func Extract() error {
_, err = io.Copy(writer, archive)
return err
+}
+// Loads the JSON data into memory and stores it
+func (in *PluginDataManager) Cache() error {
+ jsonFile, err := os.Open(in.pluginDataFile)
+ if err != nil {
+ return err
+ }
+ defer jsonFile.Close()
+
+ byteValue, err := ioutil.ReadAll(jsonFile)
+ if err != nil {
+ return err
+ }
+ err = json.Unmarshal(byteValue, &in.pluginDataCache)
+ if err != nil {
+ return err
+ }
+ return nil
}
-// returns a semantic version that can be used for comparision
+// returns a semantic version that can be used for comparison
func MakeSemanticVersion(version string) string {
version = "v" + version
return semver.Canonical(version)
diff --git a/config/samples/jenkins.io_v1alpha2_jenkins.yaml b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
index be33732a9..49f39c931 100644
--- a/config/samples/jenkins.io_v1alpha2_jenkins.yaml
+++ b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
@@ -1,8 +1,9 @@
+
apiVersion: jenkins.io/v1alpha2
kind: Jenkins
metadata:
- name: example-8
- namespace: default
+ name: example
+ namespace: default
spec:
configurationAsCode:
configurations: []
@@ -14,7 +15,6 @@ spec:
name: ""
jenkinsAPISettings:
authorizationStrategy: createUser
- ValidateSecurityWarnings: true
master:
disableCSRFProtection: false
containers:
@@ -48,75 +48,9 @@ spec:
requests:
cpu: "1"
memory: 500Mi
- plugins:
- - name: mailer
- version: "1.19"
- - name: script-security
- version: "1.18"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: credentials
- version: "2.1"
- - name: ssh-credentials
- version: "1.1"
- - name: junit
- version: "1.2"
- - name: matrix-project
- version: "1.1"
- - name: git-client
- version: "2.8.4"
- - name: pipeline-model-definition
- version: "1.3.0"
- - name: favorite
- version: "2"
- - name: workflow-cps
- version: "2"
-
seedJobs:
- id: jenkins-operator
targets: "cicd/jobs/*.jenkins"
description: "Jenkins Operator repository"
repositoryBranch: master
- repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
+ repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
\ No newline at end of file
diff --git a/main.go b/main.go
index 3cd399f6a..936862f1c 100644
--- a/main.go
+++ b/main.go
@@ -78,6 +78,7 @@ func main() {
var metricsAddr string
var enableLeaderElection bool
var probeAddr string
+ var ValidateSecurityWarnings bool
isRunningInCluster, err := resources.IsRunningInCluster()
if err != nil {
@@ -88,6 +89,7 @@ func main() {
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "leader-elect", isRunningInCluster, "Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
+ flag.BoolVar(&ValidateSecurityWarnings, "validate-security-warnings", false, "Enable validation for potential security warnings in jenkins custom resource plugins")
hostname := flag.String("jenkins-api-hostname", "", "Hostname or IP of Jenkins API. It can be service name, node IP or localhost.")
port := flag.Int("jenkins-api-port", 0, "The port on which Jenkins API is running. Note: If you want to use nodePort don't set this setting and --jenkins-api-use-nodeport must be true.")
useNodePort := flag.Bool("jenkins-api-use-nodeport", false, "Connect to Jenkins API using the service nodePort instead of service port. If you want to set this as true - don't set --jenkins-api-port.")
@@ -95,9 +97,6 @@ func main() {
opts := zap.Options{
Development: true,
}
-
- go v1alpha2.RetrieveDataFile()
-
opts.BindFlags(flag.CommandLine)
flag.Parse()
@@ -112,6 +111,15 @@ func main() {
}
logger.Info(fmt.Sprintf("Watch namespace: %v", namespace))
+ if ValidateSecurityWarnings {
+ ispluginsdatainitialized := make(chan bool)
+ go v1alpha2.PluginsDataManager.CachePluginData(ispluginsdatainitialized)
+
+ if !<-ispluginsdatainitialized {
+ fatal(errors.New("Unable to get the plugins data"), *debug)
+ }
+ }
+
// get a config to talk to the API server
cfg, err := config.GetConfig()
if err != nil {
diff --git a/webhook/all_in_one_v1alpha2.yaml b/webhook/all_in_one_v1alpha2.yaml
index 0d878dd2d..18afb8010 100644
--- a/webhook/all_in_one_v1alpha2.yaml
+++ b/webhook/all_in_one_v1alpha2.yaml
@@ -247,7 +247,7 @@ spec:
- /manager
args:
- --leader-elect
- image: jenkins-operator:52fe5fe9-dirty
+ image: jenkins-operator:37d0eac4-dirty
name: jenkins-operator
imagePullPolicy: IfNotPresent
securityContext:
@@ -266,11 +266,11 @@ spec:
periodSeconds: 10
resources:
limits:
- cpu: 100m
- memory: 30Mi
+ cpu: 200m
+ memory: 200Mi
requests:
cpu: 100m
- memory: 20Mi
+ memory: 80Mi
env:
- name: WATCH_NAMESPACE
valueFrom:
@@ -278,8 +278,7 @@ spec:
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
- name: cert
- readOnly: false
+ name: cert
volumes:
- name: cert
secret:
diff --git a/webhook/operator.yaml b/webhook/operator.yaml
index c056ba8e0..01093af2d 100644
--- a/webhook/operator.yaml
+++ b/webhook/operator.yaml
@@ -23,6 +23,7 @@ spec:
- /manager
args:
- --leader-elect
+ - --validate-security-warnings
image: {DOCKER_REGISTRY}:{GITCOMMIT}
name: jenkins-operator
imagePullPolicy: IfNotPresent
From 853f4857466922de550f934d459951b4a1e02341 Mon Sep 17 00:00:00 2001
From: Morten Birkelund
Date: Mon, 9 Aug 2021 14:57:00 +0200
Subject: [PATCH 19/26] Helm Chart: Remove empty priorityClassName from Jenkins
template (#618)
Also bump Helm Chart version to v0.5.2
---
chart/index.yaml | 10 ++++++++++
chart/jenkins-operator/Chart.yaml | 2 +-
.../jenkins-operator/jenkins-operator-0.5.2.tgz | Bin 0 -> 34161 bytes
chart/jenkins-operator/templates/jenkins.yaml | 2 --
4 files changed, 11 insertions(+), 3 deletions(-)
create mode 100644 chart/jenkins-operator/jenkins-operator-0.5.2.tgz
diff --git a/chart/index.yaml b/chart/index.yaml
index b7e1f5541..0044cbebe 100644
--- a/chart/index.yaml
+++ b/chart/index.yaml
@@ -1,6 +1,16 @@
apiVersion: v1
entries:
jenkins-operator:
+ - apiVersion: v2
+ appVersion: 0.6.0
+ created: "2021-06-11T13:50:32.677639006+02:00"
+ description: Kubernetes native operator which fully manages Jenkins on Kubernetes
+ digest: 48fbf15c3ffff7003623edcde0bec39dc37d0a62303f08066960d5fac799af90
+ icon: https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/assets/jenkins-operator-icon.png
+ name: jenkins-operator
+ urls:
+ - https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/chart/jenkins-operator/jenkins-operator-0.5.2.tgz
+ version: 0.5.2
- apiVersion: v2
appVersion: 0.6.0
created: "2021-06-11T13:50:32.677639006+02:00"
diff --git a/chart/jenkins-operator/Chart.yaml b/chart/jenkins-operator/Chart.yaml
index 9d8c137d7..d90d312a6 100644
--- a/chart/jenkins-operator/Chart.yaml
+++ b/chart/jenkins-operator/Chart.yaml
@@ -2,5 +2,5 @@ apiVersion: v2
appVersion: "0.6.0"
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
name: jenkins-operator
-version: 0.5.1
+version: 0.5.2
icon: https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/assets/jenkins-operator-icon.png
diff --git a/chart/jenkins-operator/jenkins-operator-0.5.2.tgz b/chart/jenkins-operator/jenkins-operator-0.5.2.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..c2f1afe9e0063a9c2e03b84b419cade3074dd85f
GIT binary patch
literal 34161
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
Deploy Jenkins
@@ -846,8 +848,6 @@
-
-
Configuration
diff --git a/docs/docs/index.html b/docs/docs/index.html
index 001c8b57a..c8d69c8ed 100644
--- a/docs/docs/index.html
+++ b/docs/docs/index.html
@@ -789,10 +789,6 @@ Documentation
-
-
-
-
Installation
@@ -832,6 +828,10 @@
+
+
+
+
diff --git a/docs/docs/index.xml b/docs/docs/index.xml
index 6024f26d8..77dc07336 100644
--- a/docs/docs/index.xml
+++ b/docs/docs/index.xml
@@ -651,7 +651,7 @@ spec:
targets: "cicd/jobs/*.jenkins"
description: "Jenkins Operator repository"
repositoryBranch: master
- repositoryUrl: ssh://git@github.com:jenkinsci/kubernetes-operator.git</code></pre>
+ repositoryUrl: git@github.com:jenkinsci/kubernetes-operator.git</code></pre>
<p>and create a Kubernetes Secret (name of secret should be the same from <code>credentialID</code> field):</p>
<pre><code>apiVersion: v1
kind: Secret
@@ -2167,14 +2167,17 @@ stringData:
Plugin’s configuration is applied as groovy scripts or the <a href="https://github.com/jenkinsci/configuration-as-code-plugin">configuration as code plugin</a>.
Any plugin working for Jenkins can be installed by the Jenkins Operator.</p>
-<p>Pre-installed plugins:
-* configuration-as-code v1.47
-* git v4.5.0
-* job-dsl v1.77
-* kubernetes-credentials-provider v0.15
-* kubernetes v1.29.0
-* workflow-aggregator v2.6
-* workflow-job v2.40</p>
+<p>Pre-installed plugins:</p>
+
+<ul>
+<li>configuration-as-code v1.51</li>
+<li>git v4.7.2</li>
+<li>job-dsl v1.77</li>
+<li>kubernetes-credentials-provider v0.18-1</li>
+<li>kubernetes v1.30.0</li>
+<li>workflow-aggregator v2.6</li>
+<li>workflow-job v2.41</li>
+</ul>
<p>Rest of the plugins can be found in <a href="https://plugins.jenkins.io/">plugins repository</a>.</p>
@@ -2199,19 +2202,19 @@ Any plugin working for Jenkins can be installed by the Jenkins Operator.</p&g
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>master<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>basePlugins<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>kubernetes<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.28.6"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.30.0"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>workflow-job<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"2.40"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>workflow-aggregator<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"2.6"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>git<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"4.5.0"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"4.7.2"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>job-dsl<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.77"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>configuration-as-code<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.46"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.51"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>kubernetes-credentials-provider<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"0.15"</span></code></pre></div>
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"0.18-1"</span></code></pre></div>
<p>You can change their versions.</p>
<p>The <strong>Jenkins Operator</strong> will then automatically install plugins after the Jenkins master pod restart.</p>
diff --git a/docs/docs/installation/index.html b/docs/docs/installation/index.html
index eb6372364..4aa60183a 100644
--- a/docs/docs/installation/index.html
+++ b/docs/docs/installation/index.html
@@ -26,7 +26,7 @@
" />
-
+
@@ -766,6 +766,8 @@
+
Note on Operator’s nightly built images
+Note on Jenkins home Volume
@@ -808,18 +810,21 @@ Installation
This document describes installation procedure for Jenkins Operator.
-All container images can be found at virtuslab/jenkins-operator
+All container images can be found at virtuslab/jenkins-operator Docker Hub repository.
Requirements
-To run Jenkins Operator, you will need:
-- access to a Kubernetes cluster version 1.17+
-- kubectl
version 1.17+
+To run Jenkins Operator, you will need:
-Listed below are the two ways to deploy Jenkins Operator. For details on how to customize your Jenkins instance, refer to Getting Started
+
+- access to a Kubernetes cluster version
1.17+
+kubectl
version 1.17+
+
+
+Listed below are the two ways to deploy Jenkins Operator. For details on how to customize your Jenkins instance, refer to Getting Started.
Deploy Jenkins Operator using YAML’s
@@ -1649,6 +1654,18 @@ Configuring operator deployment
+Note on Operator’s nightly built images
+
+If you wish to use the newest, not yet released version of the Operator, you can use one of nightly built snapshot images, however the maintainers of this project cannot guarantee their stability.
+
+You can find nightly built images by heading to virtuslab/jenkins-operator Docker Hub repository and looking for images with tag in the form of “{git-hash}”, {git-hash} being the hash of master branch commit that you want to use snapshot of.
+
+Note on Jenkins home Volume
+
+Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users. One of the key points of this design is maintaining an immutable state of Jenkins.
+
+One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume as Jenkins home directory. It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory, as attempting to do so will result in Operator error.
+
@@ -1805,7 +1822,7 @@ Configuring operator deployment
- Last modified October 5, 2020
+ Last modified July 30, 2021
diff --git a/docs/docs/installation/index.xml b/docs/docs/installation/index.xml
index 9bc06edf8..37e38d051 100644
--- a/docs/docs/installation/index.xml
+++ b/docs/docs/installation/index.xml
@@ -4,7 +4,7 @@
https://jenkinsci.github.io/kubernetes-operator/docs/installation/
Recent Hugo news from gohugo.io
Hugo -- gohugo.io
- Mon, 05 Oct 2020 00:00:00 +0000
+ Fri, 30 Jul 2021 00:00:00 +0000
https://jenkinsci.github.io/kubernetes-operator/img/hugo.png
GoHugo.io
diff --git a/docs/sitemap.xml b/docs/sitemap.xml
index efa05ade3..b751f91fc 100644
--- a/docs/sitemap.xml
+++ b/docs/sitemap.xml
@@ -3,18 +3,18 @@
xmlns:xhtml="http://www.w3.org/1999/xhtml">
- https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/deploy-jenkins/
- 2021-01-25T00:00:00+00:00
+ https://jenkinsci.github.io/kubernetes-operator/docs/installation/
+ 2021-07-30T00:00:00+00:00
- https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/v0.5.x/deploy-jenkins/
+ https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/deploy-jenkins/
2021-01-25T00:00:00+00:00
- https://jenkinsci.github.io/kubernetes-operator/docs/installation/
- 2020-10-05T00:00:00+00:00
+ https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/v0.5.x/deploy-jenkins/
+ 2021-01-25T00:00:00+00:00
@@ -369,7 +369,7 @@
https://jenkinsci.github.io/kubernetes-operator/docs/developer-guide/
- 2021-06-10T00:00:00+00:00
+ 2021-07-30T00:00:00+00:00
diff --git a/website/package-lock.json b/website/package-lock.json
index 57c68fa43..fabb2bfa4 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -330,9 +330,9 @@
"dev": true
},
"caniuse-lite": {
- "version": "1.0.30001245",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001245.tgz",
- "integrity": "sha512-768fM9j1PKXpOCKws6eTo3RHmvTUsG9UrpT4WoREFeZgJBTi4/X9g565azS/rVUGtqb8nt7FjLeF5u4kukERnA==",
+ "version": "1.0.30001248",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001248.tgz",
+ "integrity": "sha512-NwlQbJkxUFJ8nMErnGtT0QTM2TJ33xgz4KXJSMIrjXIbDVdaYueGyjOrLKRtJC+rTiWfi6j5cnZN1NBiSBJGNw==",
"dev": true
},
"chalk": {
@@ -568,9 +568,9 @@
}
},
"electron-to-chromium": {
- "version": "1.3.780",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.780.tgz",
- "integrity": "sha512-2KQ9OYm9WMUNpAPA/4aerURl3hwRc9tNlpsiEj3Y8Gf7LVf26NzyLIX2v0hSagQwrS9+cWab+28A2GPKDoVNRA==",
+ "version": "1.3.792",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.792.tgz",
+ "integrity": "sha512-RM2O2xrNarM7Cs+XF/OE2qX/aBROyOZqqgP+8FXMXSuWuUqCfUUzg7NytQrzZU3aSqk1Qq6zqnVkJsbfMkIatg==",
"dev": true
},
"end-of-stream": {
From 37d0eac4e394d314bef2666aee850ed85b8312d8 Mon Sep 17 00:00:00 2001
From: sharmapulkit04
Date: Wed, 4 Aug 2021 16:06:14 +0530
Subject: [PATCH 13/26] Reimplemented the validation logic with caching the
security warnings - Reimplemented the validator interface - Updated manifests
to allocate more resources
---
Dockerfile | 2 +-
api/v1alpha2/jenkins_webhook.go | 268 ++++++++++++------
.../samples/jenkins.io_v1alpha2_jenkins.yaml | 71 ++++-
main.go | 3 +
webhook/all_in_one_v1alpha2.yaml | 9 +-
webhook/operator.yaml | 12 +-
webhook/webhook.yaml | 2 +-
7 files changed, 274 insertions(+), 93 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index ff840ea45..caaced1d7 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -19,6 +19,7 @@ COPY internal/ internal/
COPY pkg/ pkg/
COPY version/ version/
COPY main.go main.go
+RUN mkdir plugins/
# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -ldflags "-w $CTIMEVAR" -o manager main.go
@@ -29,5 +30,4 @@ FROM gcr.io/distroless/static:nonroot
WORKDIR /
COPY --from=builder /workspace/manager .
USER 65532:65532
-
ENTRYPOINT ["/manager"]
diff --git a/api/v1alpha2/jenkins_webhook.go b/api/v1alpha2/jenkins_webhook.go
index 494fdb802..97af23c99 100644
--- a/api/v1alpha2/jenkins_webhook.go
+++ b/api/v1alpha2/jenkins_webhook.go
@@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
+ http://www.apache.org/lictenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,10 +17,13 @@ limitations under the License.
package v1alpha2
import (
+ "compress/gzip"
"encoding/json"
"errors"
+ "io"
"io/ioutil"
"net/http"
+ "os"
"time"
"github.com/jenkinsci/kubernetes-operator/pkg/plugins"
@@ -32,8 +35,16 @@ import (
"sigs.k8s.io/controller-runtime/pkg/webhook"
)
-// log is for logging in this package.
-var jenkinslog = logf.Log.WithName("jenkins-resource")
+var (
+ jenkinslog = logf.Log.WithName("jenkins-resource") // log is for logging in this package.
+ isRetrieved bool = false // For checking whether the data file is downloaded and extracted or not
+)
+
+const (
+ hosturl string = "https://ci.jenkins.io/job/Infra/job/plugin-site-api/job/generate-data/lastSuccessfulBuild/artifact/plugins.json.gzip" // Url for downloading the plugins file
+ compressedFile string = "/tmp/plugins.json.gzip" // location where the gzip file will be downloaded
+ pluginDataFile string = "/tmp/plugins.json" // location where the file will be extracted
+)
func (in *Jenkins) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
@@ -72,8 +83,13 @@ func (in *Jenkins) ValidateDelete() error {
return nil
}
-type Warnings struct {
- Warnings []Warning `json:"securityWarnings"`
+type PluginsInfo struct {
+ Plugins []PluginInfo `json:"plugins"`
+}
+
+type PluginInfo struct {
+ Name string `json:"name"`
+ SecurityWarnings []Warning `json:"securityWarnings"`
}
type Warning struct {
@@ -83,109 +99,203 @@ type Warning struct {
URL string `json:"url"`
Active bool `json:"active"`
}
+
type Version struct {
FirstVersion string `json:"firstVersion"`
LastVersion string `json:"lastVersion"`
}
-const APIURL string = "https://plugins.jenkins.io/api/plugin/"
-
-func MakeSemanticVersion(version string) string {
- version = "v" + version
- return semver.Canonical(version)
+type PluginData struct {
+ Version string
+ Kind string
}
-func CompareVersions(firstVersion string, lastVersion string, pluginVersion string) bool {
- firstSemVer := MakeSemanticVersion(firstVersion)
- lastSemVer := MakeSemanticVersion(lastVersion)
- pluginSemVer := MakeSemanticVersion(pluginVersion)
- if semver.Compare(pluginSemVer, firstSemVer) == -1 || semver.Compare(pluginSemVer, lastSemVer) == 1 {
- return false
- }
- return true
-}
+// Validates security warnings for both updating and creating a Jenkins CR
+func Validate(r Jenkins) error {
-func CheckSecurityWarnings(pluginName string, pluginVersion string) (bool, error) {
- jenkinslog.Info("checking security warnings", "plugin: ", pluginName)
- pluginURL := APIURL + pluginName
- client := &http.Client{
- Timeout: time.Second * 30,
- }
- request, err := http.NewRequest("GET", pluginURL, nil)
- if err != nil {
- return false, err
- }
- request.Header.Add("Accept", "application/json")
- request.Header.Add("Content-Type", "application/json")
- response, err := client.Do(request)
- if err != nil {
- return false, err
- }
- defer response.Body.Close()
- bodyBytes, err := ioutil.ReadAll(response.Body)
+ pluginset := make(map[string]PluginData)
+ var warningmsg string
+ basePlugins := plugins.BasePlugins()
+ temp, err := NewPluginsInfo()
+ AllPluginData := *temp
if err != nil {
- return false, err
+ return err
}
- securityWarnings := Warnings{}
- jsonErr := json.Unmarshal(bodyBytes, &securityWarnings)
- if jsonErr != nil {
- return false, err
+ for _, plugin := range basePlugins {
+ // Only Update the map if the plugin is not present or a lower version is being used
+ if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
+ jenkinslog.Info("Validate", plugin.Name, plugin.Version)
+ pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "base"}
+ }
}
- jenkinslog.Info("Validate()", "warnings", securityWarnings)
+ for _, plugin := range r.Spec.Master.Plugins {
+ if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
+ jenkinslog.Info("Validate", plugin.Name, plugin.Version)
+ pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "user-defined"}
+ }
+ }
- for _, warning := range securityWarnings.Warnings {
- for _, version := range warning.Versions {
- firstVersion := version.FirstVersion
- lastVersion := version.LastVersion
- if len(firstVersion) == 0 {
- firstVersion = "0" // setting default value in case of empty string
- }
- if len(lastVersion) == 0 {
- lastVersion = pluginVersion // setting default value in case of empty string
+ jenkinslog.Info("Checking through all the warnings")
+ for _, plugin := range AllPluginData.Plugins {
+
+ if pluginData, ispresent := pluginset[plugin.Name]; ispresent {
+ jenkinslog.Info("Checking for plugin", "name", plugin.Name)
+ for _, warning := range plugin.SecurityWarnings {
+ for _, version := range warning.Versions {
+ firstVersion := version.FirstVersion
+ lastVersion := version.LastVersion
+ if len(firstVersion) == 0 {
+ firstVersion = "0" // setting default value in case of empty string
+ }
+ if len(lastVersion) == 0 {
+ lastVersion = pluginData.Version // setting default value in case of empty string
+ }
+
+ if CompareVersions(firstVersion, lastVersion, pluginData.Version) {
+ jenkinslog.Info("security Vulnerabilities detected", "message", warning.Message, "Check security Advisory", warning.URL)
+ warningmsg += "Security Vulnerabilities detected in " + pluginData.Kind + " plugin " + plugin.Name + "\n"
+
+ }
+
+ }
}
- if CompareVersions(firstVersion, lastVersion, pluginVersion) {
- jenkinslog.Info("security Vulnerabilities detected", "message", warning.Message, "Check security Advisory", warning.URL)
- return true, nil
- }
}
+
}
- return false, nil
-}
+ if len(warningmsg) > 0 {
+ return errors.New(warningmsg)
+ }
-func Validate(r Jenkins) error {
- basePlugins := plugins.BasePlugins()
- var warnings string = ""
+ return nil
- for _, plugin := range basePlugins {
- name := plugin.Name
- version := plugin.Version
- hasWarnings, err := CheckSecurityWarnings(name, version)
- if err != nil {
- return err
- }
- if hasWarnings {
- warnings += "Security Vulnerabilities detected in base plugin:" + name
+}
+
+// Returns an object containing information of all the plugins present in the security center
+func NewPluginsInfo() (*PluginsInfo, error) {
+ var AllPluginData PluginsInfo
+ for i := 0; i < 28; i++ {
+ if isRetrieved {
+ break
}
+ time.Sleep(1 * time.Second)
+ }
+ if !isRetrieved {
+ jenkinslog.Info("Plugins Data file hasn't been downloaded and extracted")
+ return &AllPluginData, errors.New("plugins data file not found")
}
- for _, plugin := range r.Spec.Master.Plugins {
- name := plugin.Name
- version := plugin.Version
- hasWarnings, err := CheckSecurityWarnings(name, version)
+ jsonFile, err := os.Open(pluginDataFile)
+ if err != nil {
+ jenkinslog.Info("Failed to open the Plugins Data File")
+ return &AllPluginData, err
+ }
+ defer jsonFile.Close()
+
+ byteValue, err := ioutil.ReadAll(jsonFile)
+ if err != nil {
+ jenkinslog.Info("Failed to convert the JSON file into a byte array")
+ return &AllPluginData, err
+ }
+ err = json.Unmarshal(byteValue, &AllPluginData)
+ if err != nil {
+ jenkinslog.Info("Failed to decode the Plugin JSON data file")
+ return &AllPluginData, err
+ }
+
+ return &AllPluginData, nil
+}
+
+// Downloads and extracts the JSON file in every 12 hours
+func RetrieveDataFile() {
+ for {
+ jenkinslog.Info("Retreiving file", "Host Url", hosturl)
+ err := Download()
if err != nil {
- return err
+ jenkinslog.Info("Retrieving File", "Error while downloading", err)
+ continue
}
- if hasWarnings {
- warnings += "Security Vulnerabilities detected in the user defined plugin: " + name
+
+ jenkinslog.Info("Retrieve File", "Successfully downloaded", compressedFile)
+ err = Extract()
+ if err != nil {
+ jenkinslog.Info("Retreive File", "Error while extracting", err)
+ continue
}
+ jenkinslog.Info("Retreive File", "Successfully extracted", pluginDataFile)
+ isRetrieved = true
+ time.Sleep(12 * time.Hour)
+
}
- if len(warnings) > 0 {
- return errors.New(warnings)
+}
+
+func Download() error {
+
+ out, err := os.Create(compressedFile)
+ if err != nil {
+ return err
+ }
+ defer out.Close()
+
+ client := http.Client{
+ Timeout: 2000 * time.Second,
+ }
+
+ resp, err := client.Get(hosturl)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ jenkinslog.Info("Successfully Downloaded")
+ _, err = io.Copy(out, resp.Body)
+ if err != nil {
+ return err
}
return nil
+
+}
+
+func Extract() error {
+ reader, err := os.Open(compressedFile)
+
+ if err != nil {
+ return err
+ }
+ defer reader.Close()
+ archive, err := gzip.NewReader(reader)
+ if err != nil {
+ return err
+ }
+
+ defer archive.Close()
+ writer, err := os.Create(pluginDataFile)
+ if err != nil {
+ return err
+ }
+ defer writer.Close()
+
+ _, err = io.Copy(writer, archive)
+ return err
+
+}
+
+// returns a semantic version that can be used for comparision
+func MakeSemanticVersion(version string) string {
+ version = "v" + version
+ return semver.Canonical(version)
+}
+
+// Compare if the current version lies between first version and last version
+func CompareVersions(firstVersion string, lastVersion string, pluginVersion string) bool {
+ firstSemVer := MakeSemanticVersion(firstVersion)
+ lastSemVer := MakeSemanticVersion(lastVersion)
+ pluginSemVer := MakeSemanticVersion(pluginVersion)
+ if semver.Compare(pluginSemVer, firstSemVer) == -1 || semver.Compare(pluginSemVer, lastSemVer) == 1 {
+ return false
+ }
+ return true
}
diff --git a/config/samples/jenkins.io_v1alpha2_jenkins.yaml b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
index b451d5dab..be33732a9 100644
--- a/config/samples/jenkins.io_v1alpha2_jenkins.yaml
+++ b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
@@ -1,8 +1,8 @@
apiVersion: jenkins.io/v1alpha2
kind: Jenkins
metadata:
- name: example
- namespace: default
+ name: example-8
+ namespace: default
spec:
configurationAsCode:
configurations: []
@@ -14,6 +14,7 @@ spec:
name: ""
jenkinsAPISettings:
authorizationStrategy: createUser
+ ValidateSecurityWarnings: true
master:
disableCSRFProtection: false
containers:
@@ -47,6 +48,72 @@ spec:
requests:
cpu: "1"
memory: 500Mi
+ plugins:
+ - name: mailer
+ version: "1.19"
+ - name: script-security
+ version: "1.18"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: credentials
+ version: "2.1"
+ - name: ssh-credentials
+ version: "1.1"
+ - name: junit
+ version: "1.2"
+ - name: matrix-project
+ version: "1.1"
+ - name: git-client
+ version: "2.8.4"
+ - name: pipeline-model-definition
+ version: "1.3.0"
+ - name: favorite
+ version: "2"
+ - name: workflow-cps
+ version: "2"
+
seedJobs:
- id: jenkins-operator
targets: "cicd/jobs/*.jenkins"
diff --git a/main.go b/main.go
index 8bc382ead..3cd399f6a 100644
--- a/main.go
+++ b/main.go
@@ -95,6 +95,9 @@ func main() {
opts := zap.Options{
Development: true,
}
+
+ go v1alpha2.RetrieveDataFile()
+
opts.BindFlags(flag.CommandLine)
flag.Parse()
diff --git a/webhook/all_in_one_v1alpha2.yaml b/webhook/all_in_one_v1alpha2.yaml
index e53fc659f..0d878dd2d 100644
--- a/webhook/all_in_one_v1alpha2.yaml
+++ b/webhook/all_in_one_v1alpha2.yaml
@@ -222,6 +222,7 @@ subjects:
- kind: ServiceAccount
name: jenkins-operator
---
+---
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -246,7 +247,7 @@ spec:
- /manager
args:
- --leader-elect
- image: jenkins-operator:6f33fe82-dirty
+ image: jenkins-operator:52fe5fe9-dirty
name: jenkins-operator
imagePullPolicy: IfNotPresent
securityContext:
@@ -278,12 +279,12 @@ spec:
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
- readOnly: true
+ readOnly: false
volumes:
- name: cert
secret:
defaultMode: 420
- secretName: webhook-server-cert
+ secretName: webhook-server-cert
terminationGracePeriodSeconds: 10
---
apiVersion: cert-manager.io/v1
@@ -315,7 +316,6 @@ spec:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
- creationTimestamp: null
name: validating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: default/webhook-certificate
@@ -330,6 +330,7 @@ webhooks:
path: /validate-jenkins-io-v1alpha2-jenkins
failurePolicy: Fail
name: vjenkins.kb.io
+ timeoutSeconds: 30
rules:
- apiGroups:
- jenkins.io
diff --git a/webhook/operator.yaml b/webhook/operator.yaml
index 81cbdf98e..c056ba8e0 100644
--- a/webhook/operator.yaml
+++ b/webhook/operator.yaml
@@ -1,3 +1,4 @@
+---
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -41,11 +42,11 @@ spec:
periodSeconds: 10
resources:
limits:
- cpu: 100m
- memory: 30Mi
+ cpu: 200m
+ memory: 200Mi
requests:
cpu: 100m
- memory: 20Mi
+ memory: 80Mi
env:
- name: WATCH_NAMESPACE
valueFrom:
@@ -53,12 +54,11 @@ spec:
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
- name: cert
- readOnly: true
+ name: cert
volumes:
- name: cert
secret:
defaultMode: 420
- secretName: webhook-server-cert
+ secretName: webhook-server-cert
terminationGracePeriodSeconds: 10
---
diff --git a/webhook/webhook.yaml b/webhook/webhook.yaml
index 3a86ab0b1..9cc2a2b74 100644
--- a/webhook/webhook.yaml
+++ b/webhook/webhook.yaml
@@ -1,7 +1,6 @@
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
- creationTimestamp: null
name: validating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: default/webhook-certificate
@@ -16,6 +15,7 @@ webhooks:
path: /validate-jenkins-io-v1alpha2-jenkins
failurePolicy: Fail
name: vjenkins.kb.io
+ timeoutSeconds: 30
rules:
- apiGroups:
- jenkins.io
From 8453b3e9fecfa8ad7fe06732923476c424f7e8c4 Mon Sep 17 00:00:00 2001
From: Szymon Fugas
Date: Thu, 5 Aug 2021 17:27:19 +0200
Subject: [PATCH 14/26] Add an issue template for documentation (#613)
---
.github/ISSUE_TEMPLATE/documentation.md | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100644 .github/ISSUE_TEMPLATE/documentation.md
diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md
new file mode 100644
index 000000000..a0ed0b42c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/documentation.md
@@ -0,0 +1,14 @@
+---
+name: "📚 Documentation issue"
+about: Suggest changes to project's documentation
+title: ''
+labels: 'documentation'
+projects: ''
+assignees: ''
+---
+
+**Relevant links*
+Link(s) to the section(s) of documentation that are outdated or otherwise wrong
+
+**Description**
+Description of the changes you would like to see
\ No newline at end of file
From 858f0f4c7289bd518ac419d57116907940109429 Mon Sep 17 00:00:00 2001
From: Szymon Fugas
Date: Thu, 5 Aug 2021 17:28:01 +0200
Subject: [PATCH 15/26] Docs: add info on restricted volumeMounts other than
jenkins-home(#612)
* Update note in installation docs
* Update Helm chart default values.yaml
* Update schema
---
chart/jenkins-operator/values.yaml | 5 +++--
.../en/docs/Getting Started/latest/schema.md | 7 ++++++-
.../content/en/docs/Installation/_index.md | 20 +++++++++++++++----
3 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/chart/jenkins-operator/values.yaml b/chart/jenkins-operator/values.yaml
index 1c92fb900..60c992cd2 100644
--- a/chart/jenkins-operator/values.yaml
+++ b/chart/jenkins-operator/values.yaml
@@ -120,8 +120,9 @@ jenkins:
claimName: jenkins-backup
# volumeMounts are mounts for Jenkins pod
- # Note that attempting to overwrite default mount settings for Jenkins home directory will result in Operator error
- # See https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-jenkins-home-volume
+ # Note that attempting to overwrite default mount settings for restricted,
+ # non-configurable volumeMounts will result in Operator error
+ # See https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts for details
volumeMounts: []
# defines authorization strategy of the operator for the Jenkins API
diff --git a/website/content/en/docs/Getting Started/latest/schema.md b/website/content/en/docs/Getting Started/latest/schema.md
index 2a1444c7d..58638cbd2 100644
--- a/website/content/en/docs/Getting Started/latest/schema.md
+++ b/website/content/en/docs/Getting Started/latest/schema.md
@@ -661,7 +661,12 @@ Values defined by an Env with a duplicate key will take precedence.
(Optional)
-Pod volumes to mount into the container’s filesystem.
+
+Pod volumes to mount into the container’s filesystem. More info:
+
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+
+
diff --git a/website/content/en/docs/Installation/_index.md b/website/content/en/docs/Installation/_index.md
index fcd6ba282..17b8df645 100644
--- a/website/content/en/docs/Installation/_index.md
+++ b/website/content/en/docs/Installation/_index.md
@@ -883,7 +883,19 @@ If you wish to use the newest, not yet released version of the Operator, you can
You can find nightly built images by heading to [virtuslab/jenkins-operator](https://hub.docker.com/r/virtuslab/jenkins-operator) Docker Hub repository and looking for images with tag in the form of "{git-hash}", {git-hash} being the hash of master branch commit that you want to use snapshot of.
-## Note on Jenkins home Volume
-Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users. One of the key points of this design is maintaining an immutable state of Jenkins.
-
-One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume as Jenkins home directory. It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory, as attempting to do so will result in Operator error.
\ No newline at end of file
+## Note on restricted Jenkins controller pod volumeMounts
+Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users.
+One of the key points of this design is maintaining an immutable state of Jenkins.
+
+One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume
+(jenkins-home) as Jenkins home directory.
+It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory,
+as attempting to do so will result in Operator error.
+
+jenkins-home is not the only Jenkins controller pod volumeMount that is non-configurable and managed by Operator,
+below is the full list of those volumeMounts:
+
+* jenkins-home
+* scripts
+* init-configuration
+* operator-credentials
\ No newline at end of file
From b82fc7c7640a28a6b4912b533b9534d7e81288bb Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 6 Aug 2021 10:03:57 +0200
Subject: [PATCH 16/26] Auto-updated docs (#616)
Co-authored-by: Sig00rd
---
docs/docs/getting-started/latest/index.xml | 7 ++++-
.../getting-started/latest/schema/index.html | 9 ++++--
docs/docs/index.xml | 7 ++++-
docs/docs/installation/index.html | 22 +++++++++++---
website/package-lock.json | 30 +++++++++----------
5 files changed, 52 insertions(+), 23 deletions(-)
diff --git a/docs/docs/getting-started/latest/index.xml b/docs/docs/getting-started/latest/index.xml
index d6501db16..0b4fccb10 100644
--- a/docs/docs/getting-started/latest/index.xml
+++ b/docs/docs/getting-started/latest/index.xml
@@ -1679,7 +1679,12 @@ Values defined by an Env with a duplicate key will take precedence.</p>
</td>
<td>
<em>(Optional)</em>
-<p>Pod volumes to mount into the container’s filesystem.</p>
+<p>
+Pod volumes to mount into the container’s filesystem. More info:
+<a href="https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts">
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+</a>
+</p>
</td>
</tr>
<tr>
diff --git a/docs/docs/getting-started/latest/schema/index.html b/docs/docs/getting-started/latest/schema/index.html
index 59ee07c21..f31e941da 100644
--- a/docs/docs/getting-started/latest/schema/index.html
+++ b/docs/docs/getting-started/latest/schema/index.html
@@ -32,7 +32,7 @@
">
-
+
@@ -1471,7 +1471,12 @@
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+
+
diff --git a/docs/docs/index.xml b/docs/docs/index.xml
index 77dc07336..5f1c71ccd 100644
--- a/docs/docs/index.xml
+++ b/docs/docs/index.xml
@@ -6194,7 +6194,12 @@ Values defined by an Env with a duplicate key will take precedence.</p>
</td>
<td>
<em>(Optional)</em>
-<p>Pod volumes to mount into the container’s filesystem.</p>
+<p>
+Pod volumes to mount into the container’s filesystem. More info:
+<a href="https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts">
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+</a>
+</p>
</td>
</tr>
<tr>
diff --git a/docs/docs/installation/index.html b/docs/docs/installation/index.html
index 4aa60183a..728a3edb5 100644
--- a/docs/docs/installation/index.html
+++ b/docs/docs/installation/index.html
@@ -767,7 +767,7 @@
Configuring operator deployment
Note on Operator’s nightly built images
-Note on Jenkins home Volume
+Note on restricted Jenkins controller pod volumeMounts
@@ -1660,11 +1660,25 @@ Note on Operator’s nightl
You can find nightly built images by heading to virtuslab/jenkins-operator Docker Hub repository and looking for images with tag in the form of “{git-hash}”, {git-hash} being the hash of master branch commit that you want to use snapshot of.
-Note on Jenkins home Volume
+Note on restricted Jenkins controller pod volumeMounts
-Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users. One of the key points of this design is maintaining an immutable state of Jenkins.
+Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users.
+One of the key points of this design is maintaining an immutable state of Jenkins.
-One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume as Jenkins home directory. It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory, as attempting to do so will result in Operator error.
+One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume
+(jenkins-home) as Jenkins home directory.
+It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory,
+as attempting to do so will result in Operator error.
+
+jenkins-home is not the only Jenkins controller pod volumeMount that is non-configurable and managed by Operator,
+below is the full list of those volumeMounts:
+
+
+- jenkins-home
+- scripts
+- init-configuration
+- operator-credentials
+
diff --git a/website/package-lock.json b/website/package-lock.json
index fabb2bfa4..196e451f1 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -288,16 +288,16 @@
}
},
"browserslist": {
- "version": "4.16.6",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
- "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
+ "version": "4.16.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.7.tgz",
+ "integrity": "sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA==",
"dev": true,
"requires": {
- "caniuse-lite": "^1.0.30001219",
+ "caniuse-lite": "^1.0.30001248",
"colorette": "^1.2.2",
- "electron-to-chromium": "^1.3.723",
+ "electron-to-chromium": "^1.3.793",
"escalade": "^3.1.1",
- "node-releases": "^1.1.71"
+ "node-releases": "^1.1.73"
}
},
"cache-base": {
@@ -330,9 +330,9 @@
"dev": true
},
"caniuse-lite": {
- "version": "1.0.30001248",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001248.tgz",
- "integrity": "sha512-NwlQbJkxUFJ8nMErnGtT0QTM2TJ33xgz4KXJSMIrjXIbDVdaYueGyjOrLKRtJC+rTiWfi6j5cnZN1NBiSBJGNw==",
+ "version": "1.0.30001249",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001249.tgz",
+ "integrity": "sha512-vcX4U8lwVXPdqzPWi6cAJ3FnQaqXbBqy/GZseKNQzRj37J7qZdGcBtxq/QLFNLLlfsoXLUdHw8Iwenri86Tagw==",
"dev": true
},
"chalk": {
@@ -568,9 +568,9 @@
}
},
"electron-to-chromium": {
- "version": "1.3.792",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.792.tgz",
- "integrity": "sha512-RM2O2xrNarM7Cs+XF/OE2qX/aBROyOZqqgP+8FXMXSuWuUqCfUUzg7NytQrzZU3aSqk1Qq6zqnVkJsbfMkIatg==",
+ "version": "1.3.796",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.796.tgz",
+ "integrity": "sha512-agwJFgM0FUC1UPPbQ4aII3HamaaJ09fqWGAWYHmzxDWqdmTleCHyyA0kt3fJlTd5M440IaeuBfzXzXzCotnZcQ==",
"dev": true
},
"end-of-stream": {
@@ -1338,9 +1338,9 @@
"dev": true
},
"nan": {
- "version": "2.14.2",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
- "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
+ "version": "2.15.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
+ "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==",
"dev": true,
"optional": true
},
From b400a420e55209fcb9ee14f7cc85121737cd10d3 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 6 Aug 2021 13:06:12 +0200
Subject: [PATCH 17/26] Auto-updated docs (#617)
Co-authored-by: Sig00rd
---
website/package-lock.json | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/website/package-lock.json b/website/package-lock.json
index 196e451f1..334ea961a 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -568,9 +568,9 @@
}
},
"electron-to-chromium": {
- "version": "1.3.796",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.796.tgz",
- "integrity": "sha512-agwJFgM0FUC1UPPbQ4aII3HamaaJ09fqWGAWYHmzxDWqdmTleCHyyA0kt3fJlTd5M440IaeuBfzXzXzCotnZcQ==",
+ "version": "1.3.798",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.798.tgz",
+ "integrity": "sha512-fwsr6oXAORoV9a6Ak2vMCdXfmHIpAGgpOGesulS1cbGgJmrMl3H+GicUyRG3t+z9uHTMrIuMTleFDW+EUFYT3g==",
"dev": true
},
"end-of-stream": {
@@ -925,9 +925,9 @@
}
},
"graceful-fs": {
- "version": "4.2.6",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
- "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
+ "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
"dev": true
},
"has-flag": {
From 1d2651d43fb1616aa49611554fd678c4888b9bd5 Mon Sep 17 00:00:00 2001
From: sharmapulkit04
Date: Fri, 6 Aug 2021 19:01:27 +0530
Subject: [PATCH 18/26] Updated Validation logic - Defined a security manager
struct to cache all the plugin data - Added flag to make validating security
warnings optional while deploying the operator
---
api/v1alpha2/jenkins_webhook.go | 197 ++++++++++--------
.../samples/jenkins.io_v1alpha2_jenkins.yaml | 74 +------
main.go | 14 +-
webhook/all_in_one_v1alpha2.yaml | 11 +-
webhook/operator.yaml | 1 +
5 files changed, 129 insertions(+), 168 deletions(-)
diff --git a/api/v1alpha2/jenkins_webhook.go b/api/v1alpha2/jenkins_webhook.go
index 97af23c99..56750fc28 100644
--- a/api/v1alpha2/jenkins_webhook.go
+++ b/api/v1alpha2/jenkins_webhook.go
@@ -36,14 +36,9 @@ import (
)
var (
- jenkinslog = logf.Log.WithName("jenkins-resource") // log is for logging in this package.
- isRetrieved bool = false // For checking whether the data file is downloaded and extracted or not
-)
-
-const (
- hosturl string = "https://ci.jenkins.io/job/Infra/job/plugin-site-api/job/generate-data/lastSuccessfulBuild/artifact/plugins.json.gzip" // Url for downloading the plugins file
- compressedFile string = "/tmp/plugins.json.gzip" // location where the gzip file will be downloaded
- pluginDataFile string = "/tmp/plugins.json" // location where the file will be extracted
+ jenkinslog = logf.Log.WithName("jenkins-resource") // log is for logging in this package.
+ PluginsDataManager PluginDataManager = *NewPluginsDataManager()
+ _ webhook.Validator = &Jenkins{}
)
func (in *Jenkins) SetupWebhookWithManager(mgr ctrl.Manager) error {
@@ -57,8 +52,6 @@ func (in *Jenkins) SetupWebhookWithManager(mgr ctrl.Manager) error {
// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation.
// +kubebuilder:webhook:path=/validate-jenkins-io-jenkins-io-v1alpha2-jenkins,mutating=false,failurePolicy=fail,sideEffects=None,groups=jenkins.io.jenkins.io,resources=jenkins,verbs=create;update,versions=v1alpha2,name=vjenkins.kb.io,admissionReviewVersions={v1,v1beta1}
-var _ webhook.Validator = &Jenkins{}
-
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
func (in *Jenkins) ValidateCreate() error {
if in.Spec.ValidateSecurityWarnings {
@@ -83,6 +76,15 @@ func (in *Jenkins) ValidateDelete() error {
return nil
}
+type PluginDataManager struct {
+ pluginDataCache PluginsInfo
+ hosturl string
+ compressedFilePath string
+ pluginDataFile string
+ iscached bool
+ maxattempts int
+}
+
type PluginsInfo struct {
Plugins []PluginInfo `json:"plugins"`
}
@@ -112,36 +114,27 @@ type PluginData struct {
// Validates security warnings for both updating and creating a Jenkins CR
func Validate(r Jenkins) error {
-
pluginset := make(map[string]PluginData)
- var warningmsg string
+ var faultybaseplugins string
+ var faultyuserplugins string
basePlugins := plugins.BasePlugins()
- temp, err := NewPluginsInfo()
- AllPluginData := *temp
- if err != nil {
- return err
- }
for _, plugin := range basePlugins {
// Only Update the map if the plugin is not present or a lower version is being used
if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
- jenkinslog.Info("Validate", plugin.Name, plugin.Version)
pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "base"}
}
}
for _, plugin := range r.Spec.Master.Plugins {
if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
- jenkinslog.Info("Validate", plugin.Name, plugin.Version)
pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "user-defined"}
}
}
- jenkinslog.Info("Checking through all the warnings")
- for _, plugin := range AllPluginData.Plugins {
-
+ for _, plugin := range PluginsDataManager.pluginDataCache.Plugins {
if pluginData, ispresent := pluginset[plugin.Name]; ispresent {
- jenkinslog.Info("Checking for plugin", "name", plugin.Name)
+ var hasvulnerabilities bool
for _, warning := range plugin.SecurityWarnings {
for _, version := range warning.Versions {
firstVersion := version.FirstVersion
@@ -154,113 +147,121 @@ func Validate(r Jenkins) error {
}
if CompareVersions(firstVersion, lastVersion, pluginData.Version) {
- jenkinslog.Info("security Vulnerabilities detected", "message", warning.Message, "Check security Advisory", warning.URL)
- warningmsg += "Security Vulnerabilities detected in " + pluginData.Kind + " plugin " + plugin.Name + "\n"
-
+ jenkinslog.Info("Security Vulnerability detected in "+pluginData.Kind+" "+plugin.Name+":"+pluginData.Version, "Warning message", warning.Message, "For more details,check security advisory", warning.URL)
+ hasvulnerabilities = true
}
-
}
}
+ if hasvulnerabilities {
+ if pluginData.Kind == "base" {
+ faultybaseplugins += plugin.Name + ":" + pluginData.Version + "\n"
+ } else {
+ faultyuserplugins += plugin.Name + ":" + pluginData.Version + "\n"
+ }
+ }
}
-
}
-
- if len(warningmsg) > 0 {
- return errors.New(warningmsg)
+ if len(faultybaseplugins) > 0 || len(faultyuserplugins) > 0 {
+ var errormsg string
+ if len(faultybaseplugins) > 0 {
+ errormsg += "Security vulnerabilities detected in the following base plugins: \n" + faultybaseplugins
+ }
+ if len(faultyuserplugins) > 0 {
+ errormsg += "Security vulnerabilities detected in the following user-defined plugins: \n" + faultyuserplugins
+ }
+ return errors.New(errormsg)
}
return nil
-
}
-// Returns an object containing information of all the plugins present in the security center
-func NewPluginsInfo() (*PluginsInfo, error) {
- var AllPluginData PluginsInfo
- for i := 0; i < 28; i++ {
- if isRetrieved {
- break
- }
- time.Sleep(1 * time.Second)
- }
- if !isRetrieved {
- jenkinslog.Info("Plugins Data file hasn't been downloaded and extracted")
- return &AllPluginData, errors.New("plugins data file not found")
+func NewPluginsDataManager() *PluginDataManager {
+ return &PluginDataManager{
+ hosturl: "https://ci.jenkins.io/job/Infra/job/plugin-site-api/job/generate-data/lastSuccessfulBuild/artifact/plugins.json.gzip",
+ compressedFilePath: "/tmp/plugins.json.gzip",
+ pluginDataFile: "/tmp/plugins.json",
+ iscached: false,
+ maxattempts: 5,
}
+}
- jsonFile, err := os.Open(pluginDataFile)
- if err != nil {
- jenkinslog.Info("Failed to open the Plugins Data File")
- return &AllPluginData, err
- }
- defer jsonFile.Close()
+// Downloads extracts and caches the JSON data in every 12 hours
+func (in *PluginDataManager) CachePluginData(ch chan bool) {
+ for {
+ jenkinslog.Info("Initializing/Updating the plugin data cache")
+ var isdownloaded, isextracted, iscached bool
+ var err error
+ for i := 0; i < in.maxattempts; i++ {
+ err = in.Download()
+ if err == nil {
+ isdownloaded = true
+ break
+ }
+ }
- byteValue, err := ioutil.ReadAll(jsonFile)
- if err != nil {
- jenkinslog.Info("Failed to convert the JSON file into a byte array")
- return &AllPluginData, err
- }
- err = json.Unmarshal(byteValue, &AllPluginData)
- if err != nil {
- jenkinslog.Info("Failed to decode the Plugin JSON data file")
- return &AllPluginData, err
- }
+ if isdownloaded {
+ for i := 0; i < in.maxattempts; i++ {
+ err = in.Extract()
+ if err == nil {
+ isextracted = true
+ break
+ }
+ }
+ } else {
+ jenkinslog.Info("Cache Plugin Data", "failed to download file", err)
+ }
- return &AllPluginData, nil
-}
+ if isextracted {
+ for i := 0; i < in.maxattempts; i++ {
+ err = in.Cache()
+ if err == nil {
+ iscached = true
+ break
+ }
+ }
-// Downloads and extracts the JSON file in every 12 hours
-func RetrieveDataFile() {
- for {
- jenkinslog.Info("Retreiving file", "Host Url", hosturl)
- err := Download()
- if err != nil {
- jenkinslog.Info("Retrieving File", "Error while downloading", err)
- continue
+ if !iscached {
+ jenkinslog.Info("Cache Plugin Data", "failed to read plugin data file", err)
+ }
+ } else {
+ jenkinslog.Info("Cache Plugin Data", "failed to extract file", err)
}
- jenkinslog.Info("Retrieve File", "Successfully downloaded", compressedFile)
- err = Extract()
- if err != nil {
- jenkinslog.Info("Retreive File", "Error while extracting", err)
- continue
+ if !in.iscached {
+ ch <- iscached
}
- jenkinslog.Info("Retreive File", "Successfully extracted", pluginDataFile)
- isRetrieved = true
+ in.iscached = in.iscached || iscached
time.Sleep(12 * time.Hour)
-
}
}
-func Download() error {
-
- out, err := os.Create(compressedFile)
+func (in *PluginDataManager) Download() error {
+ out, err := os.Create(in.compressedFilePath)
if err != nil {
return err
}
defer out.Close()
client := http.Client{
- Timeout: 2000 * time.Second,
+ Timeout: 1000 * time.Second,
}
- resp, err := client.Get(hosturl)
+ resp, err := client.Get(in.hosturl)
if err != nil {
return err
}
defer resp.Body.Close()
- jenkinslog.Info("Successfully Downloaded")
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
-
}
-func Extract() error {
- reader, err := os.Open(compressedFile)
+func (in *PluginDataManager) Extract() error {
+ reader, err := os.Open(in.compressedFilePath)
if err != nil {
return err
@@ -272,7 +273,7 @@ func Extract() error {
}
defer archive.Close()
- writer, err := os.Create(pluginDataFile)
+ writer, err := os.Create(in.pluginDataFile)
if err != nil {
return err
}
@@ -280,10 +281,28 @@ func Extract() error {
_, err = io.Copy(writer, archive)
return err
+}
+// Loads the JSON data into memory and stores it
+func (in *PluginDataManager) Cache() error {
+ jsonFile, err := os.Open(in.pluginDataFile)
+ if err != nil {
+ return err
+ }
+ defer jsonFile.Close()
+
+ byteValue, err := ioutil.ReadAll(jsonFile)
+ if err != nil {
+ return err
+ }
+ err = json.Unmarshal(byteValue, &in.pluginDataCache)
+ if err != nil {
+ return err
+ }
+ return nil
}
-// returns a semantic version that can be used for comparision
+// returns a semantic version that can be used for comparison
func MakeSemanticVersion(version string) string {
version = "v" + version
return semver.Canonical(version)
diff --git a/config/samples/jenkins.io_v1alpha2_jenkins.yaml b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
index be33732a9..49f39c931 100644
--- a/config/samples/jenkins.io_v1alpha2_jenkins.yaml
+++ b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
@@ -1,8 +1,9 @@
+
apiVersion: jenkins.io/v1alpha2
kind: Jenkins
metadata:
- name: example-8
- namespace: default
+ name: example
+ namespace: default
spec:
configurationAsCode:
configurations: []
@@ -14,7 +15,6 @@ spec:
name: ""
jenkinsAPISettings:
authorizationStrategy: createUser
- ValidateSecurityWarnings: true
master:
disableCSRFProtection: false
containers:
@@ -48,75 +48,9 @@ spec:
requests:
cpu: "1"
memory: 500Mi
- plugins:
- - name: mailer
- version: "1.19"
- - name: script-security
- version: "1.18"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: credentials
- version: "2.1"
- - name: ssh-credentials
- version: "1.1"
- - name: junit
- version: "1.2"
- - name: matrix-project
- version: "1.1"
- - name: git-client
- version: "2.8.4"
- - name: pipeline-model-definition
- version: "1.3.0"
- - name: favorite
- version: "2"
- - name: workflow-cps
- version: "2"
-
seedJobs:
- id: jenkins-operator
targets: "cicd/jobs/*.jenkins"
description: "Jenkins Operator repository"
repositoryBranch: master
- repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
+ repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
\ No newline at end of file
diff --git a/main.go b/main.go
index 3cd399f6a..936862f1c 100644
--- a/main.go
+++ b/main.go
@@ -78,6 +78,7 @@ func main() {
var metricsAddr string
var enableLeaderElection bool
var probeAddr string
+ var ValidateSecurityWarnings bool
isRunningInCluster, err := resources.IsRunningInCluster()
if err != nil {
@@ -88,6 +89,7 @@ func main() {
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "leader-elect", isRunningInCluster, "Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
+ flag.BoolVar(&ValidateSecurityWarnings, "validate-security-warnings", false, "Enable validation for potential security warnings in jenkins custom resource plugins")
hostname := flag.String("jenkins-api-hostname", "", "Hostname or IP of Jenkins API. It can be service name, node IP or localhost.")
port := flag.Int("jenkins-api-port", 0, "The port on which Jenkins API is running. Note: If you want to use nodePort don't set this setting and --jenkins-api-use-nodeport must be true.")
useNodePort := flag.Bool("jenkins-api-use-nodeport", false, "Connect to Jenkins API using the service nodePort instead of service port. If you want to set this as true - don't set --jenkins-api-port.")
@@ -95,9 +97,6 @@ func main() {
opts := zap.Options{
Development: true,
}
-
- go v1alpha2.RetrieveDataFile()
-
opts.BindFlags(flag.CommandLine)
flag.Parse()
@@ -112,6 +111,15 @@ func main() {
}
logger.Info(fmt.Sprintf("Watch namespace: %v", namespace))
+ if ValidateSecurityWarnings {
+ ispluginsdatainitialized := make(chan bool)
+ go v1alpha2.PluginsDataManager.CachePluginData(ispluginsdatainitialized)
+
+ if !<-ispluginsdatainitialized {
+ fatal(errors.New("Unable to get the plugins data"), *debug)
+ }
+ }
+
// get a config to talk to the API server
cfg, err := config.GetConfig()
if err != nil {
diff --git a/webhook/all_in_one_v1alpha2.yaml b/webhook/all_in_one_v1alpha2.yaml
index 0d878dd2d..18afb8010 100644
--- a/webhook/all_in_one_v1alpha2.yaml
+++ b/webhook/all_in_one_v1alpha2.yaml
@@ -247,7 +247,7 @@ spec:
- /manager
args:
- --leader-elect
- image: jenkins-operator:52fe5fe9-dirty
+ image: jenkins-operator:37d0eac4-dirty
name: jenkins-operator
imagePullPolicy: IfNotPresent
securityContext:
@@ -266,11 +266,11 @@ spec:
periodSeconds: 10
resources:
limits:
- cpu: 100m
- memory: 30Mi
+ cpu: 200m
+ memory: 200Mi
requests:
cpu: 100m
- memory: 20Mi
+ memory: 80Mi
env:
- name: WATCH_NAMESPACE
valueFrom:
@@ -278,8 +278,7 @@ spec:
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
- name: cert
- readOnly: false
+ name: cert
volumes:
- name: cert
secret:
diff --git a/webhook/operator.yaml b/webhook/operator.yaml
index c056ba8e0..01093af2d 100644
--- a/webhook/operator.yaml
+++ b/webhook/operator.yaml
@@ -23,6 +23,7 @@ spec:
- /manager
args:
- --leader-elect
+ - --validate-security-warnings
image: {DOCKER_REGISTRY}:{GITCOMMIT}
name: jenkins-operator
imagePullPolicy: IfNotPresent
From 853f4857466922de550f934d459951b4a1e02341 Mon Sep 17 00:00:00 2001
From: Morten Birkelund
Date: Mon, 9 Aug 2021 14:57:00 +0200
Subject: [PATCH 19/26] Helm Chart: Remove empty priorityClassName from Jenkins
template (#618)
Also bump Helm Chart version to v0.5.2
---
chart/index.yaml | 10 ++++++++++
chart/jenkins-operator/Chart.yaml | 2 +-
.../jenkins-operator/jenkins-operator-0.5.2.tgz | Bin 0 -> 34161 bytes
chart/jenkins-operator/templates/jenkins.yaml | 2 --
4 files changed, 11 insertions(+), 3 deletions(-)
create mode 100644 chart/jenkins-operator/jenkins-operator-0.5.2.tgz
diff --git a/chart/index.yaml b/chart/index.yaml
index b7e1f5541..0044cbebe 100644
--- a/chart/index.yaml
+++ b/chart/index.yaml
@@ -1,6 +1,16 @@
apiVersion: v1
entries:
jenkins-operator:
+ - apiVersion: v2
+ appVersion: 0.6.0
+ created: "2021-06-11T13:50:32.677639006+02:00"
+ description: Kubernetes native operator which fully manages Jenkins on Kubernetes
+ digest: 48fbf15c3ffff7003623edcde0bec39dc37d0a62303f08066960d5fac799af90
+ icon: https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/assets/jenkins-operator-icon.png
+ name: jenkins-operator
+ urls:
+ - https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/chart/jenkins-operator/jenkins-operator-0.5.2.tgz
+ version: 0.5.2
- apiVersion: v2
appVersion: 0.6.0
created: "2021-06-11T13:50:32.677639006+02:00"
diff --git a/chart/jenkins-operator/Chart.yaml b/chart/jenkins-operator/Chart.yaml
index 9d8c137d7..d90d312a6 100644
--- a/chart/jenkins-operator/Chart.yaml
+++ b/chart/jenkins-operator/Chart.yaml
@@ -2,5 +2,5 @@ apiVersion: v2
appVersion: "0.6.0"
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
name: jenkins-operator
-version: 0.5.1
+version: 0.5.2
icon: https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/assets/jenkins-operator-icon.png
diff --git a/chart/jenkins-operator/jenkins-operator-0.5.2.tgz b/chart/jenkins-operator/jenkins-operator-0.5.2.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..c2f1afe9e0063a9c2e03b84b419cade3074dd85f
GIT binary patch
literal 34161
zcmV)IK)k;niwFP!000001MEHfZyPt#`B{Gj&ne*K;9W^}Z1;r2eQ@lgb(1)Todzfl
zhaRP+B-Z=7eaKP1$KQT4!^b|fyIQ4odv{+5)LHG4!{KmdI5QlwzliWohN%<9BH>w-
z44*uF89_NcJ;r~>r^lo6zotAHzZj2>jz)*ahvO%s@$u+n{Dd7p0xlaRPcxn{_GBuP
zJK^V{*HUlW_kYv!OMU*&mpsYbH4pp;>jNkFYyPuS?e
zFz6`%&*z`V@}o#n8HE$JIvnsgwm~vO3WGGZ`@Ul!=f}ec`bg5A`zxc%Dq@FXhWGsu=ocpO@a?aLK
z&X#;tbOj*KZy5Iz!M!!(p*IAuSnHmL)YKEPAK{lm8%3eN2Iv~43CogP45+(82M*kOoj^wIW!aAa5Zwr?x$fO7mE1KBA1?UbZ=uPi_G)k
zkj;SxL6it)t23$&D3x`71J;U4sH2e}iAbY7(KCgVh$ByZyqCVuro!s+KjYiKuxFKz
zpmiBfS(?x1^3!twQqlcIS82>=!pukU;(jR-#W@C#)Ph!%Ea7ywOGCzNtE1FH0{fF}c3gUd8!&yaO9zIbj}
zy-^-7)Trz%8Lpl9Sy~XgfzWS1+_Gl?9&87wy7$}&7BnJUHX$Cmho`6R3kRw@z2ddkp~Gmgd(5>p0olqe+$ZEEyFVcrx<07a3+ABH;`2ssuZiKx~H
zQXg(16rd*L9C?=12T)-SS}-Ra%QN+Ljg(0kpGJ8xcPQ=QO!{gi0qnCpeH2Pm5FBod
ztn#@S)|970v6oVvv3@4KMp_&-Un2gIOSC4YYZ6%NdC)+XQSN);erEKH1)>xOwL;2J
z?Vo^YPtsuX@P3GHuPjHs$^8QmUopFTR80w~|?snShbCoG=yJ+5G-v;!k!q
zFI=T)>`*P&-DuB)`7)5%5akr;OT^P?Z_HnRYfc5qKnVqLPOG~1avW>ysx`0>Hd_TJ
zgDIr+Gh?$j2St568U^}AAV5~Zjy?KL4iu3H`&xrqWoZ9Ss===!KL>Y58B3s<$|HWc
zHV)7MyBDO)(CgOr-;~ep@)#;=5UNL`2Gmyoa{cjK*U-+M`ck-gpo|i7^036HBT@|g
zeWW&E>B_*21xABEuPV_+jYerO@1i`+l`JGU96&j!5n3YMBnW|TV0`J=N(P#3MMpCXoA4N?65K*lEm01U#c6l^42;4
zj3?m$Dg}CuArrD&5`m?ZIOt#~{7U30_^*t5Atc7R;(4|N-TK+siGYh(tc|;AJqrX`
z_CL?AFVTxFH@?+vCrWRNA8|d@+Gv)On}b2%Pf8NiwAH>S#z^w;EXCHq=%dky-p$kR
zk|>Y$8-j}TwfI2om7G1!`kKO`6Y$~F{(jHhV#s4@y=EJ!ac>oxwHbP~IFrdPDobN@p4e0_`FlLzARtzthQfQ&r*
zcC6l}`3%&0T1JQ7XEG4ri`nYOdRgM0>@n`7Qm<{`M~^%1qlXyx*!X(1bVy`o6~@4^
z8}*86+A!FDYAS0lx3+B6z9L8y!bW!yY&WL}K@U^_wA3w`vfz#C@K0r7*Y?d6K;f!3
zc@)!5=+%v^NmS~vQVy-%Te0JTm@yg0kKih_V4>bBUMltmERBaI+?3wS3^xuj;8dTj
z+I%6IHz$kgZ3Oy@2&l1Lwn0~R3(Pvjy-am9P!t>h@lhsOp1$Q%#p)`kxuTaopKfk1
zYRbf`*@U9^BZHYW?^GPoGHMayL_3KpSE?Gz$&L^fx?}~$yIFvj(LJoTU?G8Zd?&21
zgvhlhMp{NyD-ui%39G-P+Ajsng}9D9kYPd01D086XOPU5GVm$Yr;Pzmw;-4u5UbOq
z;G9Q6fMVA~jG6jI^((cFs&d$H83kg9Uh{A&!=b9>rc2X_=FH7r^oL3x)yl1%=xVkX
z5Rh4v8gH?D(+{lXuc!S=sj3zTLsJ|D=av
zVo_`fJnO4fDHTNvql#aioxl0<`sa(w8{kY_8}bIQ;uaZI7@2UqXj$0dZgw0=cXfQwgW>3QS{+GJI8M?_Lp
z-to8^e3HwZ5f5SlScjB5i}H->02wdBCOn~(zpR{D&eBOhBQVu!tP8;_wjgC1rd+IlDM
z=mEE(FXvZLb`7f&4z3FJL3T7dHVlC_?^hy8V9qG`g%65sJdTZ(TCP=WI%6(iNBd&F
z448TY1FBe-m5hWSg12Bw&XCyZRTlXoDQycf#^)4nUsHwOJJ0H0wQS`7xl7>(auI@E
z^-z6m%l|z-JlV+q8-LCJ`%MZMkQm=iK+l1)Q1hOSa)@C)NA=+jO#CB{F$@F`
zz$-pm_|X)6J@77|_Cb;HLKb219$hO?C%Em4S{xUlx%@=_B-H!EbCzFP4iT{xLt(RX8jF
zl?~p(AKmmmhQCvO2Y<5wp8pT3egqpD7EE?|@d`SGB@8pO1}>;5K2-JK)xce)xSKru
zH_|p6@;^(w^nnk7>~Q`=%m2w}eDwAF$8S-Z=il0|iT41R;GO#aTqm<5eqj?D1|~Zd4eoL>s*Pak
z&BcWXUGzbrA^xx93kr?hAK3sO1Qo%mJu6NMk|4u7%pXD}B*vxvD>fYq3?0VVpF3
zQ-1qarYeLG`{3C5MMg6DA+TWOK2OSTL9@qz)Rjs8#Wk2DlS=F{1rzXszHcm}}RS4ublOipHtz>*x-q*U^N4#_{ym3=X
z`SGw;tHCG_Nn#)}Rz3;0LEoZa4s6JxDK3>R!(BT712zMu*&$27PnE8{2<2xBo9qzm
zR5|N4m=w6iTosD6kWm39#u~t2FDwsB@bpO*_RgdaR&qiNYh%kuS8E_
zXYLj%R73~9Qc@pg%!*oMp$4c;c(IiC(z+N&ZMRqqs^K^2-6$1p^WvN|z^u;FqwiSO
z=W81=u<*(TOD9p(UQCgpVgitOS`qpHjT)q-eX>fFc(W8y`4p`G8BbbjZW{m=@oAHt
zT8HrpDiZ@1JI;D2s4)2*cuDP$`e36*SK09Dg;;4vO>Kj#pXj(DYBgn13aQ`{Za;2O7RC#~vG!ubKr<}^0
zfn9}m$$}UhR~+ZQcYtRiq&|w2hkDeg$kA6mU@0D#;3nmAD|qE$V>CR;XDVm^+5Z3R
zA25;4oYpT^-2-NUI|_rlYNpF-8~)b#_O5!U(C%FdodIKTQ0mRhVZAoD1A1>&rj`
zwsb52^~{L4LB*Ew{1+zQ43~oY*-}M?F(dA?NTNOj&O_a@i^HidOy3p;$I`kUv{mIv
z!q*)&Ti1&ns#JIR`{=dvdI~{>r&UlJRBQ}PBXI|K9<}Kzv%ct1`lcyY9YqJ_Y+^y5
z0bH8gg-qZU!M4l=b1to2)PZM@Mr}-jdY)$!MDgTB=lF0C3(-uhuAGKGV}93>WueGm
zw=?j}AJpD9XFB`Btn7i!{i-Hov<-F|MZVxob*@
z(=IA2cx@!^L*Q-X?Lpk_r0pc^7P4;BIaL;Ksif$%tB$Dd#c$IN-<4}`_qQrKpb>4<
z3kn6Mx@j8SR}H|vYJjgA;E^_?%Md^yo2W9MioM6oG3}6`GDfaDT0(=tcLTA93%;o44Ht
zV+Ey)qLq!Ak#WxQ#8!LxASyuC4Ke
zosn8K?;&^K)qc_1Lu2;<20vCPZmjCUY@GUImppEIwdJwH}+x7#oe*i*3-!tY5zOfN+3a0B7F=w<`
z@q#P2th`Zow_N{)6*jY-Te?zLak2VIUi#K_l9xW16RjEsooH==ug
zN-vtuxwb(5cBEj|ProX_o2OsteeLvX3+Q83OP6u9fw^(;x0y~YV2@gf*N;psU^|J&
zj&>qbOBapAqqn6baxD5}mu`j!wAvuzX)pa;x=w?B+ml`;Ft8r)RjaoEKEZ1?9%7lb
zf^S#aQp})`PM)d63QXl~gWGTE(|+=Ac!S+d9ja)Y$Kg6CvSX(npBRb6zZG{OFU
z_h#<-yNmK+2g+X2JFezziAxE)WO&<9N;lANo_##K`T6SX-K*zhy^BvVr>hOsq2TIv
z@qSu9lGnZ7U*b)G<_MnAz*BXfr4Rb{K;Ld@0zPVQx)Y=f<2*B&LFPa7P4Y0rEEjHTNwCWu+AD7pXgzm*wy1k=Q1{!O?v>P071&o+J{5Eq
z@53>v9Ev|^tykFroq!v}o4vaFaP!mk`^&2jEt1>`u~W)hCAkx14=Hby`Tu`1a44!?N97Zy2CCpQ{X_&2a&v=dF%c
zwV`#m&t510+sm^s62Z)Yu0um{9~*XzlE
z6sqOn+FX_OrGT3kjEzO12gqK_Mrmp20kZ$%VHb!VPO(Fhs??T~a-ex{
z&+S(2s_ZU0uahX)S$uBQu7%kmYf=(hoTUm5l`MU2blLxb0lueG`+fLl7u|@(-evGc
ztZ&4;U!#p3ay;;j8(g>nL^rJW$U69Scw>Ry`d6;ujB-<7Bl
z-Tm^Cq~*0@Z|wlM&n-WAAHYhA`=L(pc2MIudb?{#C%T4D>7N}s{_y_d{e+!)p1yD&
zIDMY`>VK60TDdq2wLM9?D0r~sfaTKruRiL*lrNgWC{|mmUp$MqbVy)b(T-M9b^yvy
zL*hXn^XjL+?C<~W?|nJGfKl2(t^lHwC@$W^fhwaf
zTxz84sy~yBR9L_9QesS=M;lS#k)~*VV6HY)rp;=+_vp*d+@Sx(q`}69E=peP;>ot|
z$JR!Gq}3;;JWMPy+k1~phA+`x^Bw1XXB}p?KVCnOF0(l`dakSk)fX^bjrPy>-nA`q
zBTEqO&-E+x(7g-TWCG<|PrW_k2LrYl*M$Xa@4U9hEiwhD$&|7sB^2E?|9#_}6A_9~
zN{SOgNtNA--Dww@siU}@IQL6gmyi50x=#ltmTu99rLu4~
zl7$6#^ht_hOHQCj7Y%`&Pm9q57N{%4(xOLJnR=QE$u+ibrN;i5@hWE538?6pm
z*KSA4KB)3QHAJE2G=?tKjZQ>s8sEiv%0^rmVe;^XeT8U@80kf>XFV5ID;TQm(R5jW
z8G-Vm#4YwFtwJkLb5!i*9j@>j?4ZIOvgXf=;J>$i{`lQ!`^&AZpY}%o_RGgxKacSr
zA8miR{Z9Sy@%Fa({<~M-T$~>N5^ulzDOt{M>92QNKSjsCFoA4ufB7emNxmH!!ByfM
zM`<>qBatOkxq#G`b-#IMipLnijfzjM`NDKzZ&t}#?yNkx8%2EgYh6&~4LMfuatHww
zS`iw(23b$NC&PpiKxwHOgS=<~1kH^DG**)#`YxQsQw3AJWiWaSMi0kWi_wE}Y634&
zBp56nUO(s0+Zlc7^=7tH)NOdLb&M*t1WKr;izU=CX{p2AJgV-cu_C>t=cuNW404>QPd8V5hZ_rxj5m*U=p
zxeyEE1r(xJvLZQc!21y9c{+(h69yHTv}
zIJtAcR4%V2MG6p;tbIfO-fqBD>G3g~-pHP{rX4!38946654FM9bv8bd$Hd46^>$`m
zm}Y3hr~~4|8eC33GQnEpf%hT{@Z|vF?o6;gGJrS#_vQV3X9tIrmcyIZ`|^1&E==`t
zy>Hn;QW{ZWO#TsPk7=dQiZX&4=kB6AFrsjBgVaxQu+rCRNcw9HInhPsJCU06ib^xk
znSsvqOlKsDNkxHgZv0S)OwYnLCHe40?ad=2EEw+*H?-4irYcjOcB#ifJMu75hMAC5
zv!oMT3ie!}{ti&p94|R#FYN@cA?j(zYUto1oMwCyf$1g1a28)hlZVO7=g1CZ5jxDH
z#uhc$zZNwjDxaqcycTVxt7r(uBI}c(?XuK0^vp;daV(cluor1woP!eMrT{jgo~j2y
z4Vq9x`FK8$rl7RUglchBFbw*ktxn0-D;OsTTS;A;GR)D+d9i^OJn;I)302%nbOiwT
zYcff*DP;>fK~iB?e6&Piqos^ik|agQHY
zCA1v==4fW+&~kXx5cM#<+0{l{s)_p88QbcP+I2;JjD)-jq@2>GI2rQTH0Qf
z)B|iw{nCc|q#nTADw$R)mHM0-qo%1>&C+r(tCt#c>0)T-iE`E7vn|J!4#MrjA_0&a
zES{_oFH9|#Ar@SLIaOty*G20fOsylK`xcr2Vuc2hcoNV|i?sBd`<%bd{SQt~$H9Mz
z8za_o8D0tspxS?dHE;u7>f?(Sf*I`lw^2BSY6Ec5#XtF&+yOC-_jP3)PTERg
zQW)gph{Rm=5LhzyIiPDVp|9~$uiOdR72Qu7Jk(UM#LKBg6PLA0DE2?0B?8KLxf;8;
zs$uv#X<@8bb>uoIFp%L-s*a9fG#>d+=4hWjf_$3!`+FB*usn9vM|@Z19qLgOGq|
zl|NR;YDB8IIkFgEN+bm@57z5)W)fEC?R9)uVuSqx@3^$?QE44x(rQv5vmjZ{g|b&h
z#%D#j;T}^;SDdY{39$0zD|P^havpH^VK$$C_Sq+&jcLldI!+Rt9K1gG_56oJOn2jB
zLQkP&?e$hxhi%iuhhc3Xddt45AdxU_1?3=>KCdLx!4+BK-S8!9BSfrqNWH~maSpc3
zE^_bY#o;MEY>2*LqSW>{xl3nv+${+M0S%Wq#($yR0~NprfUiP}$$Za(2nr<`eIVpJ
zghpEN1Yws}I(Q4uYX79N_U0R9@UIoS`G}d?fvtwn&5w&3D1U|WONyWAdUXTk_n`bA
z3hndw@gj@Pi?p_hl|3r9cY3VB@-DkyxWi(aOy$!h(gbmwkRK%VL_o{Z-0g%-K~wp1
za--}*Pjp)k-X;`ZC+79dkYcZ$8F)S81I8g
z7Unk*=EFyCAzKE43u2#Bw{+ud`6BpNhf-
zm@){ZHpRhXJz07F@FImMz>PTDkn4Iz}|
z;1K#(bOmiM%gn|0E65Xqn_#SD8z%k}9MZrS$FemZie8BCpGW
z+`IMIkHULdjXf;J$_~uD9ZqYpZ3E^SqS`FQRr@a!X0w&J*7nPU+F&7e+kKhvOY1Pp
z=F2zqm6le
zOV#&K=KAD0bLV;T8QbvgX>|88r~46qzG&}fLg%Zl9_DktbFZ`M-18QDo6Of{E`PkK
z+>6@rP2_SC9-7|c%;Q~5E_3!e3>rNfGkP#&_?WMKOxGSITpwe$_QDn)BE&S;cn}hg
z{>9~}6fn|Qof7~lOZ(M^fFA0~sv^TVm4QYwTda^y^DQ|2tvriKfbI#c+w)x^`r-eS
zk%LCaAkD>X;9Z|cZ+Axa6ztP`aZu18VoMMTd0yLwFkk9Y98{Or1D@aCQ{X-{6^Pq2
zx*SgJQ-bV6{gj}fY?h^hl3MDkf9{uM+4ga6`VN70LWZL217g7ZFpki}k+vQunwJBu
zbdE9LKF)deB$~CuVFpSz6X+wHW&hIhV}DMue+BvR{Yq3tJde_4(X%jhe-lq`JU9)^
zA_u#-EyM0hu&X@U331=MJlAhTqGFz{+aS}}*0=OImVKx~Fh?D|KL7RQ!B@vGT{q(x
z%CH*AYfyI^$S2-3Au)irWSPW&Us46dU`s>Z?xji~cBku5KOLWw9+?z0vMilf2#{;#
z@E{08ArZVAAvFcpLaLE9v8mi(IMv=Lz)wIFcUD<=iGCpgMIbOBt5y~vb-}FDCzQ#2
zC%9ZPd}oU+o`+dHdoU*w&IDyll@Rh!UCz;)<8uet*KaPc*)c@ipc@OH#_ha}0G@2a
zGY$@t2l^68hD-eeAC}lb=y0xhgJjde#@-nJ-v;b%1~R1b13G|K65oIkAd8Bj0kXyb
zx#xXXP}jcvQ`iHuZMZ&V+#QD9J`4cyW**4uSw+2^sCRASl20fxK;AHUh}eII#coed
z)%k+!SRll_(!m8^K&GpmV2=g!FTq>!e;^Wk&f)ofl-*BtAgTA{)O&}2gj)vB!VZDj
z7DLr+YceP}aHOW8%`b?{;>NPz$_DpXZ9Su0!pnz1cBEw;sMlQ;T%kxO
zDXZeRWWF!J8sK}Rr}90xD`cxs#-Q(yPImw#?-q*3&krw7ZPj5zJkIJI>#;XJZG$X+
z>C(aaEoq)b;WX|${7|A>3EZ`}hbv-L7R}Q;2w?%4O2Lbg=^~9m;-TO~x5zStF1C
zbWx8XbWx2Vba4n>tRF+@V%vL$(8anr521_I_Y9$nL+IiVy4XC1(8c;Ogf7-UHH0p5
zzzv~`L+IiVx;TU`ekdx?5V|;oE)JoKFow{@n(iLSPXyoQ
zVLD$x$>cNjutrXBmSeyGGcL-%tLs&Kz05FjZkOtrk0vymkzUG3zkIiS|M`4o7SCf>
zlp~BX*znYghk20eF2vfKR4>8;BAH$U|Go9|$L~hlUv6#vv^V;CQ?$#Q;6f4$rKDLVdz31oZw%RezD_h?dTWAjTqTf?AQ
zVB6}qNJzptG!zh&%L!DXVR@s-NUTcPzdtO8;X&!8Ieb9&-zBo2$hkEg5l@}%`P-!65_&=uH{9=*p-mw@Haf>Mnqc*-7xOsT=jL)
ziVa@4k$9zey?eSSWBjHrH}i*J5Xj=<0iuecw+@BFMz3@EXpk-_R9Ok;wyI_
zG{C`2mZh^?NZ=9N28K#6W{<8Ch>*M%>ksCzg9`;5jvDS#0quP7&3)^yX5qCCgab!!RXr?U-Lyf@cVNVfP%*;UefWUeSbayF
zzXt&3ljR6Fbns
z0(CH*iaB~N?J?m4hw4=iW%f&O`sV!P|N74Y2H>2R7kEuUTVk0Rr*9no(%g_U86`WM
zLCXWZ2hM4p;p?nS0K21?x%iEe4M0()CJ(pm;@xg4S4!MVEU#liYt2s
zDsnE^rre8D^=<}mG800kWj#4BwFG!SM9o96I8XDtAt%yY2zro&0v||;MCvoS>>Vhl
zd%?SJS5a69fstepa*stxcsb*^c)hYD!s#2a)-!=}U+ZXTPc-kgSL;#V_yT>i_<^Izsb_2Z_7}?$Zt-L@UAZDo{GzzJz#RgN@g|(kCZ(5J>X~s
zD?x@`CPI)Ax?=bsB*q-jfdN&68pe_@}*&C+t&p++e(~6k#I!)l3c;d=QGL0u8(Z;Z-&>wUOk%Z6L
zatx%$OCo4lhISHAB52dU6WZrY94RU;m?IgoQaa$-cphF0U8K;c2iXEizQo3-U@8$5
zK8#?>3?fIPWob798$XZO3gO4b(Jn;dmp!`GCAm)j=uULl*96V8tjKrm5@!vhKzi&?B&MElqh
z6mc;VnCnDFCUF5v9FTvIgv7z7^OXsM$QfBRSOgNiVri{BbTpBT0hEc3C9-kQyN&w=QvP7DDBvrzC^VvB@jTwPmQrq~rfOp
zXz#REFuNHRkl~&Q4C`E~AOy=$8WcK_;4`-26g{z2(+purt6GwZ&5|xfnZw3S-@Bk-
zGlZrh`ha&S7vI!;2me-4j`u5FiDhc9
zQ+*UhtLl0Tu&e5VzAl6wzenq%AEUgU=iy-nu)#@mzTlL#fnj07H?PhQY#=~_@3HVB
z>;!zzr0L;w9_Kk)&7w=lvIw?RSj%->+$=B0f=~?9*;EZmK~L1
z?t1i3WfttXel!ot$KmEGLRXp#nd@&cDz2Ig{j?vKaj|MT^5BBoNzw?Ms$wk*VO!@JoE-oHBS59QRY;vP5|
ztigLF{-R$w_f^(e4EZXs5BtL@oiYnAtd?Ccia?fkIxNa;AQqm{c^T3s&I+UxQgFc6
zCBX-qFE)EG-AJ1tb}hVS#%5Obq6$EKTSVC$nd?n@Pv7%Mn>17)BvtfJMW4u=MzzgU
zsg?y5Xaux33HHbP
zd%Yi5r%I@0(POF+3wx@nx2wC@`%G0#hxcq>(FG_&Hc+ug2Qz+jFNnLx$zz247P@D_
zPit_*?M@L*e*Q_waKG$@#z;bem%@+4n1sKX+#GpU;@a20K}U5@s-l8W7#1{-^cosW
zz;A-`M~&+d&;MtX2wZGhvYYwp6A+4E7BwqSc8<|WjSII-$qEyVkxZUaZMy{YPTRL&f;>8R|?%nd8DV%5+4E{
zqcG1YJOz9bcky%yO&`Rh@M4+igu0l{++nu)8sbRahVbx?zO7-7vgQ=3y<|J&v^l~*
z4)JP}-$u^40Wh$Hn>0zYZmG!9xV%d{`Ny(P%?Lk%Ma%aKnR66Eid<8+l0zxBqc^~*
z@&>QxnZg`Jy>h`%)8+LIv!RdJcL=P6dnJQ;sO+bNI+awwER1bqUNe>CY0aMfp*GD1
zQF5Av_tAk<`7Vy`cO{D&fhaekrRKZ1w%tGCe_CfowSNw#Q>hLL42G&ssI=wdAY8;h
z2<#B^-a&WVPOyxpU$&>KvDiuv^ckZh8V|-Vdz~?7`wU-&3v^B56TxltKzRmec9XHh
zve(2iZ*%vg*>#x2|DYQ9fV|gf27hkl6ESNlfECTeCT+{j$|=+l71jor^gx>BM3*5)
z+DZ$ZVHONRmVGY_zv!0gcG^7$%?1k~pkvxP!jo{;`);F0x#ezDo8a?tJ?jZdaBni2|6PM0$k+YlD=
zRjfnxOK2B-F}_YPPa59Qm=Wzf>&0w&9XI<{ZH=FPTe1iFuvL}@(69%-MDLQ`{andh
z@{NyW6w~xRf!adfpS|?p7f0n&x`qNh0$9iFc$$?{7m_nvC#PLxaf+U!nYjOLp2JF0qRLZ9
zy3{Vt!yHP42};sBsg^xt*0HFsV43fJTmzKqF|+`+V`6kaRKZx&xi(?~?#Kd7X7W|L5;3`f@_`go
za}U68;sqVEn41EOloP&I!3-@h#k3&E42sZQ5Kxd6Av00geBfPQpW{Xb&&M+6wYZMk
z!m=*084kLjx02|dT$T_+fW9Hyn5*7{6K;d~pr)}6-9Rvi5`0w@a&ie(KS0fVbGA7}
zlW~yUkHr5MqXno~xk?19Nr3|!+B}^KU9+;|LNIOHQ#~z|Zoxo6Yi*4}<0i=PQe!0Q
zA0obxIg5P_HftW%(#9p2zXj36k{IxVcIIa7nR#H6Hc2Fqg{iG(u`N)gntYnt4m>&x*<3wmWw}|kdBJ4}dXZkjmc4|0dmNk;t}GsG4w$4tbae#^zF2v*fKuw2
zpexqoF!eCZUr19*o5_~s-Fdhm6)Bo8iic^OsQ^-`;K6O!c!LS2ui_l#_cr_kNE-)O
zOJ<|Sf~>#OuG2ORn9HBx5_3tqfN
zztoDG9Nj4`+DLkC-4Sj=bZxqG`(C%ELN_KlyI|HQK|4~MTY=W4Kf9Bgy%ShFq^>$0
z<~;|K@!|wn8O-a-UG9{%?8=gN>}8X`XC{mnYG?IwE?$oF)N#P
zB~R7~wk?mgJww(BdL@IFog3=}t#fDl%8Fedsbb~8G8fLvezh}O9UxtKuU(S1+cRF9
zvRNHKn{!g82(?QZ*loQc
zlwy#R^470#noW@Sg!YuR*U|arGqT8l%JQ`UHnrFOC0`vZ@iF%o$ARh76El{i7G
z`9nS_n!{RP*v%v9_W?AC6E{+wsSa+MDu{R;7{YZ#?i3;I=Va>_d#_uCDOg)oX6r%_
zxX9ZS*QyK6&BA3eX{{B{IHj7+(Dw8&xCJlV3`&-Z{lNZ?EL$T#TZ)%=Qqx%VidZ|m
z=0SF>cFSx07;a`?W83wO%G!Eo#*Hm!MT>Jf6*D8sIaiZk7NAo>0I&F=B4Pucr!72)yO{cJkYEu-Hvm%lys
zyd00n;^z}ipUi#FoPEPg?p&)oTfaUJpQE?7=jrwux_6et$L@
z=TC}s7Ev51FK%-s{{ke-&D@03v^t-V%?lL_3+9{)4I52lMG-=9EG69FH?3wdP#*xT
zWn38g^;Ow?@jjt7{^d4$*ui7op{RrZptQlZt-px~5@z`?U=l*m{)_t8e>^s-l;+_f
zB_C6`L~QtYBe`rDNdZL?V8$-wJBH{8abZIY=))jph@Ue+Km^%0k0ZcRpvCL-
zTt+zW1gDrVQGS9V#_RO>Ep)l=Bi}86V1AFy{4RP>EQ8i99xt8dC8{%xvPC*>-Brjm
zAV)fw$mrb|qvA?K)QG1d*pJ@|RWbknR4K*zWt`AN>BR~K9AHCo-s4e;lYl>QihUe}
znzF}fyiu#v%~wbZe1P=Zh?+lP#FR6cTa)wBct)TJCu#R^&BuRVhBJ1t8nLhP0SN*Q
zP3^mGkXOxn*Z{h%J&7P?Hqrz0$Q53ai>he2po2+a=#A
zX@rZce)XVio)|A2=Veh2IbV52EGzau!PiDK`fF^VqFDwq;SBX
z=aO1$3M^pL-M55BZI0%VbB%U?1Kfp1F4u6YAIHH(yb#)i5q(L1BkNUey+031|AOQcc#1?X
z;UcSkQ^%A)&nRKGAyn;8H+F)Jw^up*Cn>Hl@_Mct28+{;vMf?Ll=OgmvQ?8r|A^w8
z1Ep+32{FOO@6j!P2cn}`PMYcB3dS+8O8S6zS^O^6HE`r5;i4Pl1>~xX9OO;;YgbSqHz)-CBASbvxjqY~yX}G_G)08C^
z+%vV-EQG6#eSyN~sx;D$xd-}pPN<+%s0m^0!`?=)B|d|h0k@q+kW^7ncnJD{oFGwP
z*>25Q(C=2l-6zkPc*X1h#xAN>Ne85}2sR)teFM|AQ{Xd{9Zv-9Ou}}8)=o2lpGLVy
zDg=cuSV20*bTv|LV4V5Jd*Dtme2Tl#n@)~=PviR}{<{!`PmUCST0m}V4*m(K#&fIX
z0FE&k1dFYMdH4@;d5*t2my_CluiMwFgH-KuAMVfaAA*O280I0}9jIrj5*>UV9DxNN
zzvc88HQK4--MfUaCnCXyT-K8aH9^jH{VJV$%TeFL1P|$X>`D6~fU=l7NF)NF67)|e
z*dL)-BZFjmFju%Cyt2+K=5wbHEG#8zX^fJ
z26Mq&(Xj)lQ!5tW7w1%W%CQn+|4%9z
z4EPwx6!{KEfCt!&6SVi?od4N^|@{EhR*`=;mX~1dSeA5;c{{^l5gh0EWV1I>EZml
zKTnew+`GP##hE%ep;!_GO3s=
Configuration
diff --git a/docs/docs/index.html b/docs/docs/index.html
index 001c8b57a..c8d69c8ed 100644
--- a/docs/docs/index.html
+++ b/docs/docs/index.html
@@ -789,10 +789,6 @@ Documentation
-
-
-
-
Installation
@@ -832,6 +828,10 @@
+
+
+
+
diff --git a/docs/docs/index.xml b/docs/docs/index.xml
index 6024f26d8..77dc07336 100644
--- a/docs/docs/index.xml
+++ b/docs/docs/index.xml
@@ -651,7 +651,7 @@ spec:
targets: "cicd/jobs/*.jenkins"
description: "Jenkins Operator repository"
repositoryBranch: master
- repositoryUrl: ssh://git@github.com:jenkinsci/kubernetes-operator.git</code></pre>
+ repositoryUrl: git@github.com:jenkinsci/kubernetes-operator.git</code></pre>
<p>and create a Kubernetes Secret (name of secret should be the same from <code>credentialID</code> field):</p>
<pre><code>apiVersion: v1
kind: Secret
@@ -2167,14 +2167,17 @@ stringData:
Plugin’s configuration is applied as groovy scripts or the <a href="https://github.com/jenkinsci/configuration-as-code-plugin">configuration as code plugin</a>.
Any plugin working for Jenkins can be installed by the Jenkins Operator.</p>
-<p>Pre-installed plugins:
-* configuration-as-code v1.47
-* git v4.5.0
-* job-dsl v1.77
-* kubernetes-credentials-provider v0.15
-* kubernetes v1.29.0
-* workflow-aggregator v2.6
-* workflow-job v2.40</p>
+<p>Pre-installed plugins:</p>
+
+<ul>
+<li>configuration-as-code v1.51</li>
+<li>git v4.7.2</li>
+<li>job-dsl v1.77</li>
+<li>kubernetes-credentials-provider v0.18-1</li>
+<li>kubernetes v1.30.0</li>
+<li>workflow-aggregator v2.6</li>
+<li>workflow-job v2.41</li>
+</ul>
<p>Rest of the plugins can be found in <a href="https://plugins.jenkins.io/">plugins repository</a>.</p>
@@ -2199,19 +2202,19 @@ Any plugin working for Jenkins can be installed by the Jenkins Operator.</p&g
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>master<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>basePlugins<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>kubernetes<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.28.6"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.30.0"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>workflow-job<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"2.40"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>workflow-aggregator<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"2.6"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>git<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"4.5.0"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"4.7.2"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>job-dsl<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.77"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>configuration-as-code<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.46"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.51"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>kubernetes-credentials-provider<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"0.15"</span></code></pre></div>
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"0.18-1"</span></code></pre></div>
<p>You can change their versions.</p>
<p>The <strong>Jenkins Operator</strong> will then automatically install plugins after the Jenkins master pod restart.</p>
diff --git a/docs/docs/installation/index.html b/docs/docs/installation/index.html
index eb6372364..4aa60183a 100644
--- a/docs/docs/installation/index.html
+++ b/docs/docs/installation/index.html
@@ -26,7 +26,7 @@
" />
-
+
@@ -766,6 +766,8 @@
+
Note on Operator’s nightly built images
+Note on Jenkins home Volume
@@ -808,18 +810,21 @@ Installation
This document describes installation procedure for Jenkins Operator.
-All container images can be found at virtuslab/jenkins-operator
+All container images can be found at virtuslab/jenkins-operator Docker Hub repository.
Requirements
-To run Jenkins Operator, you will need:
-- access to a Kubernetes cluster version 1.17+
-- kubectl
version 1.17+
+To run Jenkins Operator, you will need:
-Listed below are the two ways to deploy Jenkins Operator. For details on how to customize your Jenkins instance, refer to Getting Started
+
+- access to a Kubernetes cluster version
1.17+
+kubectl
version 1.17+
+
+
+Listed below are the two ways to deploy Jenkins Operator. For details on how to customize your Jenkins instance, refer to Getting Started.
Deploy Jenkins Operator using YAML’s
@@ -1649,6 +1654,18 @@ Configuring operator deployment
+Note on Operator’s nightly built images
+
+If you wish to use the newest, not yet released version of the Operator, you can use one of nightly built snapshot images, however the maintainers of this project cannot guarantee their stability.
+
+You can find nightly built images by heading to virtuslab/jenkins-operator Docker Hub repository and looking for images with tag in the form of “{git-hash}”, {git-hash} being the hash of master branch commit that you want to use snapshot of.
+
+Note on Jenkins home Volume
+
+Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users. One of the key points of this design is maintaining an immutable state of Jenkins.
+
+One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume as Jenkins home directory. It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory, as attempting to do so will result in Operator error.
+
@@ -1805,7 +1822,7 @@ Configuring operator deployment
- Last modified October 5, 2020
+ Last modified July 30, 2021
diff --git a/docs/docs/installation/index.xml b/docs/docs/installation/index.xml
index 9bc06edf8..37e38d051 100644
--- a/docs/docs/installation/index.xml
+++ b/docs/docs/installation/index.xml
@@ -4,7 +4,7 @@
https://jenkinsci.github.io/kubernetes-operator/docs/installation/
Recent Hugo news from gohugo.io
Hugo -- gohugo.io
- Mon, 05 Oct 2020 00:00:00 +0000
+ Fri, 30 Jul 2021 00:00:00 +0000
https://jenkinsci.github.io/kubernetes-operator/img/hugo.png
GoHugo.io
diff --git a/docs/sitemap.xml b/docs/sitemap.xml
index efa05ade3..b751f91fc 100644
--- a/docs/sitemap.xml
+++ b/docs/sitemap.xml
@@ -3,18 +3,18 @@
xmlns:xhtml="http://www.w3.org/1999/xhtml">
- https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/deploy-jenkins/
- 2021-01-25T00:00:00+00:00
+ https://jenkinsci.github.io/kubernetes-operator/docs/installation/
+ 2021-07-30T00:00:00+00:00
- https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/v0.5.x/deploy-jenkins/
+ https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/deploy-jenkins/
2021-01-25T00:00:00+00:00
- https://jenkinsci.github.io/kubernetes-operator/docs/installation/
- 2020-10-05T00:00:00+00:00
+ https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/v0.5.x/deploy-jenkins/
+ 2021-01-25T00:00:00+00:00
@@ -369,7 +369,7 @@
https://jenkinsci.github.io/kubernetes-operator/docs/developer-guide/
- 2021-06-10T00:00:00+00:00
+ 2021-07-30T00:00:00+00:00
diff --git a/website/package-lock.json b/website/package-lock.json
index 57c68fa43..fabb2bfa4 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -330,9 +330,9 @@
"dev": true
},
"caniuse-lite": {
- "version": "1.0.30001245",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001245.tgz",
- "integrity": "sha512-768fM9j1PKXpOCKws6eTo3RHmvTUsG9UrpT4WoREFeZgJBTi4/X9g565azS/rVUGtqb8nt7FjLeF5u4kukERnA==",
+ "version": "1.0.30001248",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001248.tgz",
+ "integrity": "sha512-NwlQbJkxUFJ8nMErnGtT0QTM2TJ33xgz4KXJSMIrjXIbDVdaYueGyjOrLKRtJC+rTiWfi6j5cnZN1NBiSBJGNw==",
"dev": true
},
"chalk": {
@@ -568,9 +568,9 @@
}
},
"electron-to-chromium": {
- "version": "1.3.780",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.780.tgz",
- "integrity": "sha512-2KQ9OYm9WMUNpAPA/4aerURl3hwRc9tNlpsiEj3Y8Gf7LVf26NzyLIX2v0hSagQwrS9+cWab+28A2GPKDoVNRA==",
+ "version": "1.3.792",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.792.tgz",
+ "integrity": "sha512-RM2O2xrNarM7Cs+XF/OE2qX/aBROyOZqqgP+8FXMXSuWuUqCfUUzg7NytQrzZU3aSqk1Qq6zqnVkJsbfMkIatg==",
"dev": true
},
"end-of-stream": {
From 37d0eac4e394d314bef2666aee850ed85b8312d8 Mon Sep 17 00:00:00 2001
From: sharmapulkit04
Date: Wed, 4 Aug 2021 16:06:14 +0530
Subject: [PATCH 13/26] Reimplemented the validation logic with caching the
security warnings - Reimplemented the validator interface - Updated manifests
to allocate more resources
---
Dockerfile | 2 +-
api/v1alpha2/jenkins_webhook.go | 268 ++++++++++++------
.../samples/jenkins.io_v1alpha2_jenkins.yaml | 71 ++++-
main.go | 3 +
webhook/all_in_one_v1alpha2.yaml | 9 +-
webhook/operator.yaml | 12 +-
webhook/webhook.yaml | 2 +-
7 files changed, 274 insertions(+), 93 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index ff840ea45..caaced1d7 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -19,6 +19,7 @@ COPY internal/ internal/
COPY pkg/ pkg/
COPY version/ version/
COPY main.go main.go
+RUN mkdir plugins/
# Build
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=on go build -ldflags "-w $CTIMEVAR" -o manager main.go
@@ -29,5 +30,4 @@ FROM gcr.io/distroless/static:nonroot
WORKDIR /
COPY --from=builder /workspace/manager .
USER 65532:65532
-
ENTRYPOINT ["/manager"]
diff --git a/api/v1alpha2/jenkins_webhook.go b/api/v1alpha2/jenkins_webhook.go
index 494fdb802..97af23c99 100644
--- a/api/v1alpha2/jenkins_webhook.go
+++ b/api/v1alpha2/jenkins_webhook.go
@@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
+ http://www.apache.org/lictenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,10 +17,13 @@ limitations under the License.
package v1alpha2
import (
+ "compress/gzip"
"encoding/json"
"errors"
+ "io"
"io/ioutil"
"net/http"
+ "os"
"time"
"github.com/jenkinsci/kubernetes-operator/pkg/plugins"
@@ -32,8 +35,16 @@ import (
"sigs.k8s.io/controller-runtime/pkg/webhook"
)
-// log is for logging in this package.
-var jenkinslog = logf.Log.WithName("jenkins-resource")
+var (
+ jenkinslog = logf.Log.WithName("jenkins-resource") // log is for logging in this package.
+ isRetrieved bool = false // For checking whether the data file is downloaded and extracted or not
+)
+
+const (
+ hosturl string = "https://ci.jenkins.io/job/Infra/job/plugin-site-api/job/generate-data/lastSuccessfulBuild/artifact/plugins.json.gzip" // Url for downloading the plugins file
+ compressedFile string = "/tmp/plugins.json.gzip" // location where the gzip file will be downloaded
+ pluginDataFile string = "/tmp/plugins.json" // location where the file will be extracted
+)
func (in *Jenkins) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
@@ -72,8 +83,13 @@ func (in *Jenkins) ValidateDelete() error {
return nil
}
-type Warnings struct {
- Warnings []Warning `json:"securityWarnings"`
+type PluginsInfo struct {
+ Plugins []PluginInfo `json:"plugins"`
+}
+
+type PluginInfo struct {
+ Name string `json:"name"`
+ SecurityWarnings []Warning `json:"securityWarnings"`
}
type Warning struct {
@@ -83,109 +99,203 @@ type Warning struct {
URL string `json:"url"`
Active bool `json:"active"`
}
+
type Version struct {
FirstVersion string `json:"firstVersion"`
LastVersion string `json:"lastVersion"`
}
-const APIURL string = "https://plugins.jenkins.io/api/plugin/"
-
-func MakeSemanticVersion(version string) string {
- version = "v" + version
- return semver.Canonical(version)
+type PluginData struct {
+ Version string
+ Kind string
}
-func CompareVersions(firstVersion string, lastVersion string, pluginVersion string) bool {
- firstSemVer := MakeSemanticVersion(firstVersion)
- lastSemVer := MakeSemanticVersion(lastVersion)
- pluginSemVer := MakeSemanticVersion(pluginVersion)
- if semver.Compare(pluginSemVer, firstSemVer) == -1 || semver.Compare(pluginSemVer, lastSemVer) == 1 {
- return false
- }
- return true
-}
+// Validates security warnings for both updating and creating a Jenkins CR
+func Validate(r Jenkins) error {
-func CheckSecurityWarnings(pluginName string, pluginVersion string) (bool, error) {
- jenkinslog.Info("checking security warnings", "plugin: ", pluginName)
- pluginURL := APIURL + pluginName
- client := &http.Client{
- Timeout: time.Second * 30,
- }
- request, err := http.NewRequest("GET", pluginURL, nil)
- if err != nil {
- return false, err
- }
- request.Header.Add("Accept", "application/json")
- request.Header.Add("Content-Type", "application/json")
- response, err := client.Do(request)
- if err != nil {
- return false, err
- }
- defer response.Body.Close()
- bodyBytes, err := ioutil.ReadAll(response.Body)
+ pluginset := make(map[string]PluginData)
+ var warningmsg string
+ basePlugins := plugins.BasePlugins()
+ temp, err := NewPluginsInfo()
+ AllPluginData := *temp
if err != nil {
- return false, err
+ return err
}
- securityWarnings := Warnings{}
- jsonErr := json.Unmarshal(bodyBytes, &securityWarnings)
- if jsonErr != nil {
- return false, err
+ for _, plugin := range basePlugins {
+ // Only Update the map if the plugin is not present or a lower version is being used
+ if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
+ jenkinslog.Info("Validate", plugin.Name, plugin.Version)
+ pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "base"}
+ }
}
- jenkinslog.Info("Validate()", "warnings", securityWarnings)
+ for _, plugin := range r.Spec.Master.Plugins {
+ if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
+ jenkinslog.Info("Validate", plugin.Name, plugin.Version)
+ pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "user-defined"}
+ }
+ }
- for _, warning := range securityWarnings.Warnings {
- for _, version := range warning.Versions {
- firstVersion := version.FirstVersion
- lastVersion := version.LastVersion
- if len(firstVersion) == 0 {
- firstVersion = "0" // setting default value in case of empty string
- }
- if len(lastVersion) == 0 {
- lastVersion = pluginVersion // setting default value in case of empty string
+ jenkinslog.Info("Checking through all the warnings")
+ for _, plugin := range AllPluginData.Plugins {
+
+ if pluginData, ispresent := pluginset[plugin.Name]; ispresent {
+ jenkinslog.Info("Checking for plugin", "name", plugin.Name)
+ for _, warning := range plugin.SecurityWarnings {
+ for _, version := range warning.Versions {
+ firstVersion := version.FirstVersion
+ lastVersion := version.LastVersion
+ if len(firstVersion) == 0 {
+ firstVersion = "0" // setting default value in case of empty string
+ }
+ if len(lastVersion) == 0 {
+ lastVersion = pluginData.Version // setting default value in case of empty string
+ }
+
+ if CompareVersions(firstVersion, lastVersion, pluginData.Version) {
+ jenkinslog.Info("security Vulnerabilities detected", "message", warning.Message, "Check security Advisory", warning.URL)
+ warningmsg += "Security Vulnerabilities detected in " + pluginData.Kind + " plugin " + plugin.Name + "\n"
+
+ }
+
+ }
}
- if CompareVersions(firstVersion, lastVersion, pluginVersion) {
- jenkinslog.Info("security Vulnerabilities detected", "message", warning.Message, "Check security Advisory", warning.URL)
- return true, nil
- }
}
+
}
- return false, nil
-}
+ if len(warningmsg) > 0 {
+ return errors.New(warningmsg)
+ }
-func Validate(r Jenkins) error {
- basePlugins := plugins.BasePlugins()
- var warnings string = ""
+ return nil
- for _, plugin := range basePlugins {
- name := plugin.Name
- version := plugin.Version
- hasWarnings, err := CheckSecurityWarnings(name, version)
- if err != nil {
- return err
- }
- if hasWarnings {
- warnings += "Security Vulnerabilities detected in base plugin:" + name
+}
+
+// Returns an object containing information of all the plugins present in the security center
+func NewPluginsInfo() (*PluginsInfo, error) {
+ var AllPluginData PluginsInfo
+ for i := 0; i < 28; i++ {
+ if isRetrieved {
+ break
}
+ time.Sleep(1 * time.Second)
+ }
+ if !isRetrieved {
+ jenkinslog.Info("Plugins Data file hasn't been downloaded and extracted")
+ return &AllPluginData, errors.New("plugins data file not found")
}
- for _, plugin := range r.Spec.Master.Plugins {
- name := plugin.Name
- version := plugin.Version
- hasWarnings, err := CheckSecurityWarnings(name, version)
+ jsonFile, err := os.Open(pluginDataFile)
+ if err != nil {
+ jenkinslog.Info("Failed to open the Plugins Data File")
+ return &AllPluginData, err
+ }
+ defer jsonFile.Close()
+
+ byteValue, err := ioutil.ReadAll(jsonFile)
+ if err != nil {
+ jenkinslog.Info("Failed to convert the JSON file into a byte array")
+ return &AllPluginData, err
+ }
+ err = json.Unmarshal(byteValue, &AllPluginData)
+ if err != nil {
+ jenkinslog.Info("Failed to decode the Plugin JSON data file")
+ return &AllPluginData, err
+ }
+
+ return &AllPluginData, nil
+}
+
+// Downloads and extracts the JSON file in every 12 hours
+func RetrieveDataFile() {
+ for {
+ jenkinslog.Info("Retreiving file", "Host Url", hosturl)
+ err := Download()
if err != nil {
- return err
+ jenkinslog.Info("Retrieving File", "Error while downloading", err)
+ continue
}
- if hasWarnings {
- warnings += "Security Vulnerabilities detected in the user defined plugin: " + name
+
+ jenkinslog.Info("Retrieve File", "Successfully downloaded", compressedFile)
+ err = Extract()
+ if err != nil {
+ jenkinslog.Info("Retreive File", "Error while extracting", err)
+ continue
}
+ jenkinslog.Info("Retreive File", "Successfully extracted", pluginDataFile)
+ isRetrieved = true
+ time.Sleep(12 * time.Hour)
+
}
- if len(warnings) > 0 {
- return errors.New(warnings)
+}
+
+func Download() error {
+
+ out, err := os.Create(compressedFile)
+ if err != nil {
+ return err
+ }
+ defer out.Close()
+
+ client := http.Client{
+ Timeout: 2000 * time.Second,
+ }
+
+ resp, err := client.Get(hosturl)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+ jenkinslog.Info("Successfully Downloaded")
+ _, err = io.Copy(out, resp.Body)
+ if err != nil {
+ return err
}
return nil
+
+}
+
+func Extract() error {
+ reader, err := os.Open(compressedFile)
+
+ if err != nil {
+ return err
+ }
+ defer reader.Close()
+ archive, err := gzip.NewReader(reader)
+ if err != nil {
+ return err
+ }
+
+ defer archive.Close()
+ writer, err := os.Create(pluginDataFile)
+ if err != nil {
+ return err
+ }
+ defer writer.Close()
+
+ _, err = io.Copy(writer, archive)
+ return err
+
+}
+
+// returns a semantic version that can be used for comparision
+func MakeSemanticVersion(version string) string {
+ version = "v" + version
+ return semver.Canonical(version)
+}
+
+// Compare if the current version lies between first version and last version
+func CompareVersions(firstVersion string, lastVersion string, pluginVersion string) bool {
+ firstSemVer := MakeSemanticVersion(firstVersion)
+ lastSemVer := MakeSemanticVersion(lastVersion)
+ pluginSemVer := MakeSemanticVersion(pluginVersion)
+ if semver.Compare(pluginSemVer, firstSemVer) == -1 || semver.Compare(pluginSemVer, lastSemVer) == 1 {
+ return false
+ }
+ return true
}
diff --git a/config/samples/jenkins.io_v1alpha2_jenkins.yaml b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
index b451d5dab..be33732a9 100644
--- a/config/samples/jenkins.io_v1alpha2_jenkins.yaml
+++ b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
@@ -1,8 +1,8 @@
apiVersion: jenkins.io/v1alpha2
kind: Jenkins
metadata:
- name: example
- namespace: default
+ name: example-8
+ namespace: default
spec:
configurationAsCode:
configurations: []
@@ -14,6 +14,7 @@ spec:
name: ""
jenkinsAPISettings:
authorizationStrategy: createUser
+ ValidateSecurityWarnings: true
master:
disableCSRFProtection: false
containers:
@@ -47,6 +48,72 @@ spec:
requests:
cpu: "1"
memory: 500Mi
+ plugins:
+ - name: mailer
+ version: "1.19"
+ - name: script-security
+ version: "1.18"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: google-login
+ version: "1.2"
+ - name: credentials
+ version: "2.1"
+ - name: ssh-credentials
+ version: "1.1"
+ - name: junit
+ version: "1.2"
+ - name: matrix-project
+ version: "1.1"
+ - name: git-client
+ version: "2.8.4"
+ - name: pipeline-model-definition
+ version: "1.3.0"
+ - name: favorite
+ version: "2"
+ - name: workflow-cps
+ version: "2"
+
seedJobs:
- id: jenkins-operator
targets: "cicd/jobs/*.jenkins"
diff --git a/main.go b/main.go
index 8bc382ead..3cd399f6a 100644
--- a/main.go
+++ b/main.go
@@ -95,6 +95,9 @@ func main() {
opts := zap.Options{
Development: true,
}
+
+ go v1alpha2.RetrieveDataFile()
+
opts.BindFlags(flag.CommandLine)
flag.Parse()
diff --git a/webhook/all_in_one_v1alpha2.yaml b/webhook/all_in_one_v1alpha2.yaml
index e53fc659f..0d878dd2d 100644
--- a/webhook/all_in_one_v1alpha2.yaml
+++ b/webhook/all_in_one_v1alpha2.yaml
@@ -222,6 +222,7 @@ subjects:
- kind: ServiceAccount
name: jenkins-operator
---
+---
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -246,7 +247,7 @@ spec:
- /manager
args:
- --leader-elect
- image: jenkins-operator:6f33fe82-dirty
+ image: jenkins-operator:52fe5fe9-dirty
name: jenkins-operator
imagePullPolicy: IfNotPresent
securityContext:
@@ -278,12 +279,12 @@ spec:
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
- readOnly: true
+ readOnly: false
volumes:
- name: cert
secret:
defaultMode: 420
- secretName: webhook-server-cert
+ secretName: webhook-server-cert
terminationGracePeriodSeconds: 10
---
apiVersion: cert-manager.io/v1
@@ -315,7 +316,6 @@ spec:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
- creationTimestamp: null
name: validating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: default/webhook-certificate
@@ -330,6 +330,7 @@ webhooks:
path: /validate-jenkins-io-v1alpha2-jenkins
failurePolicy: Fail
name: vjenkins.kb.io
+ timeoutSeconds: 30
rules:
- apiGroups:
- jenkins.io
diff --git a/webhook/operator.yaml b/webhook/operator.yaml
index 81cbdf98e..c056ba8e0 100644
--- a/webhook/operator.yaml
+++ b/webhook/operator.yaml
@@ -1,3 +1,4 @@
+---
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -41,11 +42,11 @@ spec:
periodSeconds: 10
resources:
limits:
- cpu: 100m
- memory: 30Mi
+ cpu: 200m
+ memory: 200Mi
requests:
cpu: 100m
- memory: 20Mi
+ memory: 80Mi
env:
- name: WATCH_NAMESPACE
valueFrom:
@@ -53,12 +54,11 @@ spec:
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
- name: cert
- readOnly: true
+ name: cert
volumes:
- name: cert
secret:
defaultMode: 420
- secretName: webhook-server-cert
+ secretName: webhook-server-cert
terminationGracePeriodSeconds: 10
---
diff --git a/webhook/webhook.yaml b/webhook/webhook.yaml
index 3a86ab0b1..9cc2a2b74 100644
--- a/webhook/webhook.yaml
+++ b/webhook/webhook.yaml
@@ -1,7 +1,6 @@
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
- creationTimestamp: null
name: validating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: default/webhook-certificate
@@ -16,6 +15,7 @@ webhooks:
path: /validate-jenkins-io-v1alpha2-jenkins
failurePolicy: Fail
name: vjenkins.kb.io
+ timeoutSeconds: 30
rules:
- apiGroups:
- jenkins.io
From 8453b3e9fecfa8ad7fe06732923476c424f7e8c4 Mon Sep 17 00:00:00 2001
From: Szymon Fugas
Date: Thu, 5 Aug 2021 17:27:19 +0200
Subject: [PATCH 14/26] Add an issue template for documentation (#613)
---
.github/ISSUE_TEMPLATE/documentation.md | 14 ++++++++++++++
1 file changed, 14 insertions(+)
create mode 100644 .github/ISSUE_TEMPLATE/documentation.md
diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md
new file mode 100644
index 000000000..a0ed0b42c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/documentation.md
@@ -0,0 +1,14 @@
+---
+name: "📚 Documentation issue"
+about: Suggest changes to project's documentation
+title: ''
+labels: 'documentation'
+projects: ''
+assignees: ''
+---
+
+**Relevant links*
+Link(s) to the section(s) of documentation that are outdated or otherwise wrong
+
+**Description**
+Description of the changes you would like to see
\ No newline at end of file
From 858f0f4c7289bd518ac419d57116907940109429 Mon Sep 17 00:00:00 2001
From: Szymon Fugas
Date: Thu, 5 Aug 2021 17:28:01 +0200
Subject: [PATCH 15/26] Docs: add info on restricted volumeMounts other than
jenkins-home(#612)
* Update note in installation docs
* Update Helm chart default values.yaml
* Update schema
---
chart/jenkins-operator/values.yaml | 5 +++--
.../en/docs/Getting Started/latest/schema.md | 7 ++++++-
.../content/en/docs/Installation/_index.md | 20 +++++++++++++++----
3 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/chart/jenkins-operator/values.yaml b/chart/jenkins-operator/values.yaml
index 1c92fb900..60c992cd2 100644
--- a/chart/jenkins-operator/values.yaml
+++ b/chart/jenkins-operator/values.yaml
@@ -120,8 +120,9 @@ jenkins:
claimName: jenkins-backup
# volumeMounts are mounts for Jenkins pod
- # Note that attempting to overwrite default mount settings for Jenkins home directory will result in Operator error
- # See https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-jenkins-home-volume
+ # Note that attempting to overwrite default mount settings for restricted,
+ # non-configurable volumeMounts will result in Operator error
+ # See https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts for details
volumeMounts: []
# defines authorization strategy of the operator for the Jenkins API
diff --git a/website/content/en/docs/Getting Started/latest/schema.md b/website/content/en/docs/Getting Started/latest/schema.md
index 2a1444c7d..58638cbd2 100644
--- a/website/content/en/docs/Getting Started/latest/schema.md
+++ b/website/content/en/docs/Getting Started/latest/schema.md
@@ -661,7 +661,12 @@ Values defined by an Env with a duplicate key will take precedence.
(Optional)
-Pod volumes to mount into the container’s filesystem.
+
+Pod volumes to mount into the container’s filesystem. More info:
+
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+
+
diff --git a/website/content/en/docs/Installation/_index.md b/website/content/en/docs/Installation/_index.md
index fcd6ba282..17b8df645 100644
--- a/website/content/en/docs/Installation/_index.md
+++ b/website/content/en/docs/Installation/_index.md
@@ -883,7 +883,19 @@ If you wish to use the newest, not yet released version of the Operator, you can
You can find nightly built images by heading to [virtuslab/jenkins-operator](https://hub.docker.com/r/virtuslab/jenkins-operator) Docker Hub repository and looking for images with tag in the form of "{git-hash}", {git-hash} being the hash of master branch commit that you want to use snapshot of.
-## Note on Jenkins home Volume
-Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users. One of the key points of this design is maintaining an immutable state of Jenkins.
-
-One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume as Jenkins home directory. It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory, as attempting to do so will result in Operator error.
\ No newline at end of file
+## Note on restricted Jenkins controller pod volumeMounts
+Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users.
+One of the key points of this design is maintaining an immutable state of Jenkins.
+
+One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume
+(jenkins-home) as Jenkins home directory.
+It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory,
+as attempting to do so will result in Operator error.
+
+jenkins-home is not the only Jenkins controller pod volumeMount that is non-configurable and managed by Operator,
+below is the full list of those volumeMounts:
+
+* jenkins-home
+* scripts
+* init-configuration
+* operator-credentials
\ No newline at end of file
From b82fc7c7640a28a6b4912b533b9534d7e81288bb Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 6 Aug 2021 10:03:57 +0200
Subject: [PATCH 16/26] Auto-updated docs (#616)
Co-authored-by: Sig00rd
---
docs/docs/getting-started/latest/index.xml | 7 ++++-
.../getting-started/latest/schema/index.html | 9 ++++--
docs/docs/index.xml | 7 ++++-
docs/docs/installation/index.html | 22 +++++++++++---
website/package-lock.json | 30 +++++++++----------
5 files changed, 52 insertions(+), 23 deletions(-)
diff --git a/docs/docs/getting-started/latest/index.xml b/docs/docs/getting-started/latest/index.xml
index d6501db16..0b4fccb10 100644
--- a/docs/docs/getting-started/latest/index.xml
+++ b/docs/docs/getting-started/latest/index.xml
@@ -1679,7 +1679,12 @@ Values defined by an Env with a duplicate key will take precedence.</p>
</td>
<td>
<em>(Optional)</em>
-<p>Pod volumes to mount into the container’s filesystem.</p>
+<p>
+Pod volumes to mount into the container’s filesystem. More info:
+<a href="https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts">
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+</a>
+</p>
</td>
</tr>
<tr>
diff --git a/docs/docs/getting-started/latest/schema/index.html b/docs/docs/getting-started/latest/schema/index.html
index 59ee07c21..f31e941da 100644
--- a/docs/docs/getting-started/latest/schema/index.html
+++ b/docs/docs/getting-started/latest/schema/index.html
@@ -32,7 +32,7 @@
">
-
+
@@ -1471,7 +1471,12 @@
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+
+
diff --git a/docs/docs/index.xml b/docs/docs/index.xml
index 77dc07336..5f1c71ccd 100644
--- a/docs/docs/index.xml
+++ b/docs/docs/index.xml
@@ -6194,7 +6194,12 @@ Values defined by an Env with a duplicate key will take precedence.</p>
</td>
<td>
<em>(Optional)</em>
-<p>Pod volumes to mount into the container’s filesystem.</p>
+<p>
+Pod volumes to mount into the container’s filesystem. More info:
+<a href="https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts">
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts
+</a>
+</p>
</td>
</tr>
<tr>
diff --git a/docs/docs/installation/index.html b/docs/docs/installation/index.html
index 4aa60183a..728a3edb5 100644
--- a/docs/docs/installation/index.html
+++ b/docs/docs/installation/index.html
@@ -767,7 +767,7 @@
Configuring operator deployment
Note on Operator’s nightly built images
-Note on Jenkins home Volume
+Note on restricted Jenkins controller pod volumeMounts
@@ -1660,11 +1660,25 @@ Note on Operator’s nightl
You can find nightly built images by heading to virtuslab/jenkins-operator Docker Hub repository and looking for images with tag in the form of “{git-hash}”, {git-hash} being the hash of master branch commit that you want to use snapshot of.
-Note on Jenkins home Volume
+Note on restricted Jenkins controller pod volumeMounts
-Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users. One of the key points of this design is maintaining an immutable state of Jenkins.
+Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users.
+One of the key points of this design is maintaining an immutable state of Jenkins.
-One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume as Jenkins home directory. It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory, as attempting to do so will result in Operator error.
+One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume
+(jenkins-home) as Jenkins home directory.
+It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory,
+as attempting to do so will result in Operator error.
+
+jenkins-home is not the only Jenkins controller pod volumeMount that is non-configurable and managed by Operator,
+below is the full list of those volumeMounts:
+
+
+- jenkins-home
+- scripts
+- init-configuration
+- operator-credentials
+
diff --git a/website/package-lock.json b/website/package-lock.json
index fabb2bfa4..196e451f1 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -288,16 +288,16 @@
}
},
"browserslist": {
- "version": "4.16.6",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz",
- "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==",
+ "version": "4.16.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.7.tgz",
+ "integrity": "sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA==",
"dev": true,
"requires": {
- "caniuse-lite": "^1.0.30001219",
+ "caniuse-lite": "^1.0.30001248",
"colorette": "^1.2.2",
- "electron-to-chromium": "^1.3.723",
+ "electron-to-chromium": "^1.3.793",
"escalade": "^3.1.1",
- "node-releases": "^1.1.71"
+ "node-releases": "^1.1.73"
}
},
"cache-base": {
@@ -330,9 +330,9 @@
"dev": true
},
"caniuse-lite": {
- "version": "1.0.30001248",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001248.tgz",
- "integrity": "sha512-NwlQbJkxUFJ8nMErnGtT0QTM2TJ33xgz4KXJSMIrjXIbDVdaYueGyjOrLKRtJC+rTiWfi6j5cnZN1NBiSBJGNw==",
+ "version": "1.0.30001249",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001249.tgz",
+ "integrity": "sha512-vcX4U8lwVXPdqzPWi6cAJ3FnQaqXbBqy/GZseKNQzRj37J7qZdGcBtxq/QLFNLLlfsoXLUdHw8Iwenri86Tagw==",
"dev": true
},
"chalk": {
@@ -568,9 +568,9 @@
}
},
"electron-to-chromium": {
- "version": "1.3.792",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.792.tgz",
- "integrity": "sha512-RM2O2xrNarM7Cs+XF/OE2qX/aBROyOZqqgP+8FXMXSuWuUqCfUUzg7NytQrzZU3aSqk1Qq6zqnVkJsbfMkIatg==",
+ "version": "1.3.796",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.796.tgz",
+ "integrity": "sha512-agwJFgM0FUC1UPPbQ4aII3HamaaJ09fqWGAWYHmzxDWqdmTleCHyyA0kt3fJlTd5M440IaeuBfzXzXzCotnZcQ==",
"dev": true
},
"end-of-stream": {
@@ -1338,9 +1338,9 @@
"dev": true
},
"nan": {
- "version": "2.14.2",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
- "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
+ "version": "2.15.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz",
+ "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==",
"dev": true,
"optional": true
},
From b400a420e55209fcb9ee14f7cc85121737cd10d3 Mon Sep 17 00:00:00 2001
From: "github-actions[bot]"
<41898282+github-actions[bot]@users.noreply.github.com>
Date: Fri, 6 Aug 2021 13:06:12 +0200
Subject: [PATCH 17/26] Auto-updated docs (#617)
Co-authored-by: Sig00rd
---
website/package-lock.json | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/website/package-lock.json b/website/package-lock.json
index 196e451f1..334ea961a 100644
--- a/website/package-lock.json
+++ b/website/package-lock.json
@@ -568,9 +568,9 @@
}
},
"electron-to-chromium": {
- "version": "1.3.796",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.796.tgz",
- "integrity": "sha512-agwJFgM0FUC1UPPbQ4aII3HamaaJ09fqWGAWYHmzxDWqdmTleCHyyA0kt3fJlTd5M440IaeuBfzXzXzCotnZcQ==",
+ "version": "1.3.798",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.798.tgz",
+ "integrity": "sha512-fwsr6oXAORoV9a6Ak2vMCdXfmHIpAGgpOGesulS1cbGgJmrMl3H+GicUyRG3t+z9uHTMrIuMTleFDW+EUFYT3g==",
"dev": true
},
"end-of-stream": {
@@ -925,9 +925,9 @@
}
},
"graceful-fs": {
- "version": "4.2.6",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
- "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
+ "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==",
"dev": true
},
"has-flag": {
From 1d2651d43fb1616aa49611554fd678c4888b9bd5 Mon Sep 17 00:00:00 2001
From: sharmapulkit04
Date: Fri, 6 Aug 2021 19:01:27 +0530
Subject: [PATCH 18/26] Updated Validation logic - Defined a security manager
struct to cache all the plugin data - Added flag to make validating security
warnings optional while deploying the operator
---
api/v1alpha2/jenkins_webhook.go | 197 ++++++++++--------
.../samples/jenkins.io_v1alpha2_jenkins.yaml | 74 +------
main.go | 14 +-
webhook/all_in_one_v1alpha2.yaml | 11 +-
webhook/operator.yaml | 1 +
5 files changed, 129 insertions(+), 168 deletions(-)
diff --git a/api/v1alpha2/jenkins_webhook.go b/api/v1alpha2/jenkins_webhook.go
index 97af23c99..56750fc28 100644
--- a/api/v1alpha2/jenkins_webhook.go
+++ b/api/v1alpha2/jenkins_webhook.go
@@ -36,14 +36,9 @@ import (
)
var (
- jenkinslog = logf.Log.WithName("jenkins-resource") // log is for logging in this package.
- isRetrieved bool = false // For checking whether the data file is downloaded and extracted or not
-)
-
-const (
- hosturl string = "https://ci.jenkins.io/job/Infra/job/plugin-site-api/job/generate-data/lastSuccessfulBuild/artifact/plugins.json.gzip" // Url for downloading the plugins file
- compressedFile string = "/tmp/plugins.json.gzip" // location where the gzip file will be downloaded
- pluginDataFile string = "/tmp/plugins.json" // location where the file will be extracted
+ jenkinslog = logf.Log.WithName("jenkins-resource") // log is for logging in this package.
+ PluginsDataManager PluginDataManager = *NewPluginsDataManager()
+ _ webhook.Validator = &Jenkins{}
)
func (in *Jenkins) SetupWebhookWithManager(mgr ctrl.Manager) error {
@@ -57,8 +52,6 @@ func (in *Jenkins) SetupWebhookWithManager(mgr ctrl.Manager) error {
// TODO(user): change verbs to "verbs=create;update;delete" if you want to enable deletion validation.
// +kubebuilder:webhook:path=/validate-jenkins-io-jenkins-io-v1alpha2-jenkins,mutating=false,failurePolicy=fail,sideEffects=None,groups=jenkins.io.jenkins.io,resources=jenkins,verbs=create;update,versions=v1alpha2,name=vjenkins.kb.io,admissionReviewVersions={v1,v1beta1}
-var _ webhook.Validator = &Jenkins{}
-
// ValidateCreate implements webhook.Validator so a webhook will be registered for the type
func (in *Jenkins) ValidateCreate() error {
if in.Spec.ValidateSecurityWarnings {
@@ -83,6 +76,15 @@ func (in *Jenkins) ValidateDelete() error {
return nil
}
+type PluginDataManager struct {
+ pluginDataCache PluginsInfo
+ hosturl string
+ compressedFilePath string
+ pluginDataFile string
+ iscached bool
+ maxattempts int
+}
+
type PluginsInfo struct {
Plugins []PluginInfo `json:"plugins"`
}
@@ -112,36 +114,27 @@ type PluginData struct {
// Validates security warnings for both updating and creating a Jenkins CR
func Validate(r Jenkins) error {
-
pluginset := make(map[string]PluginData)
- var warningmsg string
+ var faultybaseplugins string
+ var faultyuserplugins string
basePlugins := plugins.BasePlugins()
- temp, err := NewPluginsInfo()
- AllPluginData := *temp
- if err != nil {
- return err
- }
for _, plugin := range basePlugins {
// Only Update the map if the plugin is not present or a lower version is being used
if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
- jenkinslog.Info("Validate", plugin.Name, plugin.Version)
pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "base"}
}
}
for _, plugin := range r.Spec.Master.Plugins {
if pluginData, ispresent := pluginset[plugin.Name]; !ispresent || semver.Compare(MakeSemanticVersion(plugin.Version), pluginData.Version) == 1 {
- jenkinslog.Info("Validate", plugin.Name, plugin.Version)
pluginset[plugin.Name] = PluginData{Version: plugin.Version, Kind: "user-defined"}
}
}
- jenkinslog.Info("Checking through all the warnings")
- for _, plugin := range AllPluginData.Plugins {
-
+ for _, plugin := range PluginsDataManager.pluginDataCache.Plugins {
if pluginData, ispresent := pluginset[plugin.Name]; ispresent {
- jenkinslog.Info("Checking for plugin", "name", plugin.Name)
+ var hasvulnerabilities bool
for _, warning := range plugin.SecurityWarnings {
for _, version := range warning.Versions {
firstVersion := version.FirstVersion
@@ -154,113 +147,121 @@ func Validate(r Jenkins) error {
}
if CompareVersions(firstVersion, lastVersion, pluginData.Version) {
- jenkinslog.Info("security Vulnerabilities detected", "message", warning.Message, "Check security Advisory", warning.URL)
- warningmsg += "Security Vulnerabilities detected in " + pluginData.Kind + " plugin " + plugin.Name + "\n"
-
+ jenkinslog.Info("Security Vulnerability detected in "+pluginData.Kind+" "+plugin.Name+":"+pluginData.Version, "Warning message", warning.Message, "For more details,check security advisory", warning.URL)
+ hasvulnerabilities = true
}
-
}
}
+ if hasvulnerabilities {
+ if pluginData.Kind == "base" {
+ faultybaseplugins += plugin.Name + ":" + pluginData.Version + "\n"
+ } else {
+ faultyuserplugins += plugin.Name + ":" + pluginData.Version + "\n"
+ }
+ }
}
-
}
-
- if len(warningmsg) > 0 {
- return errors.New(warningmsg)
+ if len(faultybaseplugins) > 0 || len(faultyuserplugins) > 0 {
+ var errormsg string
+ if len(faultybaseplugins) > 0 {
+ errormsg += "Security vulnerabilities detected in the following base plugins: \n" + faultybaseplugins
+ }
+ if len(faultyuserplugins) > 0 {
+ errormsg += "Security vulnerabilities detected in the following user-defined plugins: \n" + faultyuserplugins
+ }
+ return errors.New(errormsg)
}
return nil
-
}
-// Returns an object containing information of all the plugins present in the security center
-func NewPluginsInfo() (*PluginsInfo, error) {
- var AllPluginData PluginsInfo
- for i := 0; i < 28; i++ {
- if isRetrieved {
- break
- }
- time.Sleep(1 * time.Second)
- }
- if !isRetrieved {
- jenkinslog.Info("Plugins Data file hasn't been downloaded and extracted")
- return &AllPluginData, errors.New("plugins data file not found")
+func NewPluginsDataManager() *PluginDataManager {
+ return &PluginDataManager{
+ hosturl: "https://ci.jenkins.io/job/Infra/job/plugin-site-api/job/generate-data/lastSuccessfulBuild/artifact/plugins.json.gzip",
+ compressedFilePath: "/tmp/plugins.json.gzip",
+ pluginDataFile: "/tmp/plugins.json",
+ iscached: false,
+ maxattempts: 5,
}
+}
- jsonFile, err := os.Open(pluginDataFile)
- if err != nil {
- jenkinslog.Info("Failed to open the Plugins Data File")
- return &AllPluginData, err
- }
- defer jsonFile.Close()
+// Downloads extracts and caches the JSON data in every 12 hours
+func (in *PluginDataManager) CachePluginData(ch chan bool) {
+ for {
+ jenkinslog.Info("Initializing/Updating the plugin data cache")
+ var isdownloaded, isextracted, iscached bool
+ var err error
+ for i := 0; i < in.maxattempts; i++ {
+ err = in.Download()
+ if err == nil {
+ isdownloaded = true
+ break
+ }
+ }
- byteValue, err := ioutil.ReadAll(jsonFile)
- if err != nil {
- jenkinslog.Info("Failed to convert the JSON file into a byte array")
- return &AllPluginData, err
- }
- err = json.Unmarshal(byteValue, &AllPluginData)
- if err != nil {
- jenkinslog.Info("Failed to decode the Plugin JSON data file")
- return &AllPluginData, err
- }
+ if isdownloaded {
+ for i := 0; i < in.maxattempts; i++ {
+ err = in.Extract()
+ if err == nil {
+ isextracted = true
+ break
+ }
+ }
+ } else {
+ jenkinslog.Info("Cache Plugin Data", "failed to download file", err)
+ }
- return &AllPluginData, nil
-}
+ if isextracted {
+ for i := 0; i < in.maxattempts; i++ {
+ err = in.Cache()
+ if err == nil {
+ iscached = true
+ break
+ }
+ }
-// Downloads and extracts the JSON file in every 12 hours
-func RetrieveDataFile() {
- for {
- jenkinslog.Info("Retreiving file", "Host Url", hosturl)
- err := Download()
- if err != nil {
- jenkinslog.Info("Retrieving File", "Error while downloading", err)
- continue
+ if !iscached {
+ jenkinslog.Info("Cache Plugin Data", "failed to read plugin data file", err)
+ }
+ } else {
+ jenkinslog.Info("Cache Plugin Data", "failed to extract file", err)
}
- jenkinslog.Info("Retrieve File", "Successfully downloaded", compressedFile)
- err = Extract()
- if err != nil {
- jenkinslog.Info("Retreive File", "Error while extracting", err)
- continue
+ if !in.iscached {
+ ch <- iscached
}
- jenkinslog.Info("Retreive File", "Successfully extracted", pluginDataFile)
- isRetrieved = true
+ in.iscached = in.iscached || iscached
time.Sleep(12 * time.Hour)
-
}
}
-func Download() error {
-
- out, err := os.Create(compressedFile)
+func (in *PluginDataManager) Download() error {
+ out, err := os.Create(in.compressedFilePath)
if err != nil {
return err
}
defer out.Close()
client := http.Client{
- Timeout: 2000 * time.Second,
+ Timeout: 1000 * time.Second,
}
- resp, err := client.Get(hosturl)
+ resp, err := client.Get(in.hosturl)
if err != nil {
return err
}
defer resp.Body.Close()
- jenkinslog.Info("Successfully Downloaded")
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
-
}
-func Extract() error {
- reader, err := os.Open(compressedFile)
+func (in *PluginDataManager) Extract() error {
+ reader, err := os.Open(in.compressedFilePath)
if err != nil {
return err
@@ -272,7 +273,7 @@ func Extract() error {
}
defer archive.Close()
- writer, err := os.Create(pluginDataFile)
+ writer, err := os.Create(in.pluginDataFile)
if err != nil {
return err
}
@@ -280,10 +281,28 @@ func Extract() error {
_, err = io.Copy(writer, archive)
return err
+}
+// Loads the JSON data into memory and stores it
+func (in *PluginDataManager) Cache() error {
+ jsonFile, err := os.Open(in.pluginDataFile)
+ if err != nil {
+ return err
+ }
+ defer jsonFile.Close()
+
+ byteValue, err := ioutil.ReadAll(jsonFile)
+ if err != nil {
+ return err
+ }
+ err = json.Unmarshal(byteValue, &in.pluginDataCache)
+ if err != nil {
+ return err
+ }
+ return nil
}
-// returns a semantic version that can be used for comparision
+// returns a semantic version that can be used for comparison
func MakeSemanticVersion(version string) string {
version = "v" + version
return semver.Canonical(version)
diff --git a/config/samples/jenkins.io_v1alpha2_jenkins.yaml b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
index be33732a9..49f39c931 100644
--- a/config/samples/jenkins.io_v1alpha2_jenkins.yaml
+++ b/config/samples/jenkins.io_v1alpha2_jenkins.yaml
@@ -1,8 +1,9 @@
+
apiVersion: jenkins.io/v1alpha2
kind: Jenkins
metadata:
- name: example-8
- namespace: default
+ name: example
+ namespace: default
spec:
configurationAsCode:
configurations: []
@@ -14,7 +15,6 @@ spec:
name: ""
jenkinsAPISettings:
authorizationStrategy: createUser
- ValidateSecurityWarnings: true
master:
disableCSRFProtection: false
containers:
@@ -48,75 +48,9 @@ spec:
requests:
cpu: "1"
memory: 500Mi
- plugins:
- - name: mailer
- version: "1.19"
- - name: script-security
- version: "1.18"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: google-login
- version: "1.2"
- - name: credentials
- version: "2.1"
- - name: ssh-credentials
- version: "1.1"
- - name: junit
- version: "1.2"
- - name: matrix-project
- version: "1.1"
- - name: git-client
- version: "2.8.4"
- - name: pipeline-model-definition
- version: "1.3.0"
- - name: favorite
- version: "2"
- - name: workflow-cps
- version: "2"
-
seedJobs:
- id: jenkins-operator
targets: "cicd/jobs/*.jenkins"
description: "Jenkins Operator repository"
repositoryBranch: master
- repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
+ repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git
\ No newline at end of file
diff --git a/main.go b/main.go
index 3cd399f6a..936862f1c 100644
--- a/main.go
+++ b/main.go
@@ -78,6 +78,7 @@ func main() {
var metricsAddr string
var enableLeaderElection bool
var probeAddr string
+ var ValidateSecurityWarnings bool
isRunningInCluster, err := resources.IsRunningInCluster()
if err != nil {
@@ -88,6 +89,7 @@ func main() {
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "leader-elect", isRunningInCluster, "Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
+ flag.BoolVar(&ValidateSecurityWarnings, "validate-security-warnings", false, "Enable validation for potential security warnings in jenkins custom resource plugins")
hostname := flag.String("jenkins-api-hostname", "", "Hostname or IP of Jenkins API. It can be service name, node IP or localhost.")
port := flag.Int("jenkins-api-port", 0, "The port on which Jenkins API is running. Note: If you want to use nodePort don't set this setting and --jenkins-api-use-nodeport must be true.")
useNodePort := flag.Bool("jenkins-api-use-nodeport", false, "Connect to Jenkins API using the service nodePort instead of service port. If you want to set this as true - don't set --jenkins-api-port.")
@@ -95,9 +97,6 @@ func main() {
opts := zap.Options{
Development: true,
}
-
- go v1alpha2.RetrieveDataFile()
-
opts.BindFlags(flag.CommandLine)
flag.Parse()
@@ -112,6 +111,15 @@ func main() {
}
logger.Info(fmt.Sprintf("Watch namespace: %v", namespace))
+ if ValidateSecurityWarnings {
+ ispluginsdatainitialized := make(chan bool)
+ go v1alpha2.PluginsDataManager.CachePluginData(ispluginsdatainitialized)
+
+ if !<-ispluginsdatainitialized {
+ fatal(errors.New("Unable to get the plugins data"), *debug)
+ }
+ }
+
// get a config to talk to the API server
cfg, err := config.GetConfig()
if err != nil {
diff --git a/webhook/all_in_one_v1alpha2.yaml b/webhook/all_in_one_v1alpha2.yaml
index 0d878dd2d..18afb8010 100644
--- a/webhook/all_in_one_v1alpha2.yaml
+++ b/webhook/all_in_one_v1alpha2.yaml
@@ -247,7 +247,7 @@ spec:
- /manager
args:
- --leader-elect
- image: jenkins-operator:52fe5fe9-dirty
+ image: jenkins-operator:37d0eac4-dirty
name: jenkins-operator
imagePullPolicy: IfNotPresent
securityContext:
@@ -266,11 +266,11 @@ spec:
periodSeconds: 10
resources:
limits:
- cpu: 100m
- memory: 30Mi
+ cpu: 200m
+ memory: 200Mi
requests:
cpu: 100m
- memory: 20Mi
+ memory: 80Mi
env:
- name: WATCH_NAMESPACE
valueFrom:
@@ -278,8 +278,7 @@ spec:
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
- name: cert
- readOnly: false
+ name: cert
volumes:
- name: cert
secret:
diff --git a/webhook/operator.yaml b/webhook/operator.yaml
index c056ba8e0..01093af2d 100644
--- a/webhook/operator.yaml
+++ b/webhook/operator.yaml
@@ -23,6 +23,7 @@ spec:
- /manager
args:
- --leader-elect
+ - --validate-security-warnings
image: {DOCKER_REGISTRY}:{GITCOMMIT}
name: jenkins-operator
imagePullPolicy: IfNotPresent
From 853f4857466922de550f934d459951b4a1e02341 Mon Sep 17 00:00:00 2001
From: Morten Birkelund
Date: Mon, 9 Aug 2021 14:57:00 +0200
Subject: [PATCH 19/26] Helm Chart: Remove empty priorityClassName from Jenkins
template (#618)
Also bump Helm Chart version to v0.5.2
---
chart/index.yaml | 10 ++++++++++
chart/jenkins-operator/Chart.yaml | 2 +-
.../jenkins-operator/jenkins-operator-0.5.2.tgz | Bin 0 -> 34161 bytes
chart/jenkins-operator/templates/jenkins.yaml | 2 --
4 files changed, 11 insertions(+), 3 deletions(-)
create mode 100644 chart/jenkins-operator/jenkins-operator-0.5.2.tgz
diff --git a/chart/index.yaml b/chart/index.yaml
index b7e1f5541..0044cbebe 100644
--- a/chart/index.yaml
+++ b/chart/index.yaml
@@ -1,6 +1,16 @@
apiVersion: v1
entries:
jenkins-operator:
+ - apiVersion: v2
+ appVersion: 0.6.0
+ created: "2021-06-11T13:50:32.677639006+02:00"
+ description: Kubernetes native operator which fully manages Jenkins on Kubernetes
+ digest: 48fbf15c3ffff7003623edcde0bec39dc37d0a62303f08066960d5fac799af90
+ icon: https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/assets/jenkins-operator-icon.png
+ name: jenkins-operator
+ urls:
+ - https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/chart/jenkins-operator/jenkins-operator-0.5.2.tgz
+ version: 0.5.2
- apiVersion: v2
appVersion: 0.6.0
created: "2021-06-11T13:50:32.677639006+02:00"
diff --git a/chart/jenkins-operator/Chart.yaml b/chart/jenkins-operator/Chart.yaml
index 9d8c137d7..d90d312a6 100644
--- a/chart/jenkins-operator/Chart.yaml
+++ b/chart/jenkins-operator/Chart.yaml
@@ -2,5 +2,5 @@ apiVersion: v2
appVersion: "0.6.0"
description: Kubernetes native operator which fully manages Jenkins on Kubernetes
name: jenkins-operator
-version: 0.5.1
+version: 0.5.2
icon: https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/assets/jenkins-operator-icon.png
diff --git a/chart/jenkins-operator/jenkins-operator-0.5.2.tgz b/chart/jenkins-operator/jenkins-operator-0.5.2.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..c2f1afe9e0063a9c2e03b84b419cade3074dd85f
GIT binary patch
literal 34161
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
Installation
@@ -832,6 +828,10 @@
+
+
+
+
diff --git a/docs/docs/index.xml b/docs/docs/index.xml
index 6024f26d8..77dc07336 100644
--- a/docs/docs/index.xml
+++ b/docs/docs/index.xml
@@ -651,7 +651,7 @@ spec:
targets: "cicd/jobs/*.jenkins"
description: "Jenkins Operator repository"
repositoryBranch: master
- repositoryUrl: ssh://git@github.com:jenkinsci/kubernetes-operator.git</code></pre>
+ repositoryUrl: git@github.com:jenkinsci/kubernetes-operator.git</code></pre>
<p>and create a Kubernetes Secret (name of secret should be the same from <code>credentialID</code> field):</p>
<pre><code>apiVersion: v1
kind: Secret
@@ -2167,14 +2167,17 @@ stringData:
Plugin’s configuration is applied as groovy scripts or the <a href="https://github.com/jenkinsci/configuration-as-code-plugin">configuration as code plugin</a>.
Any plugin working for Jenkins can be installed by the Jenkins Operator.</p>
-<p>Pre-installed plugins:
-* configuration-as-code v1.47
-* git v4.5.0
-* job-dsl v1.77
-* kubernetes-credentials-provider v0.15
-* kubernetes v1.29.0
-* workflow-aggregator v2.6
-* workflow-job v2.40</p>
+<p>Pre-installed plugins:</p>
+
+<ul>
+<li>configuration-as-code v1.51</li>
+<li>git v4.7.2</li>
+<li>job-dsl v1.77</li>
+<li>kubernetes-credentials-provider v0.18-1</li>
+<li>kubernetes v1.30.0</li>
+<li>workflow-aggregator v2.6</li>
+<li>workflow-job v2.41</li>
+</ul>
<p>Rest of the plugins can be found in <a href="https://plugins.jenkins.io/">plugins repository</a>.</p>
@@ -2199,19 +2202,19 @@ Any plugin working for Jenkins can be installed by the Jenkins Operator.</p&g
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>master<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>basePlugins<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>kubernetes<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.28.6"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.30.0"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>workflow-job<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"2.40"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>workflow-aggregator<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"2.6"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>git<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"4.5.0"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"4.7.2"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>job-dsl<span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.77"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>configuration-as-code<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.46"</span><span style="color:#f8f8f8;text-decoration:underline">
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"1.51"</span><span style="color:#f8f8f8;text-decoration:underline">
</span><span style="color:#f8f8f8;text-decoration:underline"> </span>-<span style="color:#f8f8f8;text-decoration:underline"> </span>name<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span>kubernetes-credentials-provider<span style="color:#f8f8f8;text-decoration:underline">
-</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"0.15"</span></code></pre></div>
+</span><span style="color:#f8f8f8;text-decoration:underline"> </span>version<span style="color:#000;font-weight:bold">:</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#4e9a06">"0.18-1"</span></code></pre></div>
<p>You can change their versions.</p>
<p>The <strong>Jenkins Operator</strong> will then automatically install plugins after the Jenkins master pod restart.</p>
diff --git a/docs/docs/installation/index.html b/docs/docs/installation/index.html
index eb6372364..4aa60183a 100644
--- a/docs/docs/installation/index.html
+++ b/docs/docs/installation/index.html
@@ -26,7 +26,7 @@
" />
-
+
@@ -766,6 +766,8 @@
+
Installation
This document describes installation procedure for Jenkins Operator. -All container images can be found at virtuslab/jenkins-operator
+All container images can be found at virtuslab/jenkins-operator Docker Hub repository.Requirements
-To run Jenkins Operator, you will need:
-- access to a Kubernetes cluster version 1.17+
-- kubectl
version 1.17+
To run Jenkins Operator, you will need:
-Listed below are the two ways to deploy Jenkins Operator. For details on how to customize your Jenkins instance, refer to Getting Started
+-
+
- access to a Kubernetes cluster version
1.17+
+ kubectl
version1.17+
+
Listed below are the two ways to deploy Jenkins Operator. For details on how to customize your Jenkins instance, refer to Getting Started.
Deploy Jenkins Operator using YAML’s
@@ -1649,6 +1654,18 @@Configuring operator deployment
+Note on Operator’s nightly built images
+ +If you wish to use the newest, not yet released version of the Operator, you can use one of nightly built snapshot images, however the maintainers of this project cannot guarantee their stability.
+ +You can find nightly built images by heading to virtuslab/jenkins-operator Docker Hub repository and looking for images with tag in the form of “{git-hash}”, {git-hash} being the hash of master branch commit that you want to use snapshot of.
+ +Note on Jenkins home Volume
+ +Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users. One of the key points of this design is maintaining an immutable state of Jenkins.
+ +One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume as Jenkins home directory. It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory, as attempting to do so will result in Operator error.
+Configuring operator deployment
-Pod volumes to mount into the container’s filesystem.
++Pod volumes to mount into the container’s filesystem. More info: + +https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts + +
+https://jenkinsci.github.io/kubernetes-operator/docs/installation/#note-on-restricted-jenkins-controller-pod-volumemounts + +
Note on Operator’s nightl
You can find nightly built images by heading to virtuslab/jenkins-operator Docker Hub repository and looking for images with tag in the form of “{git-hash}”, {git-hash} being the hash of master branch commit that you want to use snapshot of.
-Note on Jenkins home Volume
+Note on restricted Jenkins controller pod volumeMounts
-Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users. One of the key points of this design is maintaining an immutable state of Jenkins.
+Current design of the Operator puts an emphasis on creating a full GitOps flow of work for Jenkins users. +One of the key points of this design is maintaining an immutable state of Jenkins.
-One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume as Jenkins home directory. It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory, as attempting to do so will result in Operator error.
+One of the prerequisites of this is an ephemeral Jenkins home directory. To achieve that, Operator mounts emptyDir Volume +(jenkins-home) as Jenkins home directory. +It is not possible to overwrite volumeMount and specify any other Volume for Jenkins home directory, +as attempting to do so will result in Operator error.
+ +jenkins-home is not the only Jenkins controller pod volumeMount that is non-configurable and managed by Operator, +below is the full list of those volumeMounts:
+ +-
+
- jenkins-home +
- scripts +
- init-configuration +
- operator-credentials +
tsuX@P3G