github.com/caos/orbos@v1.5.14-0.20221103111702-e6cd0cea7ad4/pkg/kubernetes/resources/ambassador/host/adapt.go (about) 1 package host 2 3 import ( 4 "reflect" 5 6 "github.com/caos/orbos/mntr" 7 "github.com/caos/orbos/pkg/kubernetes" 8 "github.com/caos/orbos/pkg/kubernetes/resources" 9 macherrs "k8s.io/apimachinery/pkg/api/errors" 10 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 11 ) 12 13 const ( 14 group = "getambassador.io" 15 version = "v2" 16 kind = "Host" 17 ) 18 19 type Arguments struct { 20 Monitor mntr.Monitor 21 Namespace string 22 Name string 23 Labels map[string]string 24 Hostname string 25 Authority string 26 PrivateKeySecret string 27 Selector map[string]string 28 TlsSecret string 29 } 30 31 //type AdaptFuncToEnsureFunc func(monitor mntr.Monitor, namespace, name string, labels map[string]string, hostname string, authority string, privateKeySecret string, selector map[string]string, tlsSecret string) (resources.QueryFunc, error) 32 33 func AdaptFuncToEnsure(params *Arguments) (resources.QueryFunc, error) { 34 35 labelInterfaceValues := make(map[string]interface{}) 36 for k, v := range params.Labels { 37 labelInterfaceValues[k] = v 38 } 39 40 acme := map[string]interface{}{ 41 "authority": params.Authority, 42 } 43 if params.PrivateKeySecret != "" { 44 acme["privateKeySecret"] = map[string]interface{}{ 45 "name": params.PrivateKeySecret, 46 } 47 } 48 49 selectorInterfaceValues := make(map[string]interface{}, 0) 50 for k, v := range params.Selector { 51 selectorInterfaceValues[k] = v 52 } 53 54 spec := map[string]interface{}{ 55 "hostname": params.Hostname, 56 "selector": map[string]interface{}{ 57 "matchLabels": selectorInterfaceValues, 58 }, 59 "ambassador_id": []interface{}{"default"}, 60 "acmeProvider": acme, 61 } 62 63 if params.TlsSecret != "" { 64 spec["tlsSecret"] = map[string]interface{}{ 65 "name": params.TlsSecret, 66 } 67 } 68 69 crd := &unstructured.Unstructured{ 70 Object: map[string]interface{}{ 71 "kind": kind, 72 "apiVersion": group + "/" + version, 73 "metadata": map[string]interface{}{ 74 "name": params.Name, 75 "namespace": params.Namespace, 76 "labels": labelInterfaceValues, 77 "annotations": map[string]interface{}{ 78 "aes_res_changed": "true", 79 }, 80 }, 81 "spec": spec, 82 }} 83 84 return func(k8sClient kubernetes.ClientInt, _ map[string]interface{}) (resources.EnsureFunc, error) { 85 ensure := func(k8sClient kubernetes.ClientInt) error { 86 return k8sClient.ApplyNamespacedCRDResource(group, version, kind, params.Namespace, params.Name, crd) 87 } 88 crdName := "hosts.getambassador.io" 89 _, ok, err := k8sClient.CheckCRD(crdName) 90 if err != nil { 91 return nil, err 92 } 93 if !ok { 94 params.Monitor.WithField("name", crdName).Info("crd definition not found, skipping") 95 return func(k8sClient kubernetes.ClientInt) error { return nil }, nil 96 } 97 98 existing, err := k8sClient.GetNamespacedCRDResource(group, version, kind, params.Namespace, params.Name) 99 if err != nil && !macherrs.IsNotFound(err) { 100 return nil, err 101 } 102 err = nil 103 104 if existing == nil { 105 return ensure, nil 106 } 107 108 if contains(existing.Object, crd.Object) { 109 // Noop 110 return func(clientInt kubernetes.ClientInt) error { return nil }, nil 111 } 112 113 return ensure, nil 114 }, nil 115 } 116 117 // The order matters!! 118 // TODO: Is this reusable? 119 func contains(set, subset map[string]interface{}) bool { 120 121 if len(set) < len(subset) { 122 return false 123 } 124 125 for k, subsetValue := range subset { 126 setValue, ok := set[k] 127 if !ok { 128 return false 129 } 130 setValueMap, setValueIsMap := setValue.(map[string]interface{}) 131 subsetValueMap, subsetValueIsMap := subsetValue.(map[string]interface{}) 132 if setValueIsMap != subsetValueIsMap { 133 return false 134 } 135 if subsetValueIsMap { 136 if contains(setValueMap, subsetValueMap) { 137 continue 138 } 139 return false 140 } 141 if !reflect.DeepEqual(setValue, subsetValue) { 142 return false 143 } 144 } 145 146 return true 147 } 148 149 func AdaptFuncToDestroy(namespace, name string) (resources.DestroyFunc, error) { 150 return func(client kubernetes.ClientInt) error { 151 return client.DeleteNamespacedCRDResource(group, version, kind, namespace, name) 152 }, nil 153 }