github.com/verrazzano/verrazzano@v1.7.0/cluster-operator/controllers/vmc/update_rancher_rolebinding.go (about)

     1  // Copyright (c) 2022, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package vmc
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  
    10  	"github.com/verrazzano/verrazzano/cluster-operator/apis/clusters/v1alpha1"
    11  	vzconst "github.com/verrazzano/verrazzano/pkg/constants"
    12  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    13  	"k8s.io/apimachinery/pkg/runtime/schema"
    14  	"k8s.io/apimachinery/pkg/types"
    15  	"sigs.k8s.io/controller-runtime/pkg/client"
    16  	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
    17  )
    18  
    19  const (
    20  	APIGroupRancherManagement        = "management.cattle.io"
    21  	APIGroupVersionRancherManagement = "v3"
    22  	ClusterRoleTemplateBindingKind   = "ClusterRoleTemplateBinding"
    23  	UserListKind                     = "UserList"
    24  	UserKind                         = "User"
    25  
    26  	ClusterRoleTemplateBindingAttributeClusterName      = "clusterName"
    27  	ClusterRoleTemplateBindingAttributeUserName         = "userName"
    28  	ClusterRoleTemplateBindingAttributeRoleTemplateName = "roleTemplateName"
    29  
    30  	UserUsernameAttribute = "username"
    31  )
    32  
    33  // updateRancherClusterRoleBindingTemplate creates a new ClusterRoleBindingTemplate for the given VMC
    34  // to grant the Verrazzano cluster user the correct permissions on the managed cluster
    35  func (r *VerrazzanoManagedClusterReconciler) updateRancherClusterRoleBindingTemplate(vmc *v1alpha1.VerrazzanoManagedCluster) error {
    36  	if vmc == nil {
    37  		r.log.Debugf("Empty VMC, no ClusterRoleBindingTemplate created")
    38  		return nil
    39  	}
    40  
    41  	clusterID := vmc.Status.RancherRegistration.ClusterID
    42  	if len(clusterID) == 0 {
    43  		r.log.Progressf("Waiting to create ClusterRoleBindingTemplate for cluster %s, Rancher ClusterID not found in the VMC status", vmc.GetName())
    44  		return nil
    45  	}
    46  
    47  	userID, err := r.getVZClusterUserID()
    48  	if err != nil {
    49  		return err
    50  	}
    51  
    52  	name := fmt.Sprintf("crtb-verrazzano-cluster-%s", clusterID)
    53  	nsn := types.NamespacedName{Name: name, Namespace: clusterID}
    54  	resource := unstructured.Unstructured{}
    55  	resource.SetGroupVersionKind(schema.GroupVersionKind{
    56  		Group:   APIGroupRancherManagement,
    57  		Version: APIGroupVersionRancherManagement,
    58  		Kind:    ClusterRoleTemplateBindingKind,
    59  	})
    60  	resource.SetName(nsn.Name)
    61  	resource.SetNamespace(nsn.Namespace)
    62  	_, err = controllerutil.CreateOrUpdate(context.TODO(), r.Client, &resource, func() error {
    63  		data := resource.UnstructuredContent()
    64  		data[ClusterRoleTemplateBindingAttributeClusterName] = clusterID
    65  		data[ClusterRoleTemplateBindingAttributeUserName] = userID
    66  		data[ClusterRoleTemplateBindingAttributeRoleTemplateName] = vzconst.VerrazzanoClusterRancherName
    67  		return nil
    68  	})
    69  	if err != nil {
    70  		return r.log.ErrorfThrottledNewErr("Failed configuring %s %s: %s", ClusterRoleTemplateBindingKind, nsn.Name, err.Error())
    71  	}
    72  	return nil
    73  }
    74  
    75  // getVZClusterUserID returns the Rancher-generated user ID for the Verrazzano cluster user
    76  func (r *VerrazzanoManagedClusterReconciler) getVZClusterUserID() (string, error) {
    77  	usersList := unstructured.UnstructuredList{}
    78  	usersList.SetGroupVersionKind(schema.GroupVersionKind{
    79  		Group:   APIGroupRancherManagement,
    80  		Version: APIGroupVersionRancherManagement,
    81  		Kind:    UserListKind,
    82  	})
    83  	err := r.Client.List(context.TODO(), &usersList, &client.ListOptions{})
    84  	if err != nil {
    85  		return "", r.log.ErrorfNewErr("Failed to list Rancher Users: %v", err)
    86  	}
    87  
    88  	for _, user := range usersList.Items {
    89  		userData := user.UnstructuredContent()
    90  		if userData[UserUsernameAttribute] == vzconst.VerrazzanoClusterRancherUsername {
    91  			return user.GetName(), nil
    92  		}
    93  	}
    94  	return "", r.log.ErrorfNewErr("Failed to find a Rancher user with username %s", vzconst.VerrazzanoClusterRancherUsername)
    95  }