Added validation webhook,cert-manager,and updated Makefile.

- Scaffolded a new validation webhook using operator-sdk
- Added manifests for webhook.
- Added manifests for self signed issuer and certificates
- Added a new spec named ValidateSecurityWarnings to the Jenkins custom resource definition to enable/disable security check.
- Updated Makefile to deploy the operator locally.
- Updated helm template and default values.yaml
This commit is contained in:
sharmapulkit04 2021-06-17 01:07:39 +05:30
parent 63370a55cc
commit e87c7cac5f
15 changed files with 854 additions and 0 deletions

View File

@ -523,3 +523,24 @@ kubebuilder:
mkdir -p ${ENVTEST_ASSETS_DIR}
test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.7.0/hack/setup-envtest.sh
source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools $(ENVTEST_ASSETS_DIR); setup_envtest_env $(ENVTEST_ASSETS_DIR);
#TODO Integrate with master Makefile.
MANIFESTS := webhook/all_in_one_$(API_VERSION).yaml
all-in-one-build-webhook: ## Re-generate all-in-one yaml
@echo "+ $@"
> $(MANIFESTS)
cat webhook/rbac.yaml >> $(MANIFESTS)
cat webhook/operator.yaml >> $(MANIFESTS)
cat webhook/cert-manager.yaml >> $(MANIFESTS)
cat webhook/webhook.yaml >> $(MANIFESTS)
sed -i "s~{DOCKER_REGISTRY}:{GITCOMMIT}~${DOCKER_REGISTRY}:${GITCOMMIT}~;" ${MANIFESTS}
# start the cluster locally and set it to use the docker daemon from minikube
install-cert-manager: minikube-start
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.4.0/cert-manager.yaml
#Launch cert-manager and deploy the operator locally along with webhook
deploy-webhook: install-cert-manager install-crds container-runtime-build all-in-one-build-webhook
@echo "+ $@"
kubectl apply -f ${MANIFESTS}

View File

@ -7,6 +7,7 @@ resources:
group: jenkins.io
kind: Jenkins
version: v1alpha2
webhookVersion: v1
version: 3-alpha
plugins:
manifests.sdk.operatorframework.io/v2: {}

View File

@ -18,6 +18,10 @@ type JenkinsSpec struct {
// +optional
SeedJobs []SeedJob `json:"seedJobs,omitempty"`
// ValidateSecurityWarnings enables or disables validating potential security warnings in Jenkins plugins via admission webhooks.
//+optional
ValidateSecurityWarnings bool `json:"ValidateSecurityWarnings,omitempty"`
// Notifications defines list of a services which are used to inform about Jenkins status
// Can be used to integrate chat services like Slack, Microsoft Teams or Mailgun
// +optional

View File

@ -0,0 +1,61 @@
/*
Copyright 2021.
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
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1alpha2
import (
"k8s.io/apimachinery/pkg/runtime"
ctrl "sigs.k8s.io/controller-runtime"
logf "sigs.k8s.io/controller-runtime/pkg/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
)
// log is for logging in this package.
var jenkinslog = logf.Log.WithName("jenkins-resource")
func (in *Jenkins) SetupWebhookWithManager(mgr ctrl.Manager) error {
return ctrl.NewWebhookManagedBy(mgr).
For(in).
Complete()
}
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// 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 {
jenkinslog.Info("validate create", "name", in.Name)
// TODO(user): fill in your validation logic upon object creation.
return nil
}
// ValidateUpdate implements webhook.Validator so a webhook will be registered for the type
func (in *Jenkins) ValidateUpdate(old runtime.Object) error {
jenkinslog.Info("validate update", "name", in.Name)
// TODO(user): fill in your validation logic upon object update.
return nil
}
func (in *Jenkins) ValidateDelete() error {
// TODO(user): fill in your validation logic upon object deletion.
return nil
}

View File

@ -148,6 +148,7 @@ spec:
{{- toYaml . | nindent 6 }}
{{- end }}
{{- with .Values.jenkins.seedJobs }}
ValidateSecurityWarnings: {{ .Values.jenkins.ValidateSecurityWarnings }}
seedJobs: {{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

View File

@ -46,6 +46,10 @@ jenkins:
# See https://github.com/jenkinsci/kubernetes-operator/pull/193 for more info
disableCSRFProtection: false
# ValidateSecurityWarnings enables or disables validating potential security warnings in Jenkins plugins via admission webhooks.
ValidateSecurityWarnings: false
# imagePullSecrets is used if you want to pull images from private repository
# See https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configuration/#pulling-docker-images-from-private-repositories for more info
imagePullSecrets: []

View File

@ -35,6 +35,10 @@ spec:
spec:
description: Spec defines the desired state of the Jenkins
properties:
ValidateSecurityWarnings:
description: ValidateSecurityWarnings enables or disables validating
potential security warnings in Jenkins plugins via admission webhooks.
type: boolean
backup:
description: 'Backup defines configuration of Jenkins backup More
info: https://jenkinsci.github.io/kubernetes-operator/docs/getting-started/latest/configure-backup-and-restore/'

View File

@ -0,0 +1,29 @@
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
creationTimestamp: null
name: validating-webhook-configuration
webhooks:
- admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
name: webhook-service
namespace: system
path: /validate-jenkins-io-jenkins-io-v1alpha2-jenkins
failurePolicy: Fail
name: vjenkins.kb.io
rules:
- apiGroups:
- jenkins.io.jenkins.io
apiVersions:
- v1alpha2
operations:
- CREATE
- UPDATE
resources:
- jenkins
sideEffects: None

View File

@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: webhook-service
namespace: system
spec:
ports:
- port: 443
targetPort: 9443
selector:
control-plane: controller-manager

View File

@ -169,6 +169,9 @@ func main() {
fatal(errors.Wrap(err, "unable to create Jenkins controller"), *debug)
}
if err = (&v1alpha2.Jenkins{}).SetupWebhookWithManager(mgr); err != nil {
fatal(errors.Wrap(err, "unable to create Webhook"), *debug)
}
// +kubebuilder:scaffold:builder
if err := mgr.AddHealthzCheck("health", healthz.Ping); err != nil {

View File

@ -0,0 +1,357 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins-operator
---
# permissions to do leader election.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: leader-election-role
rules:
- apiGroups:
- ""
- coordination.k8s.io
resources:
- configmaps
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: leader-election-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: leader-election-role
subjects:
- kind: ServiceAccount
name: jenkins-operator
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jenkins-operator
rules:
- apiGroups:
- apps
resources:
- daemonsets
- deployments
- replicasets
- statefulsets
verbs:
- '*'
- apiGroups:
- apps
- jenkins-operator
resources:
- deployments/finalizers
verbs:
- update
- apiGroups:
- build.openshift.io
resources:
- buildconfigs
- builds
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
- secrets
- services
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- get
- list
- patch
- watch
- apiGroups:
- ""
resources:
- persistentvolumeclaims
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- pods
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- pods
- pods/exec
verbs:
- '*'
- apiGroups:
- ""
resources:
- pods/log
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- pods/portforward
verbs:
- create
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- image.openshift.io
resources:
- imagestreams
verbs:
- get
- list
- watch
- apiGroups:
- jenkins.io
resources:
- '*'
verbs:
- '*'
- apiGroups:
- jenkins.io
resources:
- jenkins
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- jenkins.io
resources:
- jenkins/finalizers
verbs:
- update
- apiGroups:
- jenkins.io
resources:
- jenkins/status
verbs:
- get
- patch
- update
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
- roles
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- route.openshift.io
resources:
- routes
verbs:
- create
- get
- list
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: manager-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins-operator
subjects:
- kind: ServiceAccount
name: jenkins-operator
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins-operator
labels:
control-plane: controller-manager
spec:
selector:
matchLabels:
control-plane: controller-manager
replicas: 1
template:
metadata:
labels:
control-plane: controller-manager
spec:
serviceAccountName: jenkins-operator
securityContext:
runAsUser: 65532
containers:
- command:
- /manager
args:
- --leader-elect
image: jenkins-operator:6f33fe82-dirty
name: jenkins-operator
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
livenessProbe:
httpGet:
path: /healthz
port: 8081
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /readyz
port: 8081
initialDelaySeconds: 5
periodSeconds: 10
resources:
limits:
cpu: 100m
memory: 30Mi
requests:
cpu: 100m
memory: 20Mi
env:
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
readOnly: true
volumes:
- name: cert
secret:
defaultMode: 420
secretName: webhook-server-cert
terminationGracePeriodSeconds: 10
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: webhook-certificate
namespace: default
spec:
duration: 2160h
renewBefore: 360h
secretName: webhook-server-cert
dnsNames:
- webhook-service.default.svc
- webhook-service.default.svc.cluster.local
issuerRef:
kind: Issuer
name: selfsigned
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned
namespace: default
spec:
selfSigned: {}
---
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
creationTimestamp: null
name: validating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: default/webhook-certificate
webhooks:
- admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
name: webhook-service
namespace: default
path: /validate-jenkins-io-v1alpha2-jenkins
failurePolicy: Fail
name: vjenkins.kb.io
rules:
- apiGroups:
- jenkins.io
apiVersions:
- v1alpha2
operations:
- CREATE
- UPDATE
resources:
- jenkins
sideEffects: None
---
apiVersion: v1
kind: Service
metadata:
name: webhook-service
namespace: default
spec:
ports:
- port: 443
targetPort: 9443
selector:
control-plane: controller-manager
---

26
webhook/cert-manager.yaml Normal file
View File

@ -0,0 +1,26 @@
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: webhook-certificate
namespace: default
spec:
duration: 2160h
renewBefore: 360h
secretName: webhook-server-cert
dnsNames:
- webhook-service.default.svc
- webhook-service.default.svc.cluster.local
issuerRef:
kind: Issuer
name: selfsigned
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned
namespace: default
spec:
selfSigned: {}
---

64
webhook/operator.yaml Normal file
View File

@ -0,0 +1,64 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: jenkins-operator
labels:
control-plane: controller-manager
spec:
selector:
matchLabels:
control-plane: controller-manager
replicas: 1
template:
metadata:
labels:
control-plane: controller-manager
spec:
serviceAccountName: jenkins-operator
securityContext:
runAsUser: 65532
containers:
- command:
- /manager
args:
- --leader-elect
image: {DOCKER_REGISTRY}:{GITCOMMIT}
name: jenkins-operator
imagePullPolicy: IfNotPresent
securityContext:
allowPrivilegeEscalation: false
livenessProbe:
httpGet:
path: /healthz
port: 8081
initialDelaySeconds: 15
periodSeconds: 20
readinessProbe:
httpGet:
path: /readyz
port: 8081
initialDelaySeconds: 5
periodSeconds: 10
resources:
limits:
cpu: 100m
memory: 30Mi
requests:
cpu: 100m
memory: 20Mi
env:
- name: WATCH_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
volumeMounts:
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: cert
readOnly: true
volumes:
- name: cert
secret:
defaultMode: 420
secretName: webhook-server-cert
terminationGracePeriodSeconds: 10
---

224
webhook/rbac.yaml Normal file
View File

@ -0,0 +1,224 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: jenkins-operator
---
# permissions to do leader election.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: leader-election-role
rules:
- apiGroups:
- ""
- coordination.k8s.io
resources:
- configmaps
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: leader-election-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: leader-election-role
subjects:
- kind: ServiceAccount
name: jenkins-operator
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: jenkins-operator
rules:
- apiGroups:
- apps
resources:
- daemonsets
- deployments
- replicasets
- statefulsets
verbs:
- '*'
- apiGroups:
- apps
- jenkins-operator
resources:
- deployments/finalizers
verbs:
- update
- apiGroups:
- build.openshift.io
resources:
- buildconfigs
- builds
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
- secrets
- services
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- get
- list
- patch
- watch
- apiGroups:
- ""
resources:
- persistentvolumeclaims
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- pods
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- pods
- pods/exec
verbs:
- '*'
- apiGroups:
- ""
resources:
- pods/log
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- pods/portforward
verbs:
- create
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- image.openshift.io
resources:
- imagestreams
verbs:
- get
- list
- watch
- apiGroups:
- jenkins.io
resources:
- '*'
verbs:
- '*'
- apiGroups:
- jenkins.io
resources:
- jenkins
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- jenkins.io
resources:
- jenkins/finalizers
verbs:
- update
- apiGroups:
- jenkins.io
resources:
- jenkins/status
verbs:
- get
- patch
- update
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
- roles
verbs:
- create
- get
- list
- update
- watch
- apiGroups:
- route.openshift.io
resources:
- routes
verbs:
- create
- get
- list
- update
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: manager-rolebinding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: jenkins-operator
subjects:
- kind: ServiceAccount
name: jenkins-operator
---

43
webhook/webhook.yaml Normal file
View File

@ -0,0 +1,43 @@
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
creationTimestamp: null
name: validating-webhook-configuration
annotations:
cert-manager.io/inject-ca-from: default/webhook-certificate
webhooks:
- admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
name: webhook-service
namespace: default
path: /validate-jenkins-io-v1alpha2-jenkins
failurePolicy: Fail
name: vjenkins.kb.io
rules:
- apiGroups:
- jenkins.io
apiVersions:
- v1alpha2
operations:
- CREATE
- UPDATE
resources:
- jenkins
sideEffects: None
---
apiVersion: v1
kind: Service
metadata:
name: webhook-service
namespace: default
spec:
ports:
- port: 443
targetPort: 9443
selector:
control-plane: controller-manager
---