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 }