...
1
16
17 package set
18
19 import (
20 "strings"
21
22 "k8s.io/api/core/v1"
23 "k8s.io/apimachinery/pkg/runtime"
24 "k8s.io/apimachinery/pkg/util/sets"
25 "k8s.io/apimachinery/pkg/util/strategicpatch"
26 "k8s.io/cli-runtime/pkg/resource"
27 )
28
29
30 func selectContainers(containers []v1.Container, spec string) ([]*v1.Container, []*v1.Container) {
31 out := []*v1.Container{}
32 skipped := []*v1.Container{}
33 for i, c := range containers {
34 if selectString(c.Name, spec) {
35 out = append(out, &containers[i])
36 } else {
37 skipped = append(skipped, &containers[i])
38 }
39 }
40 return out, skipped
41 }
42
43
44
45
46 func selectString(s, spec string) bool {
47 if spec == "*" {
48 return true
49 }
50 if !strings.Contains(spec, "*") {
51 return s == spec
52 }
53
54 pos := 0
55 match := true
56 parts := strings.Split(spec, "*")
57 Loop:
58 for i, part := range parts {
59 if len(part) == 0 {
60 continue
61 }
62 next := strings.Index(s[pos:], part)
63 switch {
64
65 case next < pos:
66 fallthrough
67
68 case i == 0 && pos != 0:
69 fallthrough
70
71 case i == (len(parts)-1) && len(s) != (len(part)+next):
72 match = false
73 break Loop
74 default:
75 pos = next
76 }
77 }
78 return match
79 }
80
81
82 type Patch struct {
83 Info *resource.Info
84 Err error
85
86 Before []byte
87 After []byte
88 Patch []byte
89 }
90
91
92
93 type PatchFn func(runtime.Object) ([]byte, error)
94
95
96
97
98 func CalculatePatch(patch *Patch, encoder runtime.Encoder, mutateFn PatchFn) bool {
99 patch.Before, patch.Err = runtime.Encode(encoder, patch.Info.Object)
100 patch.After, patch.Err = mutateFn(patch.Info.Object)
101 if patch.Err != nil {
102 return true
103 }
104 if patch.After == nil {
105 return false
106 }
107
108 patch.Patch, patch.Err = strategicpatch.CreateTwoWayMergePatch(patch.Before, patch.After, patch.Info.Object)
109 return true
110 }
111
112
113
114 func CalculatePatches(infos []*resource.Info, encoder runtime.Encoder, mutateFn PatchFn) []*Patch {
115 var patches []*Patch
116 for _, info := range infos {
117 patch := &Patch{Info: info}
118 if CalculatePatch(patch, encoder, mutateFn) {
119 patches = append(patches, patch)
120 }
121 }
122 return patches
123 }
124
125 func findEnv(env []v1.EnvVar, name string) (v1.EnvVar, bool) {
126 for _, e := range env {
127 if e.Name == name {
128 return e, true
129 }
130 }
131 return v1.EnvVar{}, false
132 }
133
134
135
136
137
138
139
140 func updateEnv(existing []v1.EnvVar, env []v1.EnvVar, remove []string) []v1.EnvVar {
141 out := []v1.EnvVar{}
142 covered := sets.NewString(remove...)
143 for _, e := range existing {
144 if covered.Has(e.Name) {
145 continue
146 }
147 newer, ok := findEnv(env, e.Name)
148 if ok {
149 covered.Insert(e.Name)
150 out = append(out, newer)
151 continue
152 }
153 out = append(out, e)
154 }
155 for _, e := range env {
156 if covered.Has(e.Name) {
157 continue
158 }
159 covered.Insert(e.Name)
160 out = append(out, e)
161 }
162 return out
163 }
164
View as plain text