github.com/fabianvf/ocp-release-operator-sdk@v0.0.0-20190426141702-57620ee2f090/pkg/k8sutil/k8sutil.go (about) 1 // Copyright 2018 The Operator-SDK Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package k8sutil 16 17 import ( 18 "context" 19 "fmt" 20 "io/ioutil" 21 "os" 22 "strings" 23 24 corev1 "k8s.io/api/core/v1" 25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 discovery "k8s.io/client-go/discovery" 27 crclient "sigs.k8s.io/controller-runtime/pkg/client" 28 logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" 29 ) 30 31 var log = logf.Log.WithName("k8sutil") 32 33 // GetWatchNamespace returns the namespace the operator should be watching for changes 34 func GetWatchNamespace() (string, error) { 35 ns, found := os.LookupEnv(WatchNamespaceEnvVar) 36 if !found { 37 return "", fmt.Errorf("%s must be set", WatchNamespaceEnvVar) 38 } 39 return ns, nil 40 } 41 42 // errNoNS indicates that a namespace could not be found for the current 43 // environment 44 var ErrNoNamespace = fmt.Errorf("namespace not found for current environment") 45 46 // GetOperatorNamespace returns the namespace the operator should be running in. 47 func GetOperatorNamespace() (string, error) { 48 nsBytes, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace") 49 if err != nil { 50 if os.IsNotExist(err) { 51 return "", ErrNoNamespace 52 } 53 return "", err 54 } 55 ns := strings.TrimSpace(string(nsBytes)) 56 log.V(1).Info("Found namespace", "Namespace", ns) 57 return ns, nil 58 } 59 60 // GetOperatorName return the operator name 61 func GetOperatorName() (string, error) { 62 operatorName, found := os.LookupEnv(OperatorNameEnvVar) 63 if !found { 64 return "", fmt.Errorf("%s must be set", OperatorNameEnvVar) 65 } 66 if len(operatorName) == 0 { 67 return "", fmt.Errorf("%s must not be empty", OperatorNameEnvVar) 68 } 69 return operatorName, nil 70 } 71 72 // ResourceExists returns true if the given resource kind exists 73 // in the given api groupversion 74 func ResourceExists(dc discovery.DiscoveryInterface, apiGroupVersion, kind string) (bool, error) { 75 apiLists, err := dc.ServerResources() 76 if err != nil { 77 return false, err 78 } 79 for _, apiList := range apiLists { 80 if apiList.GroupVersion == apiGroupVersion { 81 for _, r := range apiList.APIResources { 82 if r.Kind == kind { 83 return true, nil 84 } 85 } 86 } 87 } 88 return false, nil 89 } 90 91 // GetPod returns a Pod object that corresponds to the pod in which the code 92 // is currently running. 93 // It expects the environment variable POD_NAME to be set by the downwards API. 94 func GetPod(ctx context.Context, client crclient.Client, ns string) (*corev1.Pod, error) { 95 podName := os.Getenv(PodNameEnvVar) 96 if podName == "" { 97 return nil, fmt.Errorf("required env %s not set, please configure downward API", PodNameEnvVar) 98 } 99 100 log.V(1).Info("Found podname", "Pod.Name", podName) 101 102 pod := &corev1.Pod{ 103 TypeMeta: metav1.TypeMeta{ 104 APIVersion: "v1", 105 Kind: "Pod", 106 }, 107 } 108 key := crclient.ObjectKey{Namespace: ns, Name: podName} 109 err := client.Get(ctx, key, pod) 110 if err != nil { 111 log.Error(err, "Failed to get Pod", "Pod.Namespace", ns, "Pod.Name", podName) 112 return nil, err 113 } 114 115 log.V(1).Info("Found Pod", "Pod.Namespace", ns, "Pod.Name", pod.Name) 116 117 return pod, nil 118 }