• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

kubevirt / hyperconverged-cluster-operator / 20021419104

08 Dec 2025 08:22AM UTC coverage: 76.505% (-0.2%) from 76.718%
20021419104

Pull #3912

github

web-flow
Merge 5909fb4a9 into cae67e758
Pull Request #3912: CNV-61721: Add ValidatingAdmissionPolicy to validate the HyperConverged namespace

115 of 189 new or added lines in 4 files covered. (60.85%)

5 existing lines in 1 file now uncovered.

8183 of 10696 relevant lines covered (76.51%)

1.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

3.0
/pkg/components/components.go
1
package components
2

3
import (
4
        "encoding/json"
5
        "fmt"
6
        "strconv"
7
        "time"
8

9
        "github.com/blang/semver/v4"
10
        csvVersion "github.com/operator-framework/api/pkg/lib/version"
11
        csvv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
12
        admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
13
        appsv1 "k8s.io/api/apps/v1"
14
        corev1 "k8s.io/api/core/v1"
15
        networkingv1 "k8s.io/api/networking/v1"
16
        rbacv1 "k8s.io/api/rbac/v1"
17
        "k8s.io/apimachinery/pkg/api/resource"
18
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
19
        "k8s.io/apimachinery/pkg/runtime"
20
        "k8s.io/apimachinery/pkg/util/intstr"
21
        "k8s.io/utils/ptr"
22

23
        cnaoapi "github.com/kubevirt/cluster-network-addons-operator/pkg/apis/networkaddonsoperator/v1"
24
        kvapi "kubevirt.io/api/core"
25
        aaqapi "kubevirt.io/application-aware-quota/staging/src/kubevirt.io/application-aware-quota-api/pkg/apis/core"
26
        cdiapi "kubevirt.io/containerized-data-importer-api/pkg/apis/core"
27
        sspapi "kubevirt.io/ssp-operator/api/v1beta3"
28

29
        hcov1beta1 "github.com/kubevirt/hyperconverged-cluster-operator/api/v1beta1"
30
        "github.com/kubevirt/hyperconverged-cluster-operator/pkg/util"
31
)
32

33
const DisableOperandDeletionAnnotation = "console.openshift.io/disable-operand-delete"
34

35
const (
36
        crName              = util.HyperConvergedName
37
        packageName         = util.HyperConvergedName
38
        hcoDeploymentName   = "hco-operator"
39
        hcoWhDeploymentName = "hco-webhook"
40
        certVolume          = "apiservice-cert"
41

42
        kubevirtProjectName = "KubeVirt project"
43
        rbacVersionV1       = "rbac.authorization.k8s.io/v1"
44
)
45

46
var deploymentType = metav1.TypeMeta{
47
        APIVersion: "apps/v1",
48
        Kind:       "Deployment",
49
}
50

51
type DeploymentOperatorParams struct {
52
        Namespace              string
53
        Image                  string
54
        WebhookImage           string
55
        CliDownloadsImage      string
56
        KVUIPluginImage        string
57
        KVUIProxyImage         string
58
        PasstImage             string
59
        PasstCNIImage          string
60
        WaspAgentImage         string
61
        ImagePullPolicy        string
62
        ConversionContainer    string
63
        VmwareContainer        string
64
        VirtIOWinContainer     string
65
        Smbios                 string
66
        Machinetype            string
67
        Amd64MachineType       string
68
        Arm64MachineType       string
69
        S390xMachineType       string
70
        HcoKvIoVersion         string
71
        KubevirtVersion        string
72
        KvVirtLancherOsVersion string
73
        CdiVersion             string
74
        CnaoVersion            string
75
        SspVersion             string
76
        HppoVersion            string
77
        MtqVersion             string
78
        AaqVersion             string
79
        Env                    []corev1.EnvVar
80
        AddNetworkPolicyLabels bool
81
}
82

83
func GetDeploymentOperator(params *DeploymentOperatorParams) appsv1.Deployment {
×
84
        return appsv1.Deployment{
×
85
                TypeMeta: deploymentType,
×
86
                ObjectMeta: metav1.ObjectMeta{
×
87
                        Name: util.HCOOperatorName,
×
88
                        Labels: map[string]string{
×
89
                                "name": util.HCOOperatorName,
×
90
                        },
×
91
                },
×
92
                Spec: GetDeploymentSpecOperator(params),
×
93
        }
×
94
}
×
95

96
func GetDeploymentWebhook(params *DeploymentOperatorParams) appsv1.Deployment {
×
97
        deploy := appsv1.Deployment{
×
98
                TypeMeta: deploymentType,
×
99
                ObjectMeta: metav1.ObjectMeta{
×
100
                        Name: util.HCOWebhookName,
×
101
                        Labels: map[string]string{
×
102
                                "name": util.HCOWebhookName,
×
103
                        },
×
104
                },
×
105
                Spec: GetDeploymentSpecWebhook(params),
×
106
        }
×
107

×
108
        InjectVolumesForWebHookCerts(&deploy)
×
109
        return deploy
×
110
}
×
111

112
func GetDeploymentCliDownloads(params *DeploymentOperatorParams) appsv1.Deployment {
×
113
        return appsv1.Deployment{
×
114
                TypeMeta: deploymentType,
×
115
                ObjectMeta: metav1.ObjectMeta{
×
116
                        Name: util.CLIDownloadsName,
×
117
                        Labels: map[string]string{
×
118
                                "name": util.CLIDownloadsName,
×
119
                        },
×
120
                },
×
121
                Spec: GetDeploymentSpecCliDownloads(params),
×
122
        }
×
123
}
×
124

125
func GetServiceWebhook() corev1.Service {
×
126
        return corev1.Service{
×
127
                TypeMeta: metav1.TypeMeta{
×
128
                        APIVersion: "v1",
×
129
                        Kind:       "Service",
×
130
                },
×
131
                ObjectMeta: metav1.ObjectMeta{
×
132
                        Name: util.HCOWebhookName + "-service",
×
133
                },
×
134
                Spec: corev1.ServiceSpec{
×
135
                        Selector: map[string]string{
×
136
                                "name": util.HCOWebhookName,
×
137
                        },
×
138
                        Ports: []corev1.ServicePort{
×
139
                                {
×
140
                                        Name:       strconv.Itoa(util.WebhookPort),
×
141
                                        Port:       util.WebhookPort,
×
142
                                        Protocol:   corev1.ProtocolTCP,
×
143
                                        TargetPort: intstr.FromInt32(util.WebhookPort),
×
144
                                },
×
145
                        },
×
146
                        Type: corev1.ServiceTypeClusterIP,
×
147
                },
×
148
        }
×
149
}
×
150

151
func GetDeploymentSpecOperator(params *DeploymentOperatorParams) appsv1.DeploymentSpec {
×
152
        envs := buildEnvVars(params)
×
153

×
154
        return appsv1.DeploymentSpec{
×
155
                Replicas: ptr.To[int32](1),
×
156
                Selector: &metav1.LabelSelector{
×
157
                        MatchLabels: map[string]string{
×
158
                                "name": util.HCOOperatorName,
×
159
                        },
×
160
                },
×
161
                Strategy: appsv1.DeploymentStrategy{
×
162
                        Type: appsv1.RollingUpdateDeploymentStrategyType,
×
163
                },
×
164
                Template: corev1.PodTemplateSpec{
×
165
                        ObjectMeta: metav1.ObjectMeta{
×
166
                                Labels: getLabelsWithNetworkPolicies(util.HCOOperatorName, params),
×
167
                        },
×
168
                        Spec: corev1.PodSpec{
×
169
                                ServiceAccountName: util.HCOOperatorName,
×
170
                                SecurityContext:    GetStdPodSecurityContext(),
×
171
                                Containers: []corev1.Container{
×
172
                                        {
×
173
                                                Name:            util.HCOOperatorName,
×
174
                                                Image:           params.Image,
×
175
                                                ImagePullPolicy: corev1.PullPolicy(params.ImagePullPolicy),
×
176
                                                Command:         stringListToSlice(util.HCOOperatorName),
×
177
                                                ReadinessProbe:  getReadinessProbe(util.ReadinessEndpointName, util.HealthProbePort),
×
178
                                                LivenessProbe:   getLivenessProbe(util.LivenessEndpointName, util.HealthProbePort),
×
179
                                                Env:             envs,
×
180
                                                Resources: corev1.ResourceRequirements{
×
181
                                                        Requests: map[corev1.ResourceName]resource.Quantity{
×
182
                                                                corev1.ResourceCPU:    resource.MustParse("10m"),
×
183
                                                                corev1.ResourceMemory: resource.MustParse("96Mi"),
×
184
                                                        },
×
185
                                                },
×
186
                                                SecurityContext:          GetStdContainerSecurityContext(),
×
187
                                                TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
×
188
                                                Ports: []corev1.ContainerPort{
×
189
                                                        getMetricsPort(),
×
190
                                                },
×
191
                                        },
×
192
                                },
×
193
                                PriorityClassName: "system-cluster-critical",
×
194
                        },
×
195
                },
×
196
        }
×
197
}
×
198

199
func buildEnvVars(params *DeploymentOperatorParams) []corev1.EnvVar {
×
200
        envs := append([]corev1.EnvVar{
×
201
                {
×
202
                        // deprecated: left here for CI test.
×
203
                        Name:  util.OperatorWebhookModeEnv,
×
204
                        Value: "false",
×
205
                },
×
206
                {
×
207
                        Name:  util.ContainerAppName,
×
208
                        Value: util.ContainerOperatorApp,
×
209
                },
×
210
                {
×
211
                        Name:  "KVM_EMULATION",
×
212
                        Value: "",
×
213
                },
×
214
                {
×
215
                        Name:  "OPERATOR_IMAGE",
×
216
                        Value: params.Image,
×
217
                },
×
218
                {
×
219
                        Name:  "OPERATOR_NAME",
×
220
                        Value: util.HCOOperatorName,
×
221
                },
×
222
                {
×
223
                        Name:  "OPERATOR_NAMESPACE",
×
224
                        Value: params.Namespace,
×
225
                },
×
226
                {
×
227
                        Name: "POD_NAME",
×
228
                        ValueFrom: &corev1.EnvVarSource{
×
229
                                FieldRef: &corev1.ObjectFieldSelector{
×
230
                                        FieldPath: "metadata.name",
×
231
                                },
×
232
                        },
×
233
                },
×
234
                {
×
235
                        Name:  "VIRTIOWIN_CONTAINER",
×
236
                        Value: params.VirtIOWinContainer,
×
237
                },
×
238
                {
×
239
                        Name:  "SMBIOS",
×
240
                        Value: params.Smbios,
×
241
                },
×
242
                {
×
243
                        Name:  "MACHINETYPE",
×
244
                        Value: params.Machinetype,
×
245
                },
×
246
                {
×
247
                        Name:  "AMD64_MACHINETYPE",
×
248
                        Value: params.Amd64MachineType,
×
249
                },
×
250
                {
×
251
                        Name:  "ARM64_MACHINETYPE",
×
252
                        Value: params.Arm64MachineType,
×
253
                },
×
254
                {
×
255
                        Name:  "S390X_MACHINETYPE",
×
256
                        Value: params.S390xMachineType,
×
257
                },
×
258
                {
×
259
                        Name:  util.HcoKvIoVersionName,
×
260
                        Value: params.HcoKvIoVersion,
×
261
                },
×
262
                {
×
263
                        Name:  util.KubevirtVersionEnvV,
×
264
                        Value: params.KubevirtVersion,
×
265
                },
×
266
                {
×
267
                        Name:  util.CdiVersionEnvV,
×
268
                        Value: params.CdiVersion,
×
269
                },
×
270
                {
×
271
                        Name:  util.CnaoVersionEnvV,
×
272
                        Value: params.CnaoVersion,
×
273
                },
×
274
                {
×
275
                        Name:  util.SspVersionEnvV,
×
276
                        Value: params.SspVersion,
×
277
                },
×
278
                {
×
279
                        Name:  util.HppoVersionEnvV,
×
280
                        Value: params.HppoVersion,
×
281
                },
×
282
                {
×
283
                        Name:  util.AaqVersionEnvV,
×
284
                        Value: params.AaqVersion,
×
285
                },
×
286
                {
×
287
                        Name:  util.KVUIPluginImageEnvV,
×
288
                        Value: params.KVUIPluginImage,
×
289
                },
×
290
                {
×
291
                        Name:  util.KVUIProxyImageEnvV,
×
292
                        Value: params.KVUIProxyImage,
×
293
                },
×
294
                {
×
295
                        Name:  util.PasstImageEnvV,
×
296
                        Value: params.PasstImage,
×
297
                },
×
298
                {
×
299
                        Name:  util.PasstCNIImageEnvV,
×
300
                        Value: params.PasstCNIImage,
×
301
                },
×
302
                {
×
303
                        Name:  util.WaspAgentImageEnvV,
×
304
                        Value: params.WaspAgentImage,
×
305
                },
×
306
        }, params.Env...)
×
307

×
308
        if params.KvVirtLancherOsVersion != "" {
×
309
                envs = append(envs, corev1.EnvVar{
×
310
                        Name:  util.KvVirtLauncherOSVersionEnvV,
×
311
                        Value: params.KvVirtLancherOsVersion,
×
312
                })
×
313
        }
×
314

315
        if params.AddNetworkPolicyLabels {
×
316
                envs = append(envs, corev1.EnvVar{
×
317
                        Name:  util.DeployNetworkPoliciesEnvV,
×
318
                        Value: "true",
×
319
                })
×
320
        }
×
321

322
        return envs
×
323
}
324

325
func GetDeploymentSpecCliDownloads(params *DeploymentOperatorParams) appsv1.DeploymentSpec {
×
326
        return appsv1.DeploymentSpec{
×
327
                Replicas: ptr.To[int32](1),
×
328
                Selector: &metav1.LabelSelector{
×
329
                        MatchLabels: map[string]string{
×
330
                                "name": util.CLIDownloadsName,
×
331
                        },
×
332
                },
×
333
                Strategy: appsv1.DeploymentStrategy{
×
334
                        Type: appsv1.RollingUpdateDeploymentStrategyType,
×
335
                },
×
336
                Template: corev1.PodTemplateSpec{
×
337
                        ObjectMeta: metav1.ObjectMeta{
×
338
                                Labels: getLabels(util.CLIDownloadsName, params.HcoKvIoVersion),
×
339
                        },
×
340
                        Spec: corev1.PodSpec{
×
341
                                ServiceAccountName:           util.CLIDownloadsName,
×
342
                                AutomountServiceAccountToken: ptr.To(false),
×
343
                                SecurityContext:              GetStdPodSecurityContext(),
×
344
                                Containers: []corev1.Container{
×
345
                                        {
×
346
                                                Name:            "server",
×
347
                                                Image:           params.CliDownloadsImage,
×
348
                                                ImagePullPolicy: corev1.PullPolicy(params.ImagePullPolicy),
×
349
                                                Resources: corev1.ResourceRequirements{
×
350
                                                        Requests: map[corev1.ResourceName]resource.Quantity{
×
351
                                                                corev1.ResourceCPU:    resource.MustParse("10m"),
×
352
                                                                corev1.ResourceMemory: resource.MustParse("96Mi"),
×
353
                                                        },
×
354
                                                },
×
355
                                                Ports: []corev1.ContainerPort{
×
356
                                                        {
×
357
                                                                Protocol:      corev1.ProtocolTCP,
×
358
                                                                ContainerPort: util.CliDownloadsServerPort,
×
359
                                                        },
×
360
                                                },
×
361
                                                SecurityContext:          GetStdContainerSecurityContext(),
×
362
                                                ReadinessProbe:           getReadinessProbe("/health", util.CliDownloadsServerPort),
×
363
                                                LivenessProbe:            getLivenessProbe("/health", util.CliDownloadsServerPort),
×
364
                                                TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
×
365
                                        },
×
366
                                },
×
367
                                PriorityClassName: "system-cluster-critical",
×
368
                        },
×
369
                },
×
370
        }
×
371
}
×
372

373
func getLabels(name, hcoKvIoVersion string) map[string]string {
×
374
        return map[string]string{
×
375
                "name":                 name,
×
376
                util.AppLabelVersion:   hcoKvIoVersion,
×
377
                util.AppLabelPartOf:    util.HyperConvergedCluster,
×
378
                util.AppLabelComponent: string(util.AppComponentDeployment),
×
379
        }
×
380
}
×
381

382
func getLabelsWithNetworkPolicies(deploymentName string, params *DeploymentOperatorParams) map[string]string {
×
383
        labels := getLabels(deploymentName, params.HcoKvIoVersion)
×
384
        if params.AddNetworkPolicyLabels {
×
385
                labels[util.AllowEgressToDNSAndAPIServerLabel] = "true"
×
386
                labels[util.AllowIngressToMetricsEndpointLabel] = "true"
×
387
        }
×
388

389
        return labels
×
390
}
391

392
func GetStdPodSecurityContext() *corev1.PodSecurityContext {
3✔
393
        return &corev1.PodSecurityContext{
3✔
394
                RunAsNonRoot: ptr.To(true),
3✔
395
                SeccompProfile: &corev1.SeccompProfile{
3✔
396
                        Type: corev1.SeccompProfileTypeRuntimeDefault,
3✔
397
                },
3✔
398
        }
3✔
399
}
3✔
400

401
func GetStdContainerSecurityContext() *corev1.SecurityContext {
3✔
402
        return &corev1.SecurityContext{
3✔
403
                AllowPrivilegeEscalation: ptr.To(false),
3✔
404
                Capabilities: &corev1.Capabilities{
3✔
405
                        Drop: []corev1.Capability{"ALL"},
3✔
406
                },
3✔
407
        }
3✔
408
}
3✔
409

410
// Currently we are abusing the pod readiness to signal to OLM that HCO is not ready
411
// for an upgrade. This has a lot of side effects, one of this is the validating webhook
412
// being not able to receive traffic when exposed by a pod that is not reporting ready=true.
413
// This can cause a lot of side effects if not deadlocks when the system reach a status where,
414
// for any possible reason, HCO pod cannot be ready and so HCO pod cannot validate any further update or
415
// delete request on HCO CR.
416
// A proper solution is properly use the readiness probe only to report the pod readiness and communicate
417
// status to OLM via conditions once OLM will be ready for:
418
// https://github.com/operator-framework/enhancements/blob/master/enhancements/operator-conditions.md
419
// in the meanwhile a quick (but dirty!) solution is to expose the same hco binary on two distinct pods:
420
// the first one will run only the controller and the second one (almost always ready) just the validating
421
// webhook one.
422
func GetDeploymentSpecWebhook(params *DeploymentOperatorParams) appsv1.DeploymentSpec {
×
423
        return appsv1.DeploymentSpec{
×
424
                Replicas: ptr.To[int32](1),
×
425
                Selector: &metav1.LabelSelector{
×
426
                        MatchLabels: map[string]string{
×
427
                                "name": util.HCOWebhookName,
×
428
                        },
×
429
                },
×
430
                Strategy: appsv1.DeploymentStrategy{
×
431
                        Type: appsv1.RollingUpdateDeploymentStrategyType,
×
432
                },
×
433
                Template: corev1.PodTemplateSpec{
×
434
                        ObjectMeta: metav1.ObjectMeta{
×
435
                                Labels: getLabelsWithNetworkPolicies(util.HCOWebhookName, params),
×
436
                        },
×
437
                        Spec: corev1.PodSpec{
×
438
                                ServiceAccountName: util.HCOOperatorName,
×
439
                                SecurityContext:    GetStdPodSecurityContext(),
×
440
                                Containers: []corev1.Container{
×
441
                                        {
×
442
                                                Name:            util.HCOWebhookName,
×
443
                                                Image:           params.WebhookImage,
×
444
                                                ImagePullPolicy: corev1.PullPolicy(params.ImagePullPolicy),
×
445
                                                Command:         stringListToSlice(util.HCOWebhookName),
×
446
                                                ReadinessProbe:  getReadinessProbe(util.ReadinessEndpointName, util.HealthProbePort),
×
447
                                                LivenessProbe:   getLivenessProbe(util.LivenessEndpointName, util.HealthProbePort),
×
448
                                                Env: append([]corev1.EnvVar{
×
449
                                                        {
×
450
                                                                // deprecated: left here for CI test.
×
451
                                                                Name:  util.OperatorWebhookModeEnv,
×
452
                                                                Value: "true",
×
453
                                                        },
×
454
                                                        {
×
455
                                                                Name:  util.ContainerAppName,
×
456
                                                                Value: util.ContainerWebhookApp,
×
457
                                                        },
×
458
                                                        {
×
459
                                                                Name:  "OPERATOR_IMAGE",
×
460
                                                                Value: params.WebhookImage,
×
461
                                                        },
×
462
                                                        {
×
463
                                                                Name:  "OPERATOR_NAME",
×
464
                                                                Value: util.HCOWebhookName,
×
465
                                                        },
×
466
                                                        {
×
467
                                                                Name:  "OPERATOR_NAMESPACE",
×
468
                                                                Value: params.Namespace,
×
469
                                                        },
×
470
                                                        {
×
471
                                                                Name: "POD_NAME",
×
472
                                                                ValueFrom: &corev1.EnvVarSource{
×
473
                                                                        FieldRef: &corev1.ObjectFieldSelector{
×
474
                                                                                FieldPath: "metadata.name",
×
475
                                                                        },
×
476
                                                                },
×
477
                                                        },
×
478
                                                        {
×
479
                                                                Name:  util.HcoKvIoVersionName,
×
480
                                                                Value: params.HcoKvIoVersion,
×
481
                                                        },
×
482
                                                }, params.Env...),
×
483
                                                Resources: corev1.ResourceRequirements{
×
484
                                                        Requests: map[corev1.ResourceName]resource.Quantity{
×
485
                                                                corev1.ResourceCPU:    resource.MustParse("5m"),
×
486
                                                                corev1.ResourceMemory: resource.MustParse("48Mi"),
×
487
                                                        },
×
488
                                                },
×
489
                                                SecurityContext:          GetStdContainerSecurityContext(),
×
490
                                                TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
×
491
                                                Ports: []corev1.ContainerPort{
×
492
                                                        getWebhookPort(),
×
493
                                                        getMetricsPort(),
×
494
                                                },
×
495
                                        },
×
496
                                },
×
497
                                PriorityClassName: "system-node-critical",
×
498
                        },
×
499
                },
×
500
        }
×
501
}
×
502

503
func GetClusterRole() rbacv1.ClusterRole {
×
504
        return rbacv1.ClusterRole{
×
505
                TypeMeta: metav1.TypeMeta{
×
506
                        APIVersion: rbacVersionV1,
×
507
                        Kind:       "ClusterRole",
×
508
                },
×
509
                ObjectMeta: metav1.ObjectMeta{
×
510
                        Name: util.HCOOperatorName,
×
511
                        Labels: map[string]string{
×
512
                                "name": util.HCOOperatorName,
×
513
                        },
×
514
                },
×
515
                Rules: GetClusterPermissions(),
×
516
        }
×
517
}
×
518

519
var (
520
        emptyAPIGroup = []string{""}
521
)
522

523
func GetClusterPermissions() []rbacv1.PolicyRule {
×
524
        const configOpenshiftIO = "config.openshift.io"
×
525
        const operatorOpenshiftIO = "operator.openshift.io"
×
526
        return []rbacv1.PolicyRule{
×
527
                {
×
528
                        APIGroups: stringListToSlice(util.APIVersionGroup),
×
529
                        Resources: stringListToSlice("hyperconvergeds"),
×
530
                        Verbs:     stringListToSlice("get", "list", "update", "watch"),
×
531
                },
×
532
                {
×
533
                        APIGroups: stringListToSlice(util.APIVersionGroup),
×
534
                        Resources: stringListToSlice("hyperconvergeds/finalizers", "hyperconvergeds/status"),
×
535
                        Verbs:     stringListToSlice("get", "list", "create", "update", "watch"),
×
536
                },
×
537
                roleWithAllPermissions(kvapi.GroupName, stringListToSlice("kubevirts", "kubevirts/finalizers")),
×
538
                roleWithAllPermissions(cdiapi.GroupName, stringListToSlice("cdis", "cdis/finalizers")),
×
539
                roleWithAllPermissions(sspapi.GroupVersion.Group, stringListToSlice("ssps", "ssps/finalizers")),
×
540
                roleWithAllPermissions(cnaoapi.GroupVersion.Group, stringListToSlice("networkaddonsconfigs", "networkaddonsconfigs/finalizers")),
×
541
                roleWithAllPermissions(aaqapi.GroupName, stringListToSlice("aaqs", "aaqs/finalizers")),
×
542
                roleWithAllPermissions("", stringListToSlice("configmaps")),
×
543
                {
×
544
                        APIGroups: emptyAPIGroup,
×
545
                        Resources: stringListToSlice("events"),
×
546
                        Verbs:     stringListToSlice("get", "list", "watch", "create", "patch"),
×
547
                },
×
548
                roleWithAllPermissions("", stringListToSlice("services")),
×
549
                {
×
550
                        APIGroups: emptyAPIGroup,
×
551
                        Resources: stringListToSlice("pods", "nodes"),
×
552
                        Verbs:     stringListToSlice("get", "list", "watch", "patch"),
×
553
                },
×
554
                {
×
555
                        APIGroups: emptyAPIGroup,
×
556
                        Resources: stringListToSlice("secrets"),
×
557
                        Verbs:     stringListToSlice("get", "list", "watch", "create", "update", "delete"),
×
558
                },
×
559
                {
×
560
                        APIGroups: emptyAPIGroup,
×
561
                        Resources: stringListToSlice("endpoints"),
×
562
                        Verbs:     stringListToSlice("get", "list", "delete", "watch"),
×
563
                },
×
564
                {
×
565
                        APIGroups: emptyAPIGroup,
×
566
                        Resources: stringListToSlice("namespaces"),
×
567
                        Verbs:     stringListToSlice("get", "list", "watch", "patch", "update"),
×
568
                },
×
569
                {
×
570
                        APIGroups: stringListToSlice("apps"),
×
571
                        Resources: stringListToSlice("deployments", "replicasets", "daemonsets"),
×
572
                        Verbs:     stringListToSlice("get", "list", "watch", "create", "update", "delete"),
×
573
                },
×
574
                roleWithAllPermissions("rbac.authorization.k8s.io",
×
575
                        stringListToSlice("roles", "clusterroles", "rolebindings", "clusterrolebindings")),
×
576
                {
×
577
                        APIGroups: stringListToSlice("apiextensions.k8s.io"),
×
578
                        Resources: stringListToSlice("customresourcedefinitions"),
×
579
                        Verbs:     stringListToSlice("get", "list", "watch", "delete"),
×
580
                },
×
581
                {
×
582
                        APIGroups: stringListToSlice("apiextensions.k8s.io"),
×
583
                        Resources: stringListToSlice("customresourcedefinitions/status"),
×
584
                        Verbs:     stringListToSlice("get", "list", "watch", "patch", "update"),
×
585
                },
×
586
                roleWithAllPermissions("monitoring.coreos.com", stringListToSlice("servicemonitors", "prometheusrules")),
×
587
                {
×
588
                        APIGroups: stringListToSlice("operators.coreos.com"),
×
589
                        Resources: stringListToSlice("clusterserviceversions"),
×
590
                        Verbs:     stringListToSlice("get", "list", "watch", "update", "patch"),
×
591
                },
×
592
                {
×
593
                        APIGroups: stringListToSlice("scheduling.k8s.io"),
×
594
                        Resources: stringListToSlice("priorityclasses"),
×
595
                        Verbs:     stringListToSlice("get", "list", "watch", "create", "delete", "patch"),
×
596
                },
×
597
                {
×
598
                        APIGroups: stringListToSlice("admissionregistration.k8s.io"),
×
599
                        Resources: stringListToSlice("validatingwebhookconfigurations"),
×
600
                        Verbs:     stringListToSlice("list", "watch", "update", "patch"),
×
601
                },
×
602
                roleWithAllPermissions("console.openshift.io", stringListToSlice("consoleclidownloads", "consolequickstarts")),
×
603
                {
×
604
                        APIGroups: stringListToSlice(configOpenshiftIO),
×
605
                        Resources: stringListToSlice("clusterversions", "infrastructures", "networks"),
×
606
                        Verbs:     stringListToSlice("get", "list"),
×
607
                },
×
608
                {
×
609
                        APIGroups: stringListToSlice(configOpenshiftIO),
×
610
                        Resources: stringListToSlice("ingresses"),
×
611
                        Verbs:     stringListToSlice("get", "list", "watch"),
×
612
                },
×
613
                {
×
614
                        APIGroups: stringListToSlice(configOpenshiftIO),
×
615
                        Resources: stringListToSlice("ingresses/status"),
×
616
                        Verbs:     stringListToSlice("update"),
×
617
                },
×
618
                {
×
619
                        APIGroups: stringListToSlice(configOpenshiftIO),
×
620
                        Resources: stringListToSlice("apiservers"),
×
621
                        Verbs:     stringListToSlice("get", "list", "watch"),
×
622
                },
×
623
                {
×
624
                        APIGroups: stringListToSlice(operatorOpenshiftIO),
×
625
                        Resources: stringListToSlice("kubedeschedulers"),
×
626
                        Verbs:     stringListToSlice("get", "list", "watch"),
×
627
                },
×
628
                {
×
629
                        APIGroups: stringListToSlice(configOpenshiftIO),
×
630
                        Resources: stringListToSlice("dnses"),
×
631
                        Verbs:     stringListToSlice("get"),
×
632
                },
×
633
                roleWithAllPermissions("coordination.k8s.io", stringListToSlice("leases")),
×
634
                roleWithAllPermissions("route.openshift.io", stringListToSlice("routes")),
×
635
                {
×
636
                        APIGroups: stringListToSlice("route.openshift.io"),
×
637
                        Resources: stringListToSlice("routes/custom-host"),
×
638
                        Verbs:     stringListToSlice("create", "update", "patch"),
×
639
                },
×
640
                {
×
641
                        APIGroups: stringListToSlice("operators.coreos.com"),
×
642
                        Resources: stringListToSlice("operatorconditions"),
×
643
                        Verbs:     stringListToSlice("get", "list", "watch", "update", "patch"),
×
644
                },
×
645
                roleWithAllPermissions("image.openshift.io", stringListToSlice("imagestreams")),
×
646
                roleWithAllPermissions("console.openshift.io", stringListToSlice("consoleplugins")),
×
647
                {
×
648
                        APIGroups: stringListToSlice("operator.openshift.io"),
×
649
                        Resources: stringListToSlice("consoles"),
×
650
                        Verbs:     stringListToSlice("get", "list", "watch", "update"),
×
651
                },
×
652
                {
×
653
                        APIGroups: stringListToSlice("monitoring.coreos.com"),
×
654
                        Resources: stringListToSlice("alertmanagers", "alertmanagers/api"),
×
655
                        Verbs:     stringListToSlice("get", "list", "create", "delete"),
×
656
                },
×
657
                {
×
658
                        APIGroups: stringListToSlice(""),
×
659
                        Resources: stringListToSlice("serviceaccounts"),
×
660
                        Verbs:     stringListToSlice("get", "list", "watch", "create", "update", "delete"),
×
661
                },
×
662
                {
×
663
                        APIGroups: stringListToSlice("k8s.cni.cncf.io"),
×
664
                        Resources: stringListToSlice("network-attachment-definitions"),
×
665
                        Verbs:     stringListToSlice("get", "list", "watch", "create", "update", "delete"),
×
666
                },
×
667
                {
×
668
                        APIGroups: stringListToSlice("security.openshift.io"),
×
669
                        Resources: stringListToSlice("securitycontextconstraints"),
×
670
                        Verbs:     stringListToSlice("get", "list", "watch", "create", "update", "delete"),
×
671
                },
×
672
                {
×
673
                        APIGroups: stringListToSlice(networkingv1.GroupName),
×
674
                        Resources: stringListToSlice("networkpolicies"),
×
675
                        Verbs:     stringListToSlice("get", "list", "watch", "create", "update", "delete"),
×
676
                },
×
NEW
677
                {
×
NEW
678
                        APIGroups: stringListToSlice(admissionregistrationv1.GroupName),
×
NEW
679
                        Resources: stringListToSlice("validatingadmissionpolicies", "validatingadmissionpolicybindings"),
×
NEW
680
                        Verbs:     stringListToSlice("get", "list", "watch", "create", "update", "delete"),
×
NEW
681
                },
×
682
        }
×
683
}
×
684

685
func roleWithAllPermissions(apiGroup string, resources []string) rbacv1.PolicyRule {
×
686
        return rbacv1.PolicyRule{
×
687
                APIGroups: stringListToSlice(apiGroup),
×
688
                Resources: resources,
×
689
                Verbs:     stringListToSlice("get", "list", "watch", "create", "update", "delete", "patch"),
×
690
        }
×
691
}
×
692

693
func GetServiceAccount(namespace string) corev1.ServiceAccount {
×
694
        return createServiceAccount(namespace, util.HCOOperatorName)
×
695
}
×
696

697
func GetCLIDownloadServiceAccount(namespace string) corev1.ServiceAccount {
×
698
        return createServiceAccount(namespace, util.CLIDownloadsName)
×
699
}
×
700

701
func createServiceAccount(namespace, name string) corev1.ServiceAccount {
×
702
        return corev1.ServiceAccount{
×
703
                TypeMeta: metav1.TypeMeta{
×
704
                        APIVersion: "v1",
×
705
                        Kind:       "ServiceAccount",
×
706
                },
×
707
                ObjectMeta: metav1.ObjectMeta{
×
708
                        Name:      name,
×
709
                        Namespace: namespace,
×
710
                        Labels: map[string]string{
×
711
                                "name": name,
×
712
                        },
×
713
                },
×
714
        }
×
715
}
×
716

717
func GetClusterRoleBinding(namespace string) rbacv1.ClusterRoleBinding {
×
718
        return rbacv1.ClusterRoleBinding{
×
719
                TypeMeta: metav1.TypeMeta{
×
720
                        APIVersion: rbacVersionV1,
×
721
                        Kind:       "ClusterRoleBinding",
×
722
                },
×
723
                ObjectMeta: metav1.ObjectMeta{
×
724
                        Name: util.HCOOperatorName,
×
725
                        Labels: map[string]string{
×
726
                                "name": util.HCOOperatorName,
×
727
                        },
×
728
                },
×
729
                RoleRef: rbacv1.RoleRef{
×
730
                        APIGroup: "rbac.authorization.k8s.io",
×
731
                        Kind:     "ClusterRole",
×
732
                        Name:     util.HCOOperatorName,
×
733
                },
×
734
                Subjects: []rbacv1.Subject{
×
735
                        {
×
736
                                Kind:      "ServiceAccount",
×
737
                                Name:      util.HCOOperatorName,
×
738
                                Namespace: namespace,
×
739
                        },
×
740
                },
×
741
        }
×
742
}
×
743

744
func GetOperatorCR() *hcov1beta1.HyperConverged {
13✔
745
        defaultScheme := runtime.NewScheme()
13✔
746
        _ = hcov1beta1.AddToScheme(defaultScheme)
13✔
747
        _ = hcov1beta1.RegisterDefaults(defaultScheme)
13✔
748
        defaultHco := &hcov1beta1.HyperConverged{
13✔
749
                TypeMeta: metav1.TypeMeta{
13✔
750
                        APIVersion: util.APIVersion,
13✔
751
                        Kind:       util.HyperConvergedKind,
13✔
752
                },
13✔
753
                ObjectMeta: metav1.ObjectMeta{
13✔
754
                        Name: crName,
13✔
755
                }}
13✔
756
        defaultScheme.Default(defaultHco)
13✔
757
        return defaultHco
13✔
758
}
13✔
759

760
// GetInstallStrategyBase returns the basics of an HCO InstallStrategy
761
func GetInstallStrategyBase(params *DeploymentOperatorParams) *csvv1alpha1.StrategyDetailsDeployment {
×
762
        return &csvv1alpha1.StrategyDetailsDeployment{
×
763

×
764
                DeploymentSpecs: []csvv1alpha1.StrategyDeploymentSpec{
×
765
                        {
×
766
                                Name:  hcoDeploymentName,
×
767
                                Spec:  GetDeploymentSpecOperator(params),
×
768
                                Label: getLabels(util.HCOOperatorName, params.HcoKvIoVersion),
×
769
                        },
×
770
                        {
×
771
                                Name:  hcoWhDeploymentName,
×
772
                                Spec:  GetDeploymentSpecWebhook(params),
×
773
                                Label: getLabels(util.HCOWebhookName, params.HcoKvIoVersion),
×
774
                        },
×
775
                        {
×
776
                                Name:  util.CLIDownloadsName,
×
777
                                Spec:  GetDeploymentSpecCliDownloads(params),
×
778
                                Label: getLabels(util.CLIDownloadsName, params.HcoKvIoVersion),
×
779
                        },
×
780
                },
×
781
                Permissions: []csvv1alpha1.StrategyDeploymentPermissions{},
×
782
                ClusterPermissions: []csvv1alpha1.StrategyDeploymentPermissions{
×
783
                        {
×
784
                                ServiceAccountName: util.HCOOperatorName,
×
785
                                Rules:              GetClusterPermissions(),
×
786
                        },
×
787
                        {
×
788
                                ServiceAccountName: util.CLIDownloadsName,
×
789
                                Rules:              []rbacv1.PolicyRule{},
×
790
                        },
×
791
                },
×
792
        }
×
793
}
×
794

795
type CSVBaseParams struct {
796
        Name            string
797
        Namespace       string
798
        DisplayName     string
799
        MetaDescription string
800
        Description     string
801
        Image           string
802
        Version         semver.Version
803
        CrdDisplay      string
804
        Icon            string
805
}
806

807
// GetCSVBase returns a base HCO CSV without an InstallStrategy
808
func GetCSVBase(params *CSVBaseParams) *csvv1alpha1.ClusterServiceVersion {
×
809
        almExamples, _ := json.Marshal(
×
810
                map[string]interface{}{
×
811
                        "apiVersion": util.APIVersion,
×
812
                        "kind":       util.HyperConvergedKind,
×
813
                        "metadata": map[string]interface{}{
×
814
                                "name":      packageName,
×
815
                                "namespace": params.Namespace,
×
816
                                "annotations": map[string]string{
×
817
                                        "deployOVS": "false",
×
818
                                },
×
819
                        },
×
820
                        "spec": map[string]interface{}{},
×
821
                })
×
822

×
823
        // Explicitly fail on unvalidated (for any reason) requests:
×
824
        // this can make removing HCO CR harder if HCO webhook is not able
×
825
        // to really validate the requests.
×
826
        // In that case the user can only directly remove the
×
827
        // ValidatingWebhookConfiguration object first (eventually bypassing the OLM if needed).
×
828
        // so failurePolicy = admissionregistrationv1.Fail
×
829

×
830
        validatingWebhook := csvv1alpha1.WebhookDescription{
×
831
                GenerateName:            util.HcoValidatingWebhook,
×
832
                Type:                    csvv1alpha1.ValidatingAdmissionWebhook,
×
833
                DeploymentName:          hcoWhDeploymentName,
×
834
                ContainerPort:           util.WebhookPort,
×
835
                AdmissionReviewVersions: stringListToSlice("v1beta1", "v1"),
×
836
                SideEffects:             ptr.To(admissionregistrationv1.SideEffectClassNone),
×
837
                FailurePolicy:           ptr.To(admissionregistrationv1.Fail),
×
838
                TimeoutSeconds:          ptr.To[int32](10),
×
839
                Rules: []admissionregistrationv1.RuleWithOperations{
×
840
                        {
×
841
                                Operations: []admissionregistrationv1.OperationType{
×
842
                                        admissionregistrationv1.Create,
×
843
                                        admissionregistrationv1.Delete,
×
844
                                        admissionregistrationv1.Update,
×
845
                                },
×
846
                                Rule: admissionregistrationv1.Rule{
×
847
                                        APIGroups:   stringListToSlice(util.APIVersionGroup),
×
848
                                        APIVersions: stringListToSlice(util.APIVersionBeta),
×
849
                                        Resources:   stringListToSlice("hyperconvergeds"),
×
850
                                },
×
851
                        },
×
852
                },
×
853
                WebhookPath: ptr.To(util.HCOWebhookPath),
×
854
        }
×
855

×
856
        mutatingNamespaceWebhook := csvv1alpha1.WebhookDescription{
×
857
                GenerateName:            util.HcoMutatingWebhookNS,
×
858
                Type:                    csvv1alpha1.MutatingAdmissionWebhook,
×
859
                DeploymentName:          hcoWhDeploymentName,
×
860
                ContainerPort:           util.WebhookPort,
×
861
                AdmissionReviewVersions: stringListToSlice("v1beta1", "v1"),
×
862
                SideEffects:             ptr.To(admissionregistrationv1.SideEffectClassNoneOnDryRun),
×
863
                FailurePolicy:           ptr.To(admissionregistrationv1.Fail),
×
864
                TimeoutSeconds:          ptr.To[int32](10),
×
865
                ObjectSelector: &metav1.LabelSelector{
×
866
                        MatchLabels: map[string]string{util.KubernetesMetadataName: params.Namespace},
×
867
                },
×
868
                Rules: []admissionregistrationv1.RuleWithOperations{
×
869
                        {
×
870
                                Operations: []admissionregistrationv1.OperationType{
×
871
                                        admissionregistrationv1.Delete,
×
872
                                },
×
873
                                Rule: admissionregistrationv1.Rule{
×
874
                                        APIGroups:   []string{""},
×
875
                                        APIVersions: stringListToSlice("v1"),
×
876
                                        Resources:   stringListToSlice("namespaces"),
×
877
                                },
×
878
                        },
×
879
                },
×
880
                WebhookPath: ptr.To(util.HCONSWebhookPath),
×
881
        }
×
882

×
883
        mutatingHyperConvergedWebhook := csvv1alpha1.WebhookDescription{
×
884
                GenerateName:            util.HcoMutatingWebhookHyperConverged,
×
885
                Type:                    csvv1alpha1.MutatingAdmissionWebhook,
×
886
                DeploymentName:          hcoWhDeploymentName,
×
887
                ContainerPort:           util.WebhookPort,
×
888
                AdmissionReviewVersions: stringListToSlice("v1beta1", "v1"),
×
889
                SideEffects:             ptr.To(admissionregistrationv1.SideEffectClassNoneOnDryRun),
×
890
                FailurePolicy:           ptr.To(admissionregistrationv1.Fail),
×
891
                TimeoutSeconds:          ptr.To[int32](10),
×
892
                Rules: []admissionregistrationv1.RuleWithOperations{
×
893
                        {
×
894
                                Operations: []admissionregistrationv1.OperationType{
×
895
                                        admissionregistrationv1.Create,
×
896
                                        admissionregistrationv1.Update,
×
897
                                },
×
898
                                Rule: admissionregistrationv1.Rule{
×
899
                                        APIGroups:   stringListToSlice(util.APIVersionGroup),
×
900
                                        APIVersions: stringListToSlice(util.APIVersionBeta),
×
901
                                        Resources:   stringListToSlice("hyperconvergeds"),
×
902
                                },
×
903
                        },
×
904
                },
×
905
                WebhookPath: ptr.To(util.HCOMutatingWebhookPath),
×
906
        }
×
907

×
908
        return &csvv1alpha1.ClusterServiceVersion{
×
909
                TypeMeta: metav1.TypeMeta{
×
910
                        APIVersion: "operators.coreos.com/v1alpha1",
×
911
                        Kind:       "ClusterServiceVersion",
×
912
                },
×
913
                ObjectMeta: metav1.ObjectMeta{
×
914
                        Name:      fmt.Sprintf("%v.v%v", params.Name, params.Version.String()),
×
915
                        Namespace: params.Namespace,
×
916
                        Annotations: map[string]string{
×
917
                                "alm-examples":                   string(almExamples),
×
918
                                "capabilities":                   "Deep Insights",
×
919
                                "certified":                      "false",
×
920
                                "categories":                     "OpenShift Optional",
×
921
                                "containerImage":                 params.Image,
×
922
                                DisableOperandDeletionAnnotation: "true",
×
923
                                "createdAt":                      time.Now().Format("2006-01-02 15:04:05"),
×
924
                                "description":                    params.MetaDescription,
×
925
                                "repository":                     "https://github.com/kubevirt/hyperconverged-cluster-operator",
×
926
                                "support":                        "false",
×
927
                                "operatorframework.io/suggested-namespace":         params.Namespace,
×
928
                                "operatorframework.io/initialization-resource":     string(almExamples),
×
929
                                "operators.openshift.io/infrastructure-features":   `["disconnected","proxy-aware"]`, // TODO: deprecated, remove once all the tools support "features.operators.openshift.io/*"
×
930
                                "features.operators.openshift.io/disconnected":     "true",
×
931
                                "features.operators.openshift.io/fips-compliant":   "false",
×
932
                                "features.operators.openshift.io/proxy-aware":      "true",
×
933
                                "features.operators.openshift.io/cnf":              "false",
×
934
                                "features.operators.openshift.io/cni":              "true",
×
935
                                "features.operators.openshift.io/csi":              "true",
×
936
                                "features.operators.openshift.io/tls-profiles":     "true",
×
937
                                "features.operators.openshift.io/token-auth-aws":   "false",
×
938
                                "features.operators.openshift.io/token-auth-azure": "false",
×
939
                                "features.operators.openshift.io/token-auth-gcp":   "false",
×
940
                                "openshift.io/required-scc":                        "restricted-v2",
×
941
                        },
×
942
                },
×
943
                Spec: csvv1alpha1.ClusterServiceVersionSpec{
×
944
                        DisplayName: params.DisplayName,
×
945
                        Description: params.Description,
×
946
                        Keywords:    stringListToSlice("KubeVirt", "Virtualization"),
×
947
                        Version:     csvVersion.OperatorVersion{Version: params.Version},
×
948
                        Maintainers: []csvv1alpha1.Maintainer{
×
949
                                {
×
950
                                        Name:  kubevirtProjectName,
×
951
                                        Email: "kubevirt-dev@googlegroups.com",
×
952
                                },
×
953
                        },
×
954
                        Maturity: "alpha",
×
955
                        Provider: csvv1alpha1.AppLink{
×
956
                                Name: kubevirtProjectName,
×
957
                                // https://github.com/operator-framework/operator-courier/issues/173
×
958
                                // URL:  "https://kubevirt.io",
×
959
                        },
×
960
                        Links: []csvv1alpha1.AppLink{
×
961
                                {
×
962
                                        Name: kubevirtProjectName,
×
963
                                        URL:  "https://kubevirt.io",
×
964
                                },
×
965
                                {
×
966
                                        Name: "Source Code",
×
967
                                        URL:  "https://github.com/kubevirt/hyperconverged-cluster-operator",
×
968
                                },
×
969
                        },
×
970
                        Icon: []csvv1alpha1.Icon{
×
971
                                {
×
972
                                        MediaType: "image/svg+xml",
×
973
                                        Data:      params.Icon,
×
974
                                },
×
975
                        },
×
976
                        Labels: map[string]string{
×
977
                                "alm-owner-kubevirt": packageName,
×
978
                                "operated-by":        packageName,
×
979
                        },
×
980
                        Selector: &metav1.LabelSelector{
×
981
                                MatchLabels: map[string]string{
×
982
                                        "alm-owner-kubevirt": packageName,
×
983
                                        "operated-by":        packageName,
×
984
                                },
×
985
                        },
×
986
                        InstallModes: []csvv1alpha1.InstallMode{
×
987
                                {
×
988
                                        Type:      csvv1alpha1.InstallModeTypeOwnNamespace,
×
989
                                        Supported: false,
×
990
                                },
×
991
                                {
×
992
                                        Type:      csvv1alpha1.InstallModeTypeSingleNamespace,
×
993
                                        Supported: false,
×
994
                                },
×
995
                                {
×
996
                                        Type:      csvv1alpha1.InstallModeTypeMultiNamespace,
×
997
                                        Supported: false,
×
998
                                },
×
999
                                {
×
1000
                                        Type:      csvv1alpha1.InstallModeTypeAllNamespaces,
×
1001
                                        Supported: true,
×
1002
                                },
×
1003
                        },
×
1004
                        // Skip this in favor of having a separate function to get
×
1005
                        // the actual StrategyDetailsDeployment when merging CSVs
×
1006
                        InstallStrategy: csvv1alpha1.NamedInstallStrategy{},
×
1007
                        WebhookDefinitions: []csvv1alpha1.WebhookDescription{
×
1008
                                validatingWebhook,
×
1009
                                mutatingNamespaceWebhook,
×
1010
                                mutatingHyperConvergedWebhook,
×
1011
                        },
×
1012
                        CustomResourceDefinitions: csvv1alpha1.CustomResourceDefinitions{
×
1013
                                Owned: []csvv1alpha1.CRDDescription{
×
1014
                                        {
×
1015
                                                Name:        "hyperconvergeds.hco.kubevirt.io",
×
1016
                                                Version:     util.CurrentAPIVersion,
×
1017
                                                Kind:        util.HyperConvergedKind,
×
1018
                                                DisplayName: params.CrdDisplay + " Deployment",
×
1019
                                                Description: "Represents the deployment of " + params.CrdDisplay,
×
1020
                                                // TODO: move this to annotations on hyperconverged_types.go once kubebuilder
×
1021
                                                // properly supports SpecDescriptors as the operator-sdk already does
×
1022
                                                SpecDescriptors: []csvv1alpha1.SpecDescriptor{
×
1023
                                                        {
×
1024
                                                                DisplayName: "Infra components node affinity",
×
1025
                                                                Description: "nodeAffinity describes node affinity scheduling rules for the infra pods.",
×
1026
                                                                Path:        "infra.nodePlacement.affinity.nodeAffinity",
×
1027
                                                                XDescriptors: stringListToSlice(
×
1028
                                                                        "urn:alm:descriptor:com.tectonic.ui:nodeAffinity",
×
1029
                                                                ),
×
1030
                                                        },
×
1031
                                                        {
×
1032
                                                                DisplayName: "Infra components pod affinity",
×
1033
                                                                Description: "podAffinity describes pod affinity scheduling rules for the infra pods.",
×
1034
                                                                Path:        "infra.nodePlacement.affinity.podAffinity",
×
1035
                                                                XDescriptors: stringListToSlice(
×
1036
                                                                        "urn:alm:descriptor:com.tectonic.ui:podAffinity",
×
1037
                                                                ),
×
1038
                                                        },
×
1039
                                                        {
×
1040
                                                                DisplayName: "Infra components pod anti-affinity",
×
1041
                                                                Description: "podAntiAffinity describes pod anti affinity scheduling rules for the infra pods.",
×
1042
                                                                Path:        "infra.nodePlacement.affinity.podAntiAffinity",
×
1043
                                                                XDescriptors: stringListToSlice(
×
1044
                                                                        "urn:alm:descriptor:com.tectonic.ui:podAntiAffinity",
×
1045
                                                                ),
×
1046
                                                        },
×
1047
                                                        {
×
1048
                                                                DisplayName: "Workloads components node affinity",
×
1049
                                                                Description: "nodeAffinity describes node affinity scheduling rules for the workloads pods.",
×
1050
                                                                Path:        "workloads.nodePlacement.affinity.nodeAffinity",
×
1051
                                                                XDescriptors: stringListToSlice(
×
1052
                                                                        "urn:alm:descriptor:com.tectonic.ui:nodeAffinity",
×
1053
                                                                ),
×
1054
                                                        },
×
1055
                                                        {
×
1056
                                                                DisplayName: "Workloads components pod affinity",
×
1057
                                                                Description: "podAffinity describes pod affinity scheduling rules for the workloads pods.",
×
1058
                                                                Path:        "workloads.nodePlacement.affinity.podAffinity",
×
1059
                                                                XDescriptors: stringListToSlice(
×
1060
                                                                        "urn:alm:descriptor:com.tectonic.ui:podAffinity",
×
1061
                                                                ),
×
1062
                                                        },
×
1063
                                                        {
×
1064
                                                                DisplayName: "Workloads components pod anti-affinity",
×
1065
                                                                Description: "podAntiAffinity describes pod anti affinity scheduling rules for the workloads pods.",
×
1066
                                                                Path:        "workloads.nodePlacement.affinity.podAntiAffinity",
×
1067
                                                                XDescriptors: stringListToSlice(
×
1068
                                                                        "urn:alm:descriptor:com.tectonic.ui:podAntiAffinity",
×
1069
                                                                ),
×
1070
                                                        },
×
1071
                                                        {
×
1072
                                                                DisplayName: "HIDDEN FIELDS - operator version",
×
1073
                                                                Description: "HIDDEN FIELDS - operator version.",
×
1074
                                                                Path:        "version",
×
1075
                                                                XDescriptors: stringListToSlice(
×
1076
                                                                        "urn:alm:descriptor:com.tectonic.ui:hidden",
×
1077
                                                                ),
×
1078
                                                        },
×
1079
                                                },
×
1080
                                                StatusDescriptors: []csvv1alpha1.StatusDescriptor{},
×
1081
                                        },
×
1082
                                },
×
1083
                                Required: []csvv1alpha1.CRDDescription{},
×
1084
                        },
×
1085
                },
×
1086
        }
×
1087
}
×
1088

1089
func InjectVolumesForWebHookCerts(deploy *appsv1.Deployment) {
×
1090
        // check if there is already a volume for api certificates
×
1091
        for _, vol := range deploy.Spec.Template.Spec.Volumes {
×
1092
                if vol.Name == certVolume {
×
1093
                        return
×
1094
                }
×
1095
        }
1096

1097
        volume := corev1.Volume{
×
1098
                Name: certVolume,
×
1099
                VolumeSource: corev1.VolumeSource{
×
1100
                        Secret: &corev1.SecretVolumeSource{
×
1101
                                SecretName:  deploy.Name + "-service-cert",
×
1102
                                DefaultMode: ptr.To[int32](420),
×
1103
                                Items: []corev1.KeyToPath{
×
1104
                                        {
×
1105
                                                Key:  "tls.crt",
×
1106
                                                Path: util.WebhookCertName,
×
1107
                                        },
×
1108
                                        {
×
1109
                                                Key:  "tls.key",
×
1110
                                                Path: util.WebhookKeyName,
×
1111
                                        },
×
1112
                                },
×
1113
                        },
×
1114
                },
×
1115
        }
×
1116
        deploy.Spec.Template.Spec.Volumes = append(deploy.Spec.Template.Spec.Volumes, volume)
×
1117

×
1118
        for index, container := range deploy.Spec.Template.Spec.Containers {
×
1119
                deploy.Spec.Template.Spec.Containers[index].VolumeMounts = append(container.VolumeMounts,
×
1120
                        corev1.VolumeMount{
×
1121
                                Name:      certVolume,
×
1122
                                MountPath: util.DefaultWebhookCertDir,
×
1123
                        })
×
1124
        }
×
1125
}
1126

1127
func getReadinessProbe(endpoint string, port int32) *corev1.Probe {
×
1128
        return &corev1.Probe{
×
1129
                ProbeHandler: corev1.ProbeHandler{
×
1130
                        HTTPGet: &corev1.HTTPGetAction{
×
1131
                                Path: endpoint,
×
1132
                                Port: intstr.IntOrString{
×
1133
                                        Type:   intstr.Int,
×
1134
                                        IntVal: port,
×
1135
                                },
×
1136
                                Scheme: corev1.URISchemeHTTP,
×
1137
                        },
×
1138
                },
×
1139
                InitialDelaySeconds: 5,
×
1140
                PeriodSeconds:       5,
×
1141
                FailureThreshold:    1,
×
1142
        }
×
1143
}
×
1144

1145
func getLivenessProbe(endpoint string, port int32) *corev1.Probe {
×
1146
        return &corev1.Probe{
×
1147
                ProbeHandler: corev1.ProbeHandler{
×
1148
                        HTTPGet: &corev1.HTTPGetAction{
×
1149
                                Path: endpoint,
×
1150
                                Port: intstr.IntOrString{
×
1151
                                        Type:   intstr.Int,
×
1152
                                        IntVal: port,
×
1153
                                },
×
1154
                                Scheme: corev1.URISchemeHTTP,
×
1155
                        },
×
1156
                },
×
1157
                InitialDelaySeconds: 30,
×
1158
                PeriodSeconds:       5,
×
1159
                FailureThreshold:    1,
×
1160
        }
×
1161
}
×
1162

1163
func getMetricsPort() corev1.ContainerPort {
×
1164
        return corev1.ContainerPort{
×
1165
                Name:          util.MetricsPortName,
×
1166
                ContainerPort: util.MetricsPort,
×
1167
                Protocol:      corev1.ProtocolTCP,
×
1168
        }
×
1169
}
×
1170

1171
func getWebhookPort() corev1.ContainerPort {
×
1172
        return corev1.ContainerPort{
×
1173
                Name:          util.WebhookPortName,
×
1174
                ContainerPort: util.WebhookPort,
×
1175
                Protocol:      corev1.ProtocolTCP,
×
1176
        }
×
1177
}
×
1178

1179
func stringListToSlice(words ...string) []string {
×
1180
        return words
×
1181
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc