...

Source file src/github.com/fluxcd/kustomize-controller/api/v1beta1/snapshot_types.go

Documentation: github.com/fluxcd/kustomize-controller/api/v1beta1

     1  /*
     2  Copyright 2020 The Flux authors
     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 v1beta1
    18  
    19  import (
    20  	"bytes"
    21  	"io"
    22  	"strings"
    23  
    24  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    25  	"k8s.io/apimachinery/pkg/runtime"
    26  	"k8s.io/apimachinery/pkg/runtime/schema"
    27  	"k8s.io/apimachinery/pkg/util/yaml"
    28  )
    29  
    30  // Snapshot holds the metadata of the Kubernetes objects
    31  // generated for a source revision
    32  type Snapshot struct {
    33  	// The manifests sha1 checksum.
    34  	// +required
    35  	Checksum string `json:"checksum"`
    36  
    37  	// A list of Kubernetes kinds grouped by namespace.
    38  	// +required
    39  	Entries []SnapshotEntry `json:"entries"`
    40  }
    41  
    42  // Snapshot holds the metadata of namespaced
    43  // Kubernetes objects
    44  type SnapshotEntry struct {
    45  	// The namespace of this entry.
    46  	// +optional
    47  	Namespace string `json:"namespace"`
    48  
    49  	// The list of Kubernetes kinds.
    50  	// +required
    51  	Kinds map[string]string `json:"kinds"`
    52  }
    53  
    54  func NewSnapshot(manifests []byte, checksum string) (*Snapshot, error) {
    55  	snapshot := Snapshot{
    56  		Checksum: checksum,
    57  		Entries:  []SnapshotEntry{},
    58  	}
    59  
    60  	reader := yaml.NewYAMLOrJSONDecoder(bytes.NewReader(manifests), 2048)
    61  	for {
    62  		var obj unstructured.Unstructured
    63  		err := reader.Decode(&obj)
    64  		if err == io.EOF {
    65  			break
    66  		} else if err != nil {
    67  			return nil, err
    68  		}
    69  		if obj.IsList() {
    70  			err := obj.EachListItem(func(item runtime.Object) error {
    71  				snapshot.addEntry(item.(*unstructured.Unstructured))
    72  				return nil
    73  			})
    74  			if err != nil {
    75  				return nil, err
    76  			}
    77  		} else {
    78  			snapshot.addEntry(&obj)
    79  		}
    80  	}
    81  
    82  	return &snapshot, nil
    83  }
    84  
    85  func (s *Snapshot) addEntry(item *unstructured.Unstructured) {
    86  	found := false
    87  	for _, tracker := range s.Entries {
    88  		if tracker.Namespace == item.GetNamespace() {
    89  			tracker.Kinds[item.GroupVersionKind().String()] = item.GetKind()
    90  			found = true
    91  			break
    92  		}
    93  	}
    94  	if !found {
    95  		s.Entries = append(s.Entries, SnapshotEntry{
    96  			Namespace: item.GetNamespace(),
    97  			Kinds: map[string]string{
    98  				item.GroupVersionKind().String(): item.GetKind(),
    99  			},
   100  		})
   101  	}
   102  }
   103  
   104  func (s *Snapshot) NonNamespacedKinds() []schema.GroupVersionKind {
   105  	kinds := make([]schema.GroupVersionKind, 0)
   106  
   107  	for _, tracker := range s.Entries {
   108  		if tracker.Namespace == "" {
   109  			for gvk, kind := range tracker.Kinds {
   110  				if strings.Contains(gvk, ",") {
   111  					gv, err := schema.ParseGroupVersion(strings.Split(gvk, ",")[0])
   112  					if err == nil {
   113  						kinds = append(kinds, gv.WithKind(kind))
   114  					}
   115  				}
   116  			}
   117  		}
   118  	}
   119  	return kinds
   120  }
   121  
   122  func (s *Snapshot) NamespacedKinds() map[string][]schema.GroupVersionKind {
   123  	nsk := make(map[string][]schema.GroupVersionKind)
   124  	for _, tracker := range s.Entries {
   125  		if tracker.Namespace != "" {
   126  			var kinds []schema.GroupVersionKind
   127  			for gvk, kind := range tracker.Kinds {
   128  				if strings.Contains(gvk, ",") {
   129  					gv, err := schema.ParseGroupVersion(strings.Split(gvk, ",")[0])
   130  					if err == nil {
   131  						kinds = append(kinds, gv.WithKind(kind))
   132  					}
   133  				}
   134  			}
   135  			nsk[tracker.Namespace] = kinds
   136  		}
   137  	}
   138  	return nsk
   139  }
   140  

View as plain text