...
1
2
3
4 package manifestreader
5
6 import (
7 "encoding/json"
8 "errors"
9 "fmt"
10 "strings"
11
12 "k8s.io/apimachinery/pkg/api/meta"
13 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
14 "k8s.io/apimachinery/pkg/runtime/schema"
15 "sigs.k8s.io/cli-utils/pkg/inventory"
16 "sigs.k8s.io/cli-utils/pkg/object"
17 "sigs.k8s.io/kustomize/kyaml/kio/filters"
18 "sigs.k8s.io/kustomize/kyaml/kio/kioutil"
19 "sigs.k8s.io/kustomize/kyaml/yaml"
20 )
21
22
23 type UnknownTypesError struct {
24 GroupVersionKinds []schema.GroupVersionKind
25 }
26
27 func (e *UnknownTypesError) Error() string {
28 var gvks []string
29 for _, gvk := range e.GroupVersionKinds {
30 gvks = append(gvks, fmt.Sprintf("%s/%s/%s",
31 gvk.Group, gvk.Version, gvk.Kind))
32 }
33 return fmt.Sprintf("unknown resource types: %s", strings.Join(gvks, ","))
34 }
35
36
37
38 type NamespaceMismatchError struct {
39 RequiredNamespace string
40 Namespace string
41 }
42
43 func (e *NamespaceMismatchError) Error() string {
44 return fmt.Sprintf("found namespace %q, but all resources must be in namespace %q",
45 e.Namespace, e.RequiredNamespace)
46 }
47
48
49
50
51
52
53
54
55 func SetNamespaces(mapper meta.RESTMapper, objs []*unstructured.Unstructured,
56 defaultNamespace string, enforceNamespace bool) error {
57 var crdObjs []*unstructured.Unstructured
58
59
60 for _, obj := range objs {
61 if object.IsCRD(obj) {
62 crdObjs = append(crdObjs, obj)
63 }
64 }
65
66 var unknownGVKs []schema.GroupVersionKind
67 for _, obj := range objs {
68
69
70 if inventory.IsInventoryObject(obj) {
71 continue
72 }
73
74
75
76 scope, err := object.LookupResourceScope(obj, crdObjs, mapper)
77 if err != nil {
78 var unknownTypeError *object.UnknownTypeError
79 if errors.As(err, &unknownTypeError) {
80
81
82 unknownGVKs = append(unknownGVKs, unknownTypeError.GroupVersionKind)
83 continue
84 } else {
85
86
87 return err
88 }
89 }
90
91 switch scope {
92 case meta.RESTScopeNamespace:
93 if obj.GetNamespace() == "" {
94 obj.SetNamespace(defaultNamespace)
95 } else {
96 ns := obj.GetNamespace()
97 if enforceNamespace && ns != defaultNamespace {
98 return &NamespaceMismatchError{
99 Namespace: ns,
100 RequiredNamespace: defaultNamespace,
101 }
102 }
103 }
104 case meta.RESTScopeRoot:
105 if ns := obj.GetNamespace(); ns != "" {
106 return fmt.Errorf("resource is cluster-scoped but has a non-empty namespace %q", ns)
107 }
108 default:
109 return fmt.Errorf("unknown RESTScope %q", scope.Name())
110 }
111 }
112 if len(unknownGVKs) > 0 {
113 return &UnknownTypesError{
114 GroupVersionKinds: unknownGVKs,
115 }
116 }
117 return nil
118 }
119
120
121
122 func FilterLocalConfig(objs []*unstructured.Unstructured) []*unstructured.Unstructured {
123 var filteredObjs []*unstructured.Unstructured
124 for _, obj := range objs {
125
126
127
128 if _, found := obj.GetAnnotations()[filters.LocalConfigAnnotation]; !found {
129 filteredObjs = append(filteredObjs, obj)
130 }
131 }
132 return filteredObjs
133 }
134
135
136 func RemoveAnnotations(n *yaml.RNode, annotations ...kioutil.AnnotationKey) error {
137 for _, a := range annotations {
138 err := n.PipeE(yaml.ClearAnnotation(a))
139 if err != nil {
140 return err
141 }
142 }
143 return nil
144 }
145
146
147
148 func KyamlNodeToUnstructured(n *yaml.RNode) (*unstructured.Unstructured, error) {
149 b, err := n.MarshalJSON()
150 if err != nil {
151 return nil, err
152 }
153
154 var m map[string]interface{}
155 err = json.Unmarshal(b, &m)
156 if err != nil {
157 return nil, err
158 }
159
160 return &unstructured.Unstructured{
161 Object: m,
162 }, nil
163 }
164
View as plain text