1 package kustomization
2
3 import (
4 "fmt"
5
6 "github.com/thoas/go-funk"
7 "sigs.k8s.io/controller-runtime/pkg/client"
8
9 clusterApi "edge-infra.dev/pkg/edge/apis/cluster/v1alpha1"
10 "edge-infra.dev/pkg/edge/constants"
11 "edge-infra.dev/pkg/edge/constants/api/cluster"
12 "edge-infra.dev/pkg/edge/constants/api/fleet"
13 "edge-infra.dev/pkg/edge/flux/bootstrap"
14 )
15
16 const (
17
18 ForemanBucketName = "bucket"
19
20 BannerInfraBucketName = "banner-infra-sync"
21 )
22
23 var (
24 warehouseKustomizations = []*Kustomizations{
25 {
26 Name: "shipments",
27 Namespace: constants.FluxEdgeNamespace,
28 Path: constants.ShipmentKustomizationDir,
29 Prune: false,
30 Force: false,
31 SupportedFleet: fleet.Types,
32 SupportedCluster: cluster.Types,
33 OverrideSyncSuffix: false,
34 },
35 {
36 Name: "chariot",
37 Namespace: constants.FluxEdgeNamespace,
38 Path: "chariot",
39 Prune: true,
40 Force: true,
41 SupportedFleet: fleet.Types,
42 SupportedCluster: cluster.Types,
43 OverrideSyncSuffix: false,
44 },
45 }
46 defaultKustomizations = []*Kustomizations{
47 {
48 Name: "chariot",
49 Namespace: constants.FluxEdgeNamespace,
50 Path: "chariot",
51 Prune: true,
52 Force: true,
53 SupportedFleet: fleet.Types,
54 SupportedCluster: cluster.Types,
55 OverrideSyncSuffix: false,
56 },
57 {
58 Name: "cluster",
59 Namespace: constants.FluxEdgeNamespace,
60 Path: "hydrated/cluster",
61 Prune: false,
62 Force: true,
63 SupportedFleet: fleet.Types,
64 SupportedCluster: cluster.Types,
65 OverrideSyncSuffix: false,
66 },
67 {
68 Name: "namespaces",
69 Namespace: constants.FluxEdgeNamespace,
70 Path: "hydrated/namespaces",
71 Prune: false,
72 Force: true,
73 SupportedFleet: fleet.Types,
74 SupportedCluster: cluster.Types,
75 OverrideSyncSuffix: false,
76 },
77 {
78 Name: "cert-manager",
79 Namespace: constants.FluxEdgeNamespace,
80 Path: "hydrated/cert-manager",
81 Prune: false,
82 Force: true,
83 SupportedFleet: fleet.Types,
84 SupportedCluster: cluster.Types,
85 OverrideSyncSuffix: false,
86 },
87 {
88 Name: "external-secrets",
89 Namespace: constants.FluxEdgeNamespace,
90 Path: "hydrated/external-secrets",
91 Prune: false,
92 Force: true,
93 SupportedFleet: fleet.Types,
94 SupportedCluster: cluster.Types,
95 OverrideSyncSuffix: false,
96 },
97 {
98 Name: "gatekeeper-constraints",
99 Namespace: constants.FluxEdgeNamespace,
100 Path: "hydrated/gatekeeper-policies/constraints",
101 Prune: false,
102 Force: true,
103 SupportedFleet: []fleet.Type{fleet.Store, fleet.BasicStore, fleet.CouchDB, fleet.Cluster},
104 SupportedCluster: []cluster.Type{cluster.GKE},
105 OverrideSyncSuffix: false,
106 },
107 {
108 Name: "gatekeeper-constraint-templates",
109 Namespace: constants.FluxEdgeNamespace,
110 Path: "hydrated/gatekeeper-policies/constraint-templates",
111 Prune: false,
112 Force: true,
113 SupportedFleet: []fleet.Type{fleet.Store, fleet.BasicStore, fleet.CouchDB, fleet.Cluster},
114 SupportedCluster: []cluster.Type{cluster.GKE},
115 OverrideSyncSuffix: false,
116 },
117 {
118 Name: "gatekeeper-system",
119 Namespace: constants.FluxEdgeNamespace,
120 Path: "hydrated/gatekeeper-system",
121 Prune: false,
122 Force: true,
123 SupportedFleet: []fleet.Type{fleet.Store, fleet.BasicStore, fleet.CouchDB, fleet.Cluster},
124 SupportedCluster: []cluster.Type{cluster.GKE},
125 OverrideSyncSuffix: false,
126 },
127 {
128 Name: "flux-system",
129 Namespace: constants.FluxEdgeNamespace,
130 Path: "hydrated/flux-system",
131 Prune: false,
132 Force: true,
133 SupportedFleet: fleet.Types,
134 SupportedCluster: cluster.Types,
135 OverrideSyncSuffix: false,
136 },
137 {
138 Name: "redpanda",
139 Namespace: constants.FluxEdgeNamespace,
140 Path: "hydrated/redpanda",
141 Prune: false,
142 Force: true,
143 SupportedFleet: []fleet.Type{fleet.Store},
144 SupportedCluster: cluster.Types,
145 OverrideSyncSuffix: false,
146 },
147 {
148 Name: "k8s-config-connector",
149 Namespace: constants.FluxEdgeNamespace,
150 Path: "hydrated/k8s-config-connector",
151 Prune: false,
152 Force: true,
153 SupportedFleet: []fleet.Type{fleet.Cluster, fleet.Banner},
154 SupportedCluster: cluster.Types,
155 OverrideSyncSuffix: false,
156 },
157 {
158 Name: "banner-infra",
159 Namespace: constants.FluxEdgeNamespace,
160 Path: "hydrated/fluxcfg",
161 Prune: false,
162 Force: true,
163 SupportedFleet: []fleet.Type{fleet.Banner},
164 SupportedCluster: cluster.Types,
165 OverrideSyncSuffix: false,
166 OverridePath: true,
167 },
168 {
169 Name: "sds",
170 Namespace: constants.FluxEdgeNamespace,
171 Path: "hydrated/sds",
172 Prune: true,
173 Force: true,
174 SupportedFleet: []fleet.Type{fleet.Store},
175 SupportedCluster: []cluster.Type{cluster.DSDS},
176 OverrideSyncSuffix: false,
177 },
178 }
179 )
180
181
182 type EdgeKustomizations struct {
183
184 Cluster *clusterApi.Cluster
185
186 BucketName string
187 BucketNamespace string
188
189 Rules []*Kustomizations
190 Annotations map[string]string
191 StoreVersion string
192 }
193
194
195 type Kustomizations struct {
196 Name string
197 Namespace string
198 Path string
199 Prune bool
200 Force bool
201 SupportedFleet []fleet.Type
202 SupportedCluster []cluster.Type
203 OverrideSyncSuffix bool
204 OverridePath bool
205 }
206
207
208 func New() *EdgeKustomizations {
209 return &EdgeKustomizations{
210 Annotations: make(map[string]string),
211 }
212 }
213
214
215 func (k *EdgeKustomizations) SetCluster(cluster *clusterApi.Cluster) *EdgeKustomizations {
216 k.Cluster = cluster
217 return k
218 }
219
220
221 func (k *EdgeKustomizations) SetBucketName(name string) *EdgeKustomizations {
222 k.BucketName = name
223 return k
224 }
225
226 func (k *EdgeKustomizations) SetBucketNamespace(ns string) *EdgeKustomizations {
227 k.BucketNamespace = ns
228 return k
229 }
230
231 func (k *EdgeKustomizations) SetStoreVersion(version string) *EdgeKustomizations {
232 k.StoreVersion = version
233 return k
234 }
235
236 func (k *EdgeKustomizations) SetAnnotations(annotations map[string]string) *EdgeKustomizations {
237 k.Annotations = annotations
238 return k
239 }
240
241
242 func (k *EdgeKustomizations) UseDefaultRules() *EdgeKustomizations {
243 k.Rules = defaultKustomizations
244 return k
245 }
246
247
248 func (k *EdgeKustomizations) UseWarehouseRules() *EdgeKustomizations {
249 k.Rules = warehouseKustomizations
250 return k
251 }
252
253
254 func (k *EdgeKustomizations) UseDefaultForemanRules() *EdgeKustomizations {
255 foremanRules := funk.Filter(defaultKustomizations, isForemanRule)
256 k.Rules = foremanRules.([]*Kustomizations)
257 return k
258 }
259
260
261 func (k *EdgeKustomizations) UseDefaultStoreRules() *EdgeKustomizations {
262 storeRules := funk.Filter(defaultKustomizations, isStoreRule)
263 k.Rules = storeRules.([]*Kustomizations)
264 return k
265 }
266
267
268 func (k *EdgeKustomizations) UseDefaultBannerInfraRules() *EdgeKustomizations {
269 storeRules := funk.Filter(defaultKustomizations, isBannerInfraRule)
270 k.Rules = storeRules.([]*Kustomizations)
271 return k
272 }
273
274
275 func (k *EdgeKustomizations) RegisterNewRule(name, namespace, path string, prune, force bool, supportedFleets []fleet.Type, supportedClusters []cluster.Type, overrideSuffix bool) *EdgeKustomizations {
276 k.Rules = append(k.Rules, &Kustomizations{
277 Name: name,
278 Namespace: namespace,
279 Path: path,
280 Prune: prune,
281 Force: force,
282 SupportedFleet: supportedFleets,
283 SupportedCluster: supportedClusters,
284 OverrideSyncSuffix: overrideSuffix,
285 })
286 return k
287 }
288
289
290 func (k *EdgeKustomizations) CreateBannerKustomization() client.Object {
291 return bootstrap.KustomizeFluxConfig().
292 Name("banner-sync").
293 Namespace(k.BucketNamespace).
294 BucketName(k.BucketName).
295 Path("./chariot").
296 Force(true).
297 Prune(true).
298 ForStoreVersion(k.StoreVersion).
299 Annotations(k.Annotations).
300 BucketNamespace(k.BucketNamespace).
301 Build()
302 }
303
304
305 func (k *EdgeKustomizations) CreateClusterKustomizations() []client.Object {
306 kustomizations := make([]client.Object, 0)
307 clusterEdgeID := k.Cluster.Name
308 if k.BucketName == "" {
309 k.BucketName = fmt.Sprintf("%s-cluster-sync", clusterEdgeID)
310 }
311 for _, kusto := range k.Rules {
312 name := fmt.Sprintf("%s-sync", kusto.Name)
313 path := fmt.Sprintf("./%s/%s", clusterEdgeID, kusto.Path)
314 if kusto.OverrideSyncSuffix {
315 name = kusto.Name
316 }
317 if kusto.OverridePath {
318 path = fmt.Sprintf("./%s/%s/%s", clusterEdgeID, kusto.Path, clusterEdgeID)
319 }
320 if funk.Contains(kusto.SupportedFleet, k.Cluster.Spec.Fleet) && funk.Contains(kusto.SupportedCluster, k.Cluster.Spec.Type) {
321 k := bootstrap.KustomizeFluxConfig().
322 Name(name).
323 Namespace(kusto.Namespace).
324 BucketName(k.BucketName).
325 Path(path).
326 Force(kusto.Force).
327 Prune(kusto.Prune).
328 Annotations(k.Annotations).
329 ForStoreVersion(k.StoreVersion).
330 BucketNamespace(k.BucketNamespace).
331 Build()
332 kustomizations = append(kustomizations, k)
333 }
334 }
335 return kustomizations
336 }
337
338
339 func isForemanRule(k *Kustomizations) bool {
340 for _, fleetType := range k.SupportedFleet {
341 if fleetType == fleet.TopLevel {
342 return true
343 }
344 }
345 return false
346 }
347
348
349 func isBannerInfraRule(k *Kustomizations) bool {
350 for _, fleetType := range k.SupportedFleet {
351 if fleetType == fleet.Banner {
352 return true
353 }
354 }
355 return false
356 }
357
358
359 func isStoreRule(k *Kustomizations) bool {
360 for _, fleetType := range k.SupportedFleet {
361 if fleetType == fleet.BasicStore || fleetType == fleet.Store {
362 return true
363 }
364 }
365 return false
366 }
367
View as plain text