Add RBAC for Jenkins master pod

This commit is contained in:
Tomasz Sęk 2019-01-10 16:50:44 +01:00
parent 8d12d9b1fe
commit e313cc2991
No known key found for this signature in database
GPG Key ID: DC356D23F6A644D0
6 changed files with 200 additions and 46 deletions

View File

@ -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:
- "*"

View File

@ -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
} }

View File

@ -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,

View File

@ -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,
},
},
}
}

View File

@ -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,
}
}

View File

@ -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
} }