Skip to content

Commit

Permalink
Introdice rolebinding controller to handle rbacs
Browse files Browse the repository at this point in the history
  • Loading branch information
atheo89 committed Oct 28, 2024
1 parent 6e20d78 commit 5cb7687
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 0 deletions.
11 changes: 11 additions & 0 deletions components/odh-notebook-controller/config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,14 @@ rules:
- patch
- update
- watch
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings, roles
verbs:
- create
- get
- list
- patch
- update
- watch
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ type OpenshiftNotebookReconciler struct {
// +kubebuilder:rbac:groups="",resources=services;serviceaccounts;secrets;configmaps,verbs=get;list;watch;create;update;patch
// +kubebuilder:rbac:groups=config.openshift.io,resources=proxies,verbs=get;list;watch
// +kubebuilder:rbac:groups=networking.k8s.io,resources=networkpolicies,verbs=get;list;watch;create;update;patch
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=rolebindings;roles,verbs=get;list;watch;create;update;patch

// CompareNotebooks checks if two notebooks are equal, if not return false.
func CompareNotebooks(nb1 nbv1.Notebook, nb2 nbv1.Notebook) bool {
Expand Down Expand Up @@ -184,6 +185,12 @@ func (r *OpenshiftNotebookReconciler) Reconcile(ctx context.Context, req ctrl.Re
return ctrl.Result{}, err
}

// Call the Rolebinding reconciler
err = r.ReconcileRoleBinding(notebook, ctx)
if err != nil {
return ctrl.Result{}, err
}

if !ServiceMeshIsEnabled(notebook.ObjectMeta) {
// Create the objects required by the OAuth proxy sidecar (see notebook_oauth.go file)
if OAuthInjectionIsEnabled(notebook.ObjectMeta) {
Expand Down
105 changes: 105 additions & 0 deletions components/odh-notebook-controller/controllers/notebook_rbac.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
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 controllers

import (
"context"
"reflect"

nbv1 "github.com/kubeflow/kubeflow/components/notebook-controller/api/v1"
rbacv1 "k8s.io/api/rbac/v1"
apierrs "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)

const (
// ViewRoleBindingName is the name of the role binding that grants view access to the notebook
ViewRoleBindingName = "-view-datasciencecluster"
)

// NewRoleBinding defines the desired role binding object
func NewRoleBinding(notebook *nbv1.Notebook) *rbacv1.RoleBinding {
return &rbacv1.RoleBinding{
ObjectMeta: metav1.ObjectMeta{
Name: notebook.Name + ViewRoleBindingName,
Namespace: notebook.Namespace,
Labels: map[string]string{
"notebook-name": notebook.Name,
},
},
Subjects: []rbacv1.Subject{
{
Kind: "ServiceAccount",
Name: notebook.Name,
Namespace: notebook.Namespace,
},
},
RoleRef: rbacv1.RoleRef{
Kind: "ClusterRole",
Name: "datascienceclusters.datasciencecluster.opendatahub.io-v1-view",
APIGroup: "rbac.authorization.k8s.io",
},
}
}

// reconcileRoleBinding will manage the creation, update and deletion of the
// role binding when the notebook is reconciled
func (r *OpenshiftNotebookReconciler) reconcileRoleBinding(notebook *nbv1.Notebook,
ctx context.Context, newRoleBinding func(notebook *nbv1.Notebook) *rbacv1.RoleBinding) error {
// Initialize the logger
log := r.Log.WithValues("notebook", types.NamespacedName{Name: notebook.Name, Namespace: notebook.Namespace})

// Define a new RoleBinding object
roleBinding := newRoleBinding(notebook)

// Check if the RoleBinding already exists
found := &rbacv1.RoleBinding{}
err := r.Get(ctx, types.NamespacedName{
Name: notebook.Name + ViewRoleBindingName,
Namespace: notebook.Namespace,
}, found)
if err != nil && apierrs.IsNotFound(err) {
log.Info("Creating RoleBinding", "RoleBinding.Namespace", roleBinding.Namespace, "RoleBinding.Name", roleBinding.Name)
err = r.Create(ctx, roleBinding)
if err != nil {
log.Error(err, "Failed to create RoleBinding", "RoleBinding.Namespace", roleBinding.Namespace, "RoleBinding.Name", roleBinding.Name)
return err
}
return nil
} else if err != nil {
log.Error(err, "Failed to get RoleBinding")
return err
}

if !reflect.DeepEqual(roleBinding.Subjects, found.Subjects) {
log.Info("Updating RoleBinding", "RoleBinding.Namespace", roleBinding.Namespace, "RoleBinding.Name", roleBinding.Name)
err = r.Update(ctx, roleBinding)
if err != nil {
log.Error(err, "Failed to update RoleBinding", "RoleBinding.Namespace", roleBinding.Namespace, "RoleBinding.Name", roleBinding.Name)
return err
}
}

return nil
}

// Reconcile will manage the creation, update and deletion of the role binding
// when the notebook is reconciled
func (r *OpenshiftNotebookReconciler) ReconcileRoleBinding(
notebook *nbv1.Notebook, ctx context.Context) error {
return r.reconcileRoleBinding(notebook, ctx, NewRoleBinding)
}

0 comments on commit 5cb7687

Please sign in to comment.