github.com/verrazzano/verrazzano@v1.7.0/platform-operator/namespacewatch/rancher_utils.go (about) 1 // Copyright (c) 2023, 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 namespacewatch 5 6 import ( 7 "context" 8 "fmt" 9 "github.com/verrazzano/verrazzano/pkg/k8sutil" 10 "github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/common" 11 "github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/registry" 12 "github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/spi" 13 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 14 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 15 "k8s.io/apimachinery/pkg/runtime/schema" 16 "k8s.io/client-go/dynamic" 17 ) 18 19 const ( 20 RancherProjectIDLabelKey = "field.cattle.io/projectId" 21 ) 22 23 // getRancherProjectList returns the list of Rancher projects 24 func getRancherProjectList(dynClient dynamic.Interface) (*unstructured.UnstructuredList, error) { 25 var rancherProjectList *unstructured.UnstructuredList 26 gvr := GetRancherMgmtAPIGVRForResource("projects") 27 rancherProjectList, err := dynClient.Resource(gvr).List(context.TODO(), metav1.ListOptions{}) 28 if err != nil { 29 return nil, fmt.Errorf("failed to list %s/%s/%s: %v", gvr.Resource, gvr.Group, gvr.Version, err) 30 } 31 return rancherProjectList, nil 32 } 33 34 // getRancherSystemProjectID returns the ID of Rancher system project 35 func (nw *NamespacesWatcher) getRancherSystemProjectID() (string, string, error) { 36 37 isRancherReady, err := nw.IsRancherReady() 38 if err != nil { 39 return "", "", err 40 } 41 if !isRancherReady { 42 nw.log.Debugf("rancher is not enabled or ready") 43 return "", "", nil 44 } 45 dynClient, err := getDynamicClient() 46 if err != nil { 47 return "", "", err 48 } 49 rancherProjectList, err := getRancherProjectList(dynClient) 50 if err != nil { 51 return "", "", err 52 } 53 var projectID string 54 for _, rancherProject := range rancherProjectList.Items { 55 projectName := rancherProject.UnstructuredContent()["spec"].(map[string]interface{})["displayName"].(string) 56 clusterName := rancherProject.UnstructuredContent()["spec"].(map[string]interface{})["clusterName"].(string) 57 if projectName == "System" { 58 projectID = rancherProject.UnstructuredContent()["metadata"].(map[string]interface{})["name"].(string) 59 return clusterName, projectID, nil 60 } 61 } 62 return "", "", nil 63 } 64 65 // GetRancherMgmtAPIGVRForResource returns a management.cattle.io/v3 GroupVersionResource structure for specified kind 66 func GetRancherMgmtAPIGVRForResource(resource string) schema.GroupVersionResource { 67 return schema.GroupVersionResource{ 68 Group: common.APIGroupRancherManagement, 69 Version: common.APIGroupVersionRancherManagement, 70 Resource: resource, 71 } 72 } 73 74 // GetDynamicClient returns a dynamic client needed to access Unstructured data 75 func getDynamicClient() (dynamic.Interface, error) { 76 config, err := k8sutil.GetConfigFromController() 77 if err != nil { 78 return nil, err 79 } 80 dynamicClient, err := dynamic.NewForConfig(config) 81 if err != nil { 82 return nil, err 83 } 84 return dynamicClient, nil 85 } 86 87 func (nw *NamespacesWatcher) IsRancherReady() (bool, error) { 88 vz, err := getVerrazzanoResource(nw.client) 89 if err != nil { 90 return false, fmt.Errorf("failed to get Verrazzano resource: %v", err) 91 } 92 93 logger, err := newLogger(vz) 94 if err != nil { 95 return false, fmt.Errorf("failed to get Verrazzano resource logger: %v", err) 96 } 97 ctx, err := spi.NewContext(logger, nw.client, vz, nil, true) 98 if err != nil { 99 return false, fmt.Errorf("error creating a component context %v", err) 100 } 101 _, rancherComponent := registry.FindComponent(common.RancherName) 102 isEnabled := rancherComponent.IsEnabled(ctx.EffectiveCR()) 103 return isEnabled && rancherComponent.IsReady(ctx), nil 104 }