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  }