github.com/splunk/dan1-qbec@v0.7.3/internal/remote/collection.go (about) 1 /* 2 Copyright 2019 Splunk Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package remote 18 19 import ( 20 "fmt" 21 22 "github.com/splunk/qbec/internal/model" 23 "k8s.io/apimachinery/pkg/runtime/schema" 24 ) 25 26 type objectKey struct { 27 gvk schema.GroupVersionKind 28 namespace string 29 name string 30 } 31 32 func (o objectKey) GroupVersionKind() schema.GroupVersionKind { return o.gvk } 33 func (o objectKey) GetKind() string { return o.gvk.Kind } 34 func (o objectKey) GetNamespace() string { return o.namespace } 35 func (o objectKey) GetName() string { return o.name } 36 37 type basicObject struct { 38 objectKey 39 app string 40 tag string 41 component string 42 env string 43 } 44 45 func (b *basicObject) Application() string { return b.app } 46 func (b *basicObject) Tag() string { return b.tag } 47 func (b *basicObject) Component() string { return b.component } 48 func (b *basicObject) Environment() string { return b.env } 49 func (b *basicObject) GetGenerateName() string { return "" } 50 51 type collectMetadata interface { 52 objectNamespace(obj model.K8sMeta) string 53 canonicalGroupVersionKind(in schema.GroupVersionKind) (schema.GroupVersionKind, error) 54 } 55 56 type collection struct { 57 defaultNs string 58 meta collectMetadata 59 objects map[objectKey]model.K8sQbecMeta 60 } 61 62 func newCollection(defaultNs string, meta collectMetadata) *collection { 63 if defaultNs == "" { 64 defaultNs = "default" 65 } 66 return &collection{ 67 defaultNs: defaultNs, 68 meta: meta, 69 objects: map[objectKey]model.K8sQbecMeta{}, 70 } 71 } 72 73 // add adds the supplied object potentially transforming its gvk to its canonical form. 74 func (c *collection) add(object model.K8sQbecMeta) error { 75 gvk := object.GroupVersionKind() 76 canonicalGVK, err := c.meta.canonicalGroupVersionKind(gvk) 77 if err != nil { 78 return err 79 } 80 if object.GetName() == "" { 81 return fmt.Errorf("internal error: object %v did not have a name", object) 82 } 83 ns := c.meta.objectNamespace(object) 84 key := objectKey{ 85 gvk: canonicalGVK, 86 namespace: ns, 87 name: object.GetName(), 88 } 89 resultObject := &basicObject{ 90 objectKey: key, 91 app: object.Application(), 92 tag: object.Tag(), 93 component: object.Component(), 94 env: object.Environment(), 95 } 96 c.objects[key] = resultObject 97 return nil 98 } 99 100 // Remove removes objects from its internal collection for each 101 // matching object supplied. 102 func (c *collection) Remove(objs []model.K8sQbecMeta) error { 103 sub := newCollection(c.defaultNs, c.meta) 104 for _, o := range objs { 105 if err := sub.add(o); err != nil { 106 return err 107 } 108 } 109 retainedSet := map[objectKey]model.K8sQbecMeta{} 110 for k, v := range c.objects { 111 if _, ok := sub.objects[k]; !ok { 112 retainedSet[k] = v 113 } 114 } 115 c.objects = retainedSet 116 return nil 117 } 118 119 // ToList returns the list of objects in this collection in arbitrary order. 120 func (c *collection) ToList() []model.K8sQbecMeta { 121 var ret []model.K8sQbecMeta 122 for _, v := range c.objects { 123 ret = append(ret, v) 124 } 125 return ret 126 }