github.com/tickoalcantara12/micro/v3@v3.0.0-20221007104245-9d75b9bcbab9/service/runtime/kubernetes/namespace.go (about) 1 // Licensed under the Apache License, Version 2.0 (the "License"); 2 // you may not use this file except in compliance with the License. 3 // You may obtain a copy of the License at 4 // 5 // https://www.apache.org/licenses/LICENSE-2.0 6 // 7 // Unless required by applicable law or agreed to in writing, software 8 // distributed under the License is distributed on an "AS IS" BASIS, 9 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 10 // See the License for the specific language governing permissions and 11 // limitations under the License. 12 // 13 // Original source: github.com/micro/go-micro/v3/runtime/kubernetes/namespace.go 14 15 package kubernetes 16 17 import ( 18 "strings" 19 20 "github.com/tickoalcantara12/micro/v3/service/logger" 21 "github.com/tickoalcantara12/micro/v3/service/runtime" 22 "github.com/tickoalcantara12/micro/v3/service/runtime/kubernetes/client" 23 ) 24 25 func (k *kubernetes) ensureNamepaceExists(ns string) error { 26 namespace := client.Format(ns) 27 if namespace == client.DefaultNamespace { 28 return nil 29 } 30 31 exist, err := k.namespaceExists(namespace) 32 if err == nil && exist { 33 return nil 34 } 35 if err != nil { 36 if logger.V(logger.WarnLevel, logger.DefaultLogger) { 37 logger.Warnf("Error checking namespace %v exists: %v", namespace, err) 38 } 39 return err 40 } 41 42 if err := k.autoCreateNamespace(namespace); err != nil { 43 if logger.V(logger.WarnLevel, logger.DefaultLogger) { 44 logger.Warnf("Error creating namespace %v: %v", namespace, err) 45 } 46 return err 47 } 48 49 return nil 50 } 51 52 // namespaceExists returns a boolean indicating if a namespace exists in the cache 53 func (k *kubernetes) namespaceExists(name string) (bool, error) { 54 // populate the cache 55 if k.namespaces == nil { 56 if logger.V(logger.DebugLevel, logger.DefaultLogger) { 57 logger.Debugf("Populating namespace cache") 58 } 59 60 namespaceList := new(client.NamespaceList) 61 resource := &client.Resource{Kind: "namespace", Value: namespaceList} 62 if err := k.client.List(resource); err != nil { 63 return false, err 64 } 65 66 if logger.V(logger.DebugLevel, logger.DefaultLogger) { 67 logger.Debugf("Populated namespace cache successfully with %v items", len(namespaceList.Items)) 68 } 69 k.namespaces = namespaceList.Items 70 } 71 72 // check if the namespace exists in the cache 73 for _, n := range k.namespaces { 74 if n.Metadata.Name == name { 75 return true, nil 76 } 77 } 78 79 return false, nil 80 } 81 82 // autoCreateNamespace creates a new k8s namespace 83 func (k *kubernetes) autoCreateNamespace(namespace string) error { 84 ns := client.Namespace{Metadata: &client.Metadata{Name: namespace}} 85 err := k.client.Create(&client.Resource{Kind: "namespace", Value: ns}) 86 87 // ignore err already exists 88 if err != nil && strings.Contains(err.Error(), "already exists") { 89 logger.Debugf("Ignoring ErrAlreadyExists for namespace %v: %v", namespace, err) 90 err = nil 91 } 92 93 // add to cache and create networkpolicy 94 if err == nil && k.namespaces != nil { 95 k.namespaces = append(k.namespaces, ns) 96 } 97 98 return err 99 } 100 101 // createNamespace creates a namespace resource 102 func (k *kubernetes) createNamespace(namespace *runtime.Namespace) error { 103 err := k.client.Create(&client.Resource{ 104 Kind: "namespace", 105 Name: namespace.Name, 106 Value: &client.Namespace{ 107 Metadata: &client.Metadata{ 108 Name: namespace.Name, 109 }, 110 }, 111 }, client.CreateNamespace(namespace.Name)) 112 if err != nil { 113 if logger.V(logger.ErrorLevel, logger.DefaultLogger) { 114 logger.Errorf("Error creating namespace %s: %v", namespace.String(), err) 115 } 116 } 117 return err 118 } 119 120 // deleteNamespace deletes a namespace resource 121 func (k *kubernetes) deleteNamespace(namespace *runtime.Namespace) error { 122 err := k.client.Delete(&client.Resource{ 123 Kind: "namespace", 124 Name: namespace.Name, 125 Value: &client.Namespace{ 126 Metadata: &client.Metadata{ 127 Name: namespace.Name, 128 }, 129 }, 130 }, client.DeleteNamespace(namespace.Name)) 131 if err != nil { 132 if logger.V(logger.ErrorLevel, logger.DefaultLogger) { 133 logger.Errorf("Error deleting namespace %s: %v", namespace.String(), err) 134 } 135 } 136 return err 137 }