Add RBAC for Jenkins master pod
This commit is contained in:
		
							parent
							
								
									8d12d9b1fe
								
							
						
					
					
						commit
						e313cc2991
					
				|  | @ -1,41 +1,64 @@ | ||||||
| --- | --- | ||||||
| apiVersion: rbac.authorization.k8s.io/v1 |  | ||||||
| kind: Role | kind: Role | ||||||
|  | apiVersion: rbac.authorization.k8s.io/v1 | ||||||
| metadata: | metadata: | ||||||
|   creationTimestamp: null |  | ||||||
|   name: jenkins-operator |   name: jenkins-operator | ||||||
| rules: | rules: | ||||||
| - apiGroups: |   - apiGroups: | ||||||
|   - "" |       - aurora.tescocloud.com | ||||||
|   resources: |     resources: | ||||||
|   - pods |       - jenkinses | ||||||
|   - services |     verbs: | ||||||
|   - endpoints |       - "*" | ||||||
|   - persistentvolumeclaims |   - apiGroups: | ||||||
|   - events |       - "" | ||||||
|   - configmaps |     resources: | ||||||
|   - secrets |       - services | ||||||
|   verbs: |       - configmaps | ||||||
|   - '*' |       - secrets | ||||||
| - apiGroups: |     verbs: | ||||||
|   - apps |       - get | ||||||
|   resources: |       - create | ||||||
|   - deployments |       - update | ||||||
|   - daemonsets |   - apiGroups: | ||||||
|   - replicasets |       - "extensions" | ||||||
|   - statefulsets |     resources: | ||||||
|   verbs: |       - ingresses | ||||||
|   - '*' |     verbs: | ||||||
| - apiGroups: |       - create | ||||||
|   - monitoring.coreos.com |       - update | ||||||
|   resources: |   - apiGroups: | ||||||
|   - servicemonitors |       - "" | ||||||
|   verbs: |     resources: | ||||||
|   - get |       - serviceaccounts | ||||||
|   - create |     verbs: | ||||||
| - apiGroups: |       - create | ||||||
|   - virtuslab.com |   - apiGroups: | ||||||
|   resources: |       - rbac.authorization.k8s.io | ||||||
|   - '*' |     resources: | ||||||
|   verbs: |       - roles | ||||||
|   - '*' |       - rolebindings | ||||||
|  |     verbs: | ||||||
|  |       - create | ||||||
|  |       - update | ||||||
|  |   - apiGroups: | ||||||
|  |       - "" | ||||||
|  |     resources: | ||||||
|  |       - pods/portforward | ||||||
|  |     verbs: | ||||||
|  |       - create | ||||||
|  |   - apiGroups: | ||||||
|  |       - "" | ||||||
|  |     resources: | ||||||
|  |       - pods/log | ||||||
|  |     verbs: | ||||||
|  |       - get | ||||||
|  |       - list | ||||||
|  |       - watch | ||||||
|  |   - apiGroups: | ||||||
|  |       - "" | ||||||
|  |     resources: | ||||||
|  |       - pods | ||||||
|  |       - pods/exec | ||||||
|  |     verbs: | ||||||
|  |       - "*" | ||||||
|  |  | ||||||
|  | @ -2,14 +2,16 @@ package base | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"crypto/sha256" | ||||||
|  | 	"encoding/base64" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"reflect" | 	"reflect" | ||||||
|  | 	"sort" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1" | 	virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1" | ||||||
| 	jenkinsclient "github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/client" | 	jenkinsclient "github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/client" | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/configuration/base/resources" | 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/configuration/base/resources" | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/configuration/user/theme" |  | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/constants" | 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/constants" | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/groovy" | 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/groovy" | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/plugin" | 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/plugin" | ||||||
|  | @ -82,6 +84,11 @@ func (r *ReconcileJenkinsBaseConfiguration) Reconcile() (*reconcile.Result, jenk | ||||||
| 	} | 	} | ||||||
| 	r.logger.V(log.VDebug).Info("User configuration config map is present") | 	r.logger.V(log.VDebug).Info("User configuration config map is present") | ||||||
| 
 | 
 | ||||||
|  | 	if err := r.createRBAC(metaObject); err != nil { | ||||||
|  | 		return &reconcile.Result{}, nil, err | ||||||
|  | 	} | ||||||
|  | 	r.logger.V(log.VDebug).Info("User configuration config map is present") | ||||||
|  | 
 | ||||||
| 	if err := r.createService(metaObject); err != nil { | 	if err := r.createService(metaObject); err != nil { | ||||||
| 		return &reconcile.Result{}, nil, err | 		return &reconcile.Result{}, nil, err | ||||||
| 	} | 	} | ||||||
|  | @ -226,6 +233,28 @@ func (r *ReconcileJenkinsBaseConfiguration) createUserConfigurationConfigMap(met | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (r *ReconcileJenkinsBaseConfiguration) createRBAC(meta metav1.ObjectMeta) error { | ||||||
|  | 	serviceAccount := resources.NewServiceAccount(meta) | ||||||
|  | 	err := r.createOrUpdateResource(serviceAccount) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	role := resources.NewRole(meta) | ||||||
|  | 	err = r.createOrUpdateResource(role) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	roleBinding := resources.NewRoleBinding(meta) | ||||||
|  | 	err = r.createOrUpdateResource(roleBinding) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (r *ReconcileJenkinsBaseConfiguration) createService(meta metav1.ObjectMeta) error { | func (r *ReconcileJenkinsBaseConfiguration) createService(meta metav1.ObjectMeta) error { | ||||||
| 	err := r.createResource(resources.NewService(&meta, r.minikube)) | 	err := r.createResource(resources.NewService(&meta, r.minikube)) | ||||||
| 	if err != nil && !apierrors.IsAlreadyExists(err) { | 	if err != nil && !apierrors.IsAlreadyExists(err) { | ||||||
|  | @ -399,7 +428,27 @@ func (r *ReconcileJenkinsBaseConfiguration) baseConfiguration(jenkinsClient jenk | ||||||
| 		return &reconcile.Result{}, err | 		return &reconcile.Result{}, err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	done, err := groovyClient.EnsureGroovyJob(theme.SetThemeGroovyScript, r.jenkins) | 	configuration := &corev1.ConfigMap{} | ||||||
|  | 	namespaceName := types.NamespacedName{Namespace: r.jenkins.Namespace, Name: resources.GetUserConfigurationConfigMapName(r.jenkins)} | ||||||
|  | 	err = r.client.Get(context.TODO(), namespaceName, configuration) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return &reconcile.Result{}, err | ||||||
|  | 	} | ||||||
|  | 	hash := sha256.New() | ||||||
|  | 
 | ||||||
|  | 	var keys []string | ||||||
|  | 	for key, _ := range configuration.Data { | ||||||
|  | 		keys = append(keys, key) | ||||||
|  | 	} | ||||||
|  | 	sort.Strings(keys) | ||||||
|  | 	for _, key := range keys { | ||||||
|  | 		hash.Write([]byte(key)) | ||||||
|  | 		hash.Write([]byte(configuration.Data[key])) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	encodedHash := base64.URLEncoding.EncodeToString(hash.Sum(nil)) | ||||||
|  | 
 | ||||||
|  | 	done, err := groovyClient.EnsureGroovyJob(encodedHash, r.jenkins) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return &reconcile.Result{}, err | 		return &reconcile.Result{}, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -64,6 +64,7 @@ func NewJenkinsMasterPod(objectMeta metav1.ObjectMeta, jenkins *virtuslabv1alpha | ||||||
| 		TypeMeta:   buildPodTypeMeta(), | 		TypeMeta:   buildPodTypeMeta(), | ||||||
| 		ObjectMeta: objectMeta, | 		ObjectMeta: objectMeta, | ||||||
| 		Spec: corev1.PodSpec{ | 		Spec: corev1.PodSpec{ | ||||||
|  | 			ServiceAccountName: objectMeta.Name, | ||||||
| 			RestartPolicy: corev1.RestartPolicyNever, | 			RestartPolicy: corev1.RestartPolicyNever, | ||||||
| 			SecurityContext: &corev1.PodSecurityContext{ | 			SecurityContext: &corev1.PodSecurityContext{ | ||||||
| 				RunAsUser:  &runAsUser, | 				RunAsUser:  &runAsUser, | ||||||
|  |  | ||||||
|  | @ -0,0 +1,71 @@ | ||||||
|  | package resources | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"k8s.io/api/rbac/v1" | ||||||
|  | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	createVerb = "create" | ||||||
|  | 	deleteVerb = "delete" | ||||||
|  | 	getVerb    = "get" | ||||||
|  | 	listVerb   = "list" | ||||||
|  | 	watchVerb  = "watch" | ||||||
|  | 	patchVerb  = "patch" | ||||||
|  | 	updateVerb = "update" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func NewRole(meta metav1.ObjectMeta) *v1.Role { | ||||||
|  | 	return &v1.Role{ | ||||||
|  | 		TypeMeta: metav1.TypeMeta{ | ||||||
|  | 			Kind:       "Role", | ||||||
|  | 			APIVersion: "rbac.authorization.k8s.io/v1", | ||||||
|  | 		}, | ||||||
|  | 		ObjectMeta: meta, | ||||||
|  | 		Rules: []v1.PolicyRule{ | ||||||
|  | 			{ | ||||||
|  | 				APIGroups: []string{""}, | ||||||
|  | 				Resources: []string{"pods/portforward"}, | ||||||
|  | 				Verbs:     []string{createVerb}, | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				APIGroups: []string{""}, | ||||||
|  | 				Resources: []string{"pods"}, | ||||||
|  | 				Verbs:     []string{createVerb, deleteVerb, getVerb, listVerb, patchVerb, updateVerb, watchVerb}, | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				APIGroups: []string{""}, | ||||||
|  | 				Resources: []string{"pods/exec"}, | ||||||
|  | 				Verbs:     []string{createVerb, deleteVerb, getVerb, listVerb, patchVerb, updateVerb, watchVerb}, | ||||||
|  | 			}, | ||||||
|  | 			{ | ||||||
|  | 				APIGroups: []string{""}, | ||||||
|  | 				Resources: []string{"pods/log"}, | ||||||
|  | 				Verbs:     []string{getVerb, listVerb, watchVerb}, | ||||||
|  | 			}, | ||||||
|  | 			//TODO get secrets ???
 | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func NewRoleBinding(meta metav1.ObjectMeta) *v1.RoleBinding { | ||||||
|  | 	return &v1.RoleBinding{ | ||||||
|  | 		TypeMeta: metav1.TypeMeta{ | ||||||
|  | 			Kind:       "RoleBinding", | ||||||
|  | 			APIVersion: "rbac.authorization.k8s.io/v1", | ||||||
|  | 		}, | ||||||
|  | 		ObjectMeta: meta, | ||||||
|  | 		RoleRef: v1.RoleRef{ | ||||||
|  | 			APIGroup: "rbac.authorization.k8s.io", | ||||||
|  | 			Kind:     "Role", | ||||||
|  | 			Name:     meta.Name, | ||||||
|  | 		}, | ||||||
|  | 		Subjects: []v1.Subject{ | ||||||
|  | 			{ | ||||||
|  | 				Kind:      "ServiceAccount", | ||||||
|  | 				Name:      meta.Name, | ||||||
|  | 				Namespace: meta.Namespace, | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -0,0 +1,16 @@ | ||||||
|  | package resources | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"k8s.io/api/core/v1" | ||||||
|  | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func NewServiceAccount(meta metav1.ObjectMeta) *v1.ServiceAccount { | ||||||
|  | 	return &v1.ServiceAccount{ | ||||||
|  | 		TypeMeta: metav1.TypeMeta{ | ||||||
|  | 			Kind:       "ServiceAccount", | ||||||
|  | 			APIVersion: "v1", | ||||||
|  | 		}, | ||||||
|  | 		ObjectMeta: meta, | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -1,8 +1,6 @@ | ||||||
| package groovy | package groovy | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"crypto/sha256" |  | ||||||
| 	"encoding/base64" |  | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
| 	virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1" | 	virtuslabv1alpha1 "github.com/VirtusLab/jenkins-operator/pkg/apis/virtuslab/v1alpha1" | ||||||
|  | @ -44,14 +42,10 @@ func (g *Groovy) ConfigureGroovyJob() error { | ||||||
| 
 | 
 | ||||||
| // EnsureGroovyJob executes groovy script and verifies jenkins job status according to reconciliation loop lifecycle
 | // EnsureGroovyJob executes groovy script and verifies jenkins job status according to reconciliation loop lifecycle
 | ||||||
| // see https://wiki.jenkins.io/display/JENKINS/Jenkins+Script+Console
 | // see https://wiki.jenkins.io/display/JENKINS/Jenkins+Script+Console
 | ||||||
| func (g *Groovy) EnsureGroovyJob(groovyScript string, jenkins *virtuslabv1alpha1.Jenkins) (bool, error) { | func (g *Groovy) EnsureGroovyJob(hash string, jenkins *virtuslabv1alpha1.Jenkins) (bool, error) { | ||||||
| 	jobsClient := jobs.New(g.jenkinsClient, g.k8sClient, g.logger) | 	jobsClient := jobs.New(g.jenkinsClient, g.k8sClient, g.logger) | ||||||
| 
 | 
 | ||||||
| 	hash := sha256.New() | 	done, err := jobsClient.EnsureBuildJob(g.jobName, hash, map[string]string{}, jenkins, true) | ||||||
| 	hash.Write([]byte(groovyScript)) |  | ||||||
| 	encodedHash := base64.URLEncoding.EncodeToString(hash.Sum(nil)) |  | ||||||
| 
 |  | ||||||
| 	done, err := jobsClient.EnsureBuildJob(g.jobName, encodedHash, map[string]string{}, jenkins, true) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return false, err | 		return false, err | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue