github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/manager/resources/rolebinding/manager.go (about)

     1  /*
     2   * Copyright contributors to the Hyperledger Fabric Operator project
     3   *
     4   * SPDX-License-Identifier: Apache-2.0
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at:
     9   *
    10   * 	  http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package rolebinding
    20  
    21  import (
    22  	"context"
    23  	"fmt"
    24  
    25  	k8sclient "github.com/IBM-Blockchain/fabric-operator/pkg/k8s/controllerclient"
    26  	"github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources"
    27  	"github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources/role"
    28  	"github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources/serviceaccount"
    29  	"github.com/IBM-Blockchain/fabric-operator/pkg/operatorerrors"
    30  	"github.com/IBM-Blockchain/fabric-operator/pkg/util"
    31  	rbacv1 "k8s.io/api/rbac/v1"
    32  	k8serrors "k8s.io/apimachinery/pkg/api/errors"
    33  	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    34  	"k8s.io/apimachinery/pkg/runtime"
    35  	"k8s.io/apimachinery/pkg/types"
    36  	"sigs.k8s.io/controller-runtime/pkg/client"
    37  	logf "sigs.k8s.io/controller-runtime/pkg/log"
    38  )
    39  
    40  var log = logf.Log.WithName("rolebinding_manager")
    41  
    42  type Manager struct {
    43  	Client          k8sclient.Client
    44  	Scheme          *runtime.Scheme
    45  	RoleBindingFile string
    46  	Name            string
    47  
    48  	LabelsFunc   func(v1.Object) map[string]string
    49  	OverrideFunc func(v1.Object, *rbacv1.RoleBinding, resources.Action) error
    50  }
    51  
    52  func (m *Manager) GetName(instance v1.Object) string {
    53  	if m.Name != "" {
    54  		return fmt.Sprintf("%s-%s-rolebinding", instance.GetName(), m.Name)
    55  	}
    56  	return fmt.Sprintf("%s-rolebinding", instance.GetName())
    57  }
    58  
    59  func (m *Manager) Reconcile(instance v1.Object, update bool) error {
    60  	name := m.GetName(instance)
    61  	err := m.Client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: instance.GetNamespace()}, &rbacv1.RoleBinding{})
    62  	if err != nil {
    63  		if k8serrors.IsNotFound(err) {
    64  			log.Info(fmt.Sprintf("Creating role binding '%s'", name))
    65  			roleBinding, err := m.GetRoleBindingBasedOnCRFromFile(instance)
    66  			if err != nil {
    67  				return err
    68  			}
    69  
    70  			err = m.Client.Create(context.TODO(), roleBinding, k8sclient.CreateOption{Owner: instance, Scheme: m.Scheme})
    71  			if err != nil {
    72  				return err
    73  			}
    74  			return nil
    75  		}
    76  		return err
    77  	}
    78  
    79  	// TODO: If needed, update logic for servie goes here
    80  
    81  	return nil
    82  }
    83  
    84  func (m *Manager) GetRoleBindingBasedOnCRFromFile(instance v1.Object) (*rbacv1.RoleBinding, error) {
    85  	roleBinding, err := util.GetRoleBindingFromFile(m.RoleBindingFile)
    86  	if err != nil {
    87  		log.Error(err, fmt.Sprintf("Error reading role binding configuration file: %s", m.RoleBindingFile))
    88  		return nil, err
    89  	}
    90  
    91  	name := m.GetName(instance)
    92  	roleBinding.Name = name
    93  	roleBinding.RoleRef.Name = role.GetName(instance.GetName())
    94  	roleBinding.Namespace = instance.GetNamespace()
    95  	roleBinding.Labels = m.LabelsFunc(instance)
    96  	roleBinding.Subjects[0].Name = serviceaccount.GetName(instance.GetName())
    97  	roleBinding.Subjects[0].Namespace = instance.GetNamespace()
    98  
    99  	return m.BasedOnCR(instance, roleBinding)
   100  }
   101  
   102  func (m *Manager) BasedOnCR(instance v1.Object, roleBinding *rbacv1.RoleBinding) (*rbacv1.RoleBinding, error) {
   103  	if m.OverrideFunc != nil {
   104  		err := m.OverrideFunc(instance, roleBinding, resources.Create)
   105  		if err != nil {
   106  			return nil, operatorerrors.New(operatorerrors.InvalidRoleBindingCreateRequest, err.Error())
   107  		}
   108  	}
   109  
   110  	return roleBinding, nil
   111  }
   112  
   113  func (m *Manager) Get(instance v1.Object) (client.Object, error) {
   114  	if instance == nil {
   115  		return nil, nil // Instance has not been reconciled yet
   116  	}
   117  
   118  	name := m.GetName(instance)
   119  	rb := &rbacv1.RoleBinding{}
   120  	err := m.Client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: instance.GetNamespace()}, rb)
   121  	if err != nil {
   122  		return nil, err
   123  	}
   124  
   125  	return rb, nil
   126  }
   127  
   128  func (m *Manager) Exists(instance v1.Object) bool {
   129  	_, err := m.Get(instance)
   130  	if err != nil {
   131  		return false
   132  	}
   133  
   134  	return true
   135  }
   136  
   137  func (m *Manager) Delete(instance v1.Object) error {
   138  	rb, err := m.Get(instance)
   139  	if err != nil {
   140  		if !k8serrors.IsNotFound(err) {
   141  			return err
   142  		}
   143  	}
   144  
   145  	if rb == nil {
   146  		return nil
   147  	}
   148  
   149  	err = m.Client.Delete(context.TODO(), rb)
   150  	if err != nil {
   151  		if !k8serrors.IsNotFound(err) {
   152  			return err
   153  		}
   154  	}
   155  
   156  	return nil
   157  }
   158  
   159  func (m *Manager) CheckState(instance v1.Object) error {
   160  	// NO-OP
   161  	return nil
   162  }
   163  
   164  func (m *Manager) RestoreState(instance v1.Object) error {
   165  	// NO-OP
   166  	return nil
   167  }
   168  
   169  func (m *Manager) SetCustomName(name string) {
   170  	// NO-OP
   171  }