kubernetes-operator/pkg/configuration/base/rbac.go

96 lines
2.5 KiB
Go

package base
import (
"context"
"fmt"
"strings"
"github.com/jenkinsci/kubernetes-operator/pkg/configuration/base/resources"
stackerr "github.com/pkg/errors"
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
)
func (r *JenkinsBaseConfigurationReconciler) createRBAC(meta metav1.ObjectMeta) error {
err := r.createServiceAccount(meta)
if err != nil {
return err
}
role := resources.NewRole(meta)
err = r.CreateOrUpdateResource(role)
if err != nil {
return stackerr.WithStack(err)
}
roleBinding := resources.NewRoleBinding(meta.Name, meta.Namespace, meta.Name, rbacv1.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
Kind: "Role",
Name: meta.Name,
})
err = r.CreateOrUpdateResource(roleBinding)
if err != nil {
return stackerr.WithStack(err)
}
return nil
}
func (r *JenkinsBaseConfigurationReconciler) ensureExtraRBAC(meta metav1.ObjectMeta) error {
var err error
var name string
for _, roleRef := range r.Configuration.Jenkins.Spec.Roles {
name = getExtraRoleBindingName(meta.Name, roleRef)
roleBinding := resources.NewRoleBinding(name, meta.Namespace, meta.Name, roleRef)
err := r.Client.Create(context.TODO(), roleBinding)
if err != nil && errors.IsAlreadyExists(err) {
continue
}
if err != nil {
return stackerr.WithStack(err)
}
}
roleBindings := &rbacv1.RoleBindingList{}
err = r.Client.List(context.TODO(), roleBindings, client.InNamespace(r.Configuration.Jenkins.Namespace))
if err != nil {
return stackerr.WithStack(err)
}
for _, roleBinding := range roleBindings.Items {
if !strings.HasPrefix(roleBinding.Name, getExtraRoleBindingName(meta.Name, rbacv1.RoleRef{Kind: "Role"})) &&
!strings.HasPrefix(roleBinding.Name, getExtraRoleBindingName(meta.Name, rbacv1.RoleRef{Kind: "ClusterRole"})) {
continue
}
found := false
for _, roleRef := range r.Configuration.Jenkins.Spec.Roles {
name = getExtraRoleBindingName(meta.Name, roleRef)
if roleBinding.Name == name {
found = true
continue
}
}
if !found {
r.logger.Info(fmt.Sprintf("Deleting RoleBinding '%s'", roleBinding.Name))
if err = r.Client.Delete(context.TODO(), &roleBinding); err != nil {
return stackerr.WithStack(err)
}
}
}
return nil
}
func getExtraRoleBindingName(serviceAccountName string, roleRef rbacv1.RoleRef) string {
var typeName string
if roleRef.Kind == "ClusterRole" {
typeName = "cr"
} else {
typeName = "r"
}
return fmt.Sprintf("%s-%s-%s", serviceAccountName, typeName, roleRef.Name)
}