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

kubevirt / hyperconverged-cluster-operator / 16164807415

09 Jul 2025 08:52AM UTC coverage: 75.273% (+0.04%) from 75.231%
16164807415

Pull #3600

github

web-flow
Merge ce328a81a into ab9b9c136
Pull Request #3600: network, passt: Introduce deployPasstNetworkBinding annotation

33 of 37 new or added lines in 2 files covered. (89.19%)

16 existing lines in 1 file now uncovered.

6542 of 8691 relevant lines covered (75.27%)

1.75 hits per line

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

3.02
/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
        "golang.org/x/tools/go/packages"
13
        admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
14
        appsv1 "k8s.io/api/apps/v1"
15
        corev1 "k8s.io/api/core/v1"
16
        rbacv1 "k8s.io/api/rbac/v1"
17
        extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
18
        "k8s.io/apimachinery/pkg/api/resource"
19
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
20
        "k8s.io/apimachinery/pkg/runtime"
21
        "k8s.io/apimachinery/pkg/runtime/schema"
22
        "k8s.io/apimachinery/pkg/util/intstr"
23
        "k8s.io/utils/ptr"
24
        crdgen "sigs.k8s.io/controller-tools/pkg/crd"
25
        crdmarkers "sigs.k8s.io/controller-tools/pkg/crd/markers"
26
        "sigs.k8s.io/controller-tools/pkg/loader"
27
        "sigs.k8s.io/controller-tools/pkg/markers"
28

29
        cnaoapi "github.com/kubevirt/cluster-network-addons-operator/pkg/apis/networkaddonsoperator/v1"
30
        kvapi "kubevirt.io/api/core"
31
        aaqapi "kubevirt.io/application-aware-quota/staging/src/kubevirt.io/application-aware-quota-api/pkg/apis/core"
32
        cdiapi "kubevirt.io/containerized-data-importer-api/pkg/apis/core"
33
        sspapi "kubevirt.io/ssp-operator/api/v1beta3"
34

35
        hcov1beta1 "github.com/kubevirt/hyperconverged-cluster-operator/api/v1beta1"
36
        "github.com/kubevirt/hyperconverged-cluster-operator/pkg/util"
37
)
38

39
const DisableOperandDeletionAnnotation = "console.openshift.io/disable-operand-delete"
40

41
const (
42
        crName              = util.HyperConvergedName
43
        packageName         = util.HyperConvergedName
44
        hcoName             = "hyperconverged-cluster-operator"
45
        hcoNameWebhook      = "hyperconverged-cluster-webhook"
46
        hcoDeploymentName   = "hco-operator"
47
        hcoWhDeploymentName = "hco-webhook"
48
        certVolume          = "apiservice-cert"
49

50
        cliDownloadsName = "hyperconverged-cluster-cli-download"
51

52
        kubevirtProjectName = "KubeVirt project"
53
        rbacVersionV1       = "rbac.authorization.k8s.io/v1"
54
)
55

56
var deploymentType = metav1.TypeMeta{
57
        APIVersion: "apps/v1",
58
        Kind:       "Deployment",
59
}
60

61
type DeploymentOperatorParams struct {
62
        Namespace              string
63
        Image                  string
64
        WebhookImage           string
65
        CliDownloadsImage      string
66
        KVUIPluginImage        string
67
        KVUIProxyImage         string
68
        PasstImage             string
69
        ImagePullPolicy        string
70
        ConversionContainer    string
71
        VmwareContainer        string
72
        VirtIOWinContainer     string
73
        Smbios                 string
74
        Machinetype            string
75
        Amd64MachineType       string
76
        Arm64MachineType       string
77
        HcoKvIoVersion         string
78
        KubevirtVersion        string
79
        KvVirtLancherOsVersion string
80
        CdiVersion             string
81
        CnaoVersion            string
82
        SspVersion             string
83
        HppoVersion            string
84
        MtqVersion             string
85
        AaqVersion             string
86
        Env                    []corev1.EnvVar
87
}
88

89
func GetDeploymentOperator(params *DeploymentOperatorParams) appsv1.Deployment {
×
90
        return appsv1.Deployment{
×
91
                TypeMeta: deploymentType,
×
92
                ObjectMeta: metav1.ObjectMeta{
×
93
                        Name: hcoName,
×
94
                        Labels: map[string]string{
×
95
                                "name": hcoName,
×
96
                        },
×
97
                },
×
98
                Spec: GetDeploymentSpecOperator(params),
×
99
        }
×
100
}
×
101

102
func GetDeploymentWebhook(namespace, image, imagePullPolicy, hcoKvIoVersion string, env []corev1.EnvVar) appsv1.Deployment {
×
103
        deploy := appsv1.Deployment{
×
104
                TypeMeta: deploymentType,
×
105
                ObjectMeta: metav1.ObjectMeta{
×
106
                        Name: hcoNameWebhook,
×
107
                        Labels: map[string]string{
×
108
                                "name": hcoNameWebhook,
×
109
                        },
×
110
                },
×
111
                Spec: GetDeploymentSpecWebhook(namespace, image, imagePullPolicy, hcoKvIoVersion, env),
×
112
        }
×
113

×
114
        InjectVolumesForWebHookCerts(&deploy)
×
115
        return deploy
×
116
}
×
117

118
func GetDeploymentCliDownloads(params *DeploymentOperatorParams) appsv1.Deployment {
×
119
        return appsv1.Deployment{
×
120
                TypeMeta: deploymentType,
×
121
                ObjectMeta: metav1.ObjectMeta{
×
122
                        Name: cliDownloadsName,
×
123
                        Labels: map[string]string{
×
124
                                "name": cliDownloadsName,
×
125
                        },
×
126
                },
×
127
                Spec: GetDeploymentSpecCliDownloads(params),
×
128
        }
×
129
}
×
130

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

157
func GetDeploymentSpecOperator(params *DeploymentOperatorParams) appsv1.DeploymentSpec {
×
158
        envs := buildEnvVars(params)
×
159

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

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

×
302
        if params.KvVirtLancherOsVersion != "" {
×
303
                envs = append(envs, corev1.EnvVar{
×
304
                        Name:  util.KvVirtLauncherOSVersionEnvV,
×
305
                        Value: params.KvVirtLancherOsVersion,
×
306
                })
×
307
        }
×
308

309
        return envs
×
310
}
311

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

360
func getLabels(name, hcoKvIoVersion string) map[string]string {
×
361
        return map[string]string{
×
362
                "name":                 name,
×
363
                util.AppLabelVersion:   hcoKvIoVersion,
×
364
                util.AppLabelPartOf:    util.HyperConvergedCluster,
×
365
                util.AppLabelComponent: string(util.AppComponentDeployment),
×
366
        }
×
367
}
×
368

369
func GetStdPodSecurityContext() *corev1.PodSecurityContext {
3✔
370
        return &corev1.PodSecurityContext{
3✔
371
                RunAsNonRoot: ptr.To(true),
3✔
372
                SeccompProfile: &corev1.SeccompProfile{
3✔
373
                        Type: corev1.SeccompProfileTypeRuntimeDefault,
3✔
374
                },
3✔
375
        }
3✔
376
}
3✔
377

378
func GetStdContainerSecurityContext() *corev1.SecurityContext {
3✔
379
        return &corev1.SecurityContext{
3✔
380
                AllowPrivilegeEscalation: ptr.To(false),
3✔
381
                Capabilities: &corev1.Capabilities{
3✔
382
                        Drop: []corev1.Capability{"ALL"},
3✔
383
                },
3✔
384
        }
3✔
385
}
3✔
386

387
// Currently we are abusing the pod readiness to signal to OLM that HCO is not ready
388
// for an upgrade. This has a lot of side effects, one of this is the validating webhook
389
// being not able to receive traffic when exposed by a pod that is not reporting ready=true.
390
// This can cause a lot of side effects if not deadlocks when the system reach a status where,
391
// for any possible reason, HCO pod cannot be ready and so HCO pod cannot validate any further update or
392
// delete request on HCO CR.
393
// A proper solution is properly use the readiness probe only to report the pod readiness and communicate
394
// status to OLM via conditions once OLM will be ready for:
395
// https://github.com/operator-framework/enhancements/blob/master/enhancements/operator-conditions.md
396
// in the meanwhile a quick (but dirty!) solution is to expose the same hco binary on two distinct pods:
397
// the first one will run only the controller and the second one (almost always ready) just the validating
398
// webhook one.
399
func GetDeploymentSpecWebhook(namespace, image, imagePullPolicy, hcoKvIoVersion string, env []corev1.EnvVar) appsv1.DeploymentSpec {
×
400
        return appsv1.DeploymentSpec{
×
401
                Replicas: ptr.To[int32](1),
×
402
                Selector: &metav1.LabelSelector{
×
403
                        MatchLabels: map[string]string{
×
404
                                "name": hcoNameWebhook,
×
405
                        },
×
406
                },
×
407
                Strategy: appsv1.DeploymentStrategy{
×
408
                        Type: appsv1.RollingUpdateDeploymentStrategyType,
×
409
                },
×
410
                Template: corev1.PodTemplateSpec{
×
411
                        ObjectMeta: metav1.ObjectMeta{
×
412
                                Labels: getLabels(hcoNameWebhook, hcoKvIoVersion),
×
413
                        },
×
414
                        Spec: corev1.PodSpec{
×
415
                                ServiceAccountName: hcoName,
×
416
                                SecurityContext:    GetStdPodSecurityContext(),
×
417
                                Containers: []corev1.Container{
×
418
                                        {
×
419
                                                Name:            hcoNameWebhook,
×
420
                                                Image:           image,
×
421
                                                ImagePullPolicy: corev1.PullPolicy(imagePullPolicy),
×
422
                                                Command:         stringListToSlice(hcoNameWebhook),
×
423
                                                ReadinessProbe:  getReadinessProbe(util.ReadinessEndpointName, util.HealthProbePort),
×
424
                                                LivenessProbe:   getLivenessProbe(util.LivenessEndpointName, util.HealthProbePort),
×
425
                                                Env: append([]corev1.EnvVar{
×
426
                                                        {
×
427
                                                                // deprecated: left here for CI test.
×
428
                                                                Name:  util.OperatorWebhookModeEnv,
×
429
                                                                Value: "true",
×
430
                                                        },
×
431
                                                        {
×
432
                                                                Name:  util.ContainerAppName,
×
433
                                                                Value: util.ContainerWebhookApp,
×
434
                                                        },
×
435
                                                        {
×
436
                                                                Name:  "OPERATOR_IMAGE",
×
437
                                                                Value: image,
×
438
                                                        },
×
439
                                                        {
×
440
                                                                Name:  "OPERATOR_NAME",
×
441
                                                                Value: hcoNameWebhook,
×
442
                                                        },
×
443
                                                        {
×
444
                                                                Name:  "OPERATOR_NAMESPACE",
×
445
                                                                Value: namespace,
×
446
                                                        },
×
447
                                                        {
×
448
                                                                Name: "POD_NAME",
×
449
                                                                ValueFrom: &corev1.EnvVarSource{
×
450
                                                                        FieldRef: &corev1.ObjectFieldSelector{
×
451
                                                                                FieldPath: "metadata.name",
×
452
                                                                        },
×
453
                                                                },
×
454
                                                        },
×
455
                                                }, env...),
×
456
                                                Resources: corev1.ResourceRequirements{
×
457
                                                        Requests: map[corev1.ResourceName]resource.Quantity{
×
458
                                                                corev1.ResourceCPU:    resource.MustParse("5m"),
×
459
                                                                corev1.ResourceMemory: resource.MustParse("48Mi"),
×
460
                                                        },
×
461
                                                },
×
462
                                                SecurityContext:          GetStdContainerSecurityContext(),
×
463
                                                TerminationMessagePolicy: corev1.TerminationMessageFallbackToLogsOnError,
×
464
                                                Ports: []corev1.ContainerPort{
×
465
                                                        getMetricsPort(),
×
466
                                                },
×
467
                                        },
×
468
                                },
×
469
                                PriorityClassName: "system-node-critical",
×
470
                        },
×
471
                },
×
472
        }
×
473
}
×
474

475
func GetClusterRole() rbacv1.ClusterRole {
×
476
        return rbacv1.ClusterRole{
×
477
                TypeMeta: metav1.TypeMeta{
×
478
                        APIVersion: rbacVersionV1,
×
479
                        Kind:       "ClusterRole",
×
480
                },
×
481
                ObjectMeta: metav1.ObjectMeta{
×
482
                        Name: hcoName,
×
483
                        Labels: map[string]string{
×
484
                                "name": hcoName,
×
485
                        },
×
486
                },
×
487
                Rules: GetClusterPermissions(),
×
488
        }
×
489
}
×
490

491
var (
492
        emptyAPIGroup = []string{""}
493
)
494

495
func GetClusterPermissions() []rbacv1.PolicyRule {
×
496
        const configOpenshiftIO = "config.openshift.io"
×
497
        const operatorOpenshiftIO = "operator.openshift.io"
×
498
        return []rbacv1.PolicyRule{
×
499
                {
×
500
                        APIGroups: stringListToSlice(util.APIVersionGroup),
×
501
                        Resources: stringListToSlice("hyperconvergeds"),
×
502
                        Verbs:     stringListToSlice("get", "list", "update", "watch"),
×
503
                },
×
504
                {
×
505
                        APIGroups: stringListToSlice(util.APIVersionGroup),
×
506
                        Resources: stringListToSlice("hyperconvergeds/finalizers", "hyperconvergeds/status"),
×
507
                        Verbs:     stringListToSlice("get", "list", "create", "update", "watch"),
×
508
                },
×
509
                roleWithAllPermissions(kvapi.GroupName, stringListToSlice("kubevirts", "kubevirts/finalizers")),
×
510
                roleWithAllPermissions(cdiapi.GroupName, stringListToSlice("cdis", "cdis/finalizers")),
×
511
                roleWithAllPermissions(sspapi.GroupVersion.Group, stringListToSlice("ssps", "ssps/finalizers")),
×
512
                roleWithAllPermissions(cnaoapi.GroupVersion.Group, stringListToSlice("networkaddonsconfigs", "networkaddonsconfigs/finalizers")),
×
513
                roleWithAllPermissions(aaqapi.GroupName, stringListToSlice("aaqs", "aaqs/finalizers")),
×
514
                roleWithAllPermissions("", stringListToSlice("configmaps")),
×
515
                {
×
516
                        APIGroups: emptyAPIGroup,
×
517
                        Resources: stringListToSlice("events"),
×
518
                        Verbs:     stringListToSlice("get", "list", "watch", "create", "patch"),
×
519
                },
×
520
                roleWithAllPermissions("", stringListToSlice("services")),
×
521
                {
×
522
                        APIGroups: emptyAPIGroup,
×
523
                        Resources: stringListToSlice("pods", "nodes"),
×
524
                        Verbs:     stringListToSlice("get", "list", "watch"),
×
525
                },
×
526
                {
×
527
                        APIGroups: emptyAPIGroup,
×
528
                        Resources: stringListToSlice("secrets"),
×
529
                        Verbs:     stringListToSlice("get", "list", "watch", "create", "update"),
×
530
                },
×
531
                {
×
532
                        APIGroups: emptyAPIGroup,
×
533
                        Resources: stringListToSlice("endpoints"),
×
534
                        Verbs:     stringListToSlice("get", "list", "delete", "watch"),
×
535
                },
×
536
                {
×
537
                        APIGroups: emptyAPIGroup,
×
538
                        Resources: stringListToSlice("namespaces"),
×
539
                        Verbs:     stringListToSlice("get", "list", "watch", "patch", "update"),
×
540
                },
×
541
                {
×
542
                        APIGroups: stringListToSlice("apps"),
×
543
                        Resources: stringListToSlice("deployments", "replicasets"),
×
544
                        Verbs:     stringListToSlice("get", "list", "watch", "create", "update", "delete"),
×
545
                },
×
546
                roleWithAllPermissions("rbac.authorization.k8s.io", stringListToSlice("roles", "rolebindings")),
×
547
                {
×
548
                        APIGroups: stringListToSlice("apiextensions.k8s.io"),
×
549
                        Resources: stringListToSlice("customresourcedefinitions"),
×
550
                        Verbs:     stringListToSlice("get", "list", "watch", "delete"),
×
551
                },
×
552
                {
×
553
                        APIGroups: stringListToSlice("apiextensions.k8s.io"),
×
554
                        Resources: stringListToSlice("customresourcedefinitions/status"),
×
555
                        Verbs:     stringListToSlice("get", "list", "watch", "patch", "update"),
×
556
                },
×
557
                roleWithAllPermissions("monitoring.coreos.com", stringListToSlice("servicemonitors", "prometheusrules")),
×
558
                {
×
559
                        APIGroups: stringListToSlice("operators.coreos.com"),
×
560
                        Resources: stringListToSlice("clusterserviceversions"),
×
561
                        Verbs:     stringListToSlice("get", "list", "watch", "update", "patch"),
×
562
                },
×
563
                {
×
564
                        APIGroups: stringListToSlice("scheduling.k8s.io"),
×
565
                        Resources: stringListToSlice("priorityclasses"),
×
566
                        Verbs:     stringListToSlice("get", "list", "watch", "create", "delete", "patch"),
×
567
                },
×
568
                {
×
569
                        APIGroups: stringListToSlice("admissionregistration.k8s.io"),
×
570
                        Resources: stringListToSlice("validatingwebhookconfigurations"),
×
571
                        Verbs:     stringListToSlice("list", "watch", "update", "patch"),
×
572
                },
×
573
                roleWithAllPermissions("console.openshift.io", stringListToSlice("consoleclidownloads", "consolequickstarts")),
×
574
                {
×
575
                        APIGroups: stringListToSlice(configOpenshiftIO),
×
576
                        Resources: stringListToSlice("clusterversions", "infrastructures", "networks"),
×
577
                        Verbs:     stringListToSlice("get", "list"),
×
578
                },
×
579
                {
×
580
                        APIGroups: stringListToSlice(configOpenshiftIO),
×
581
                        Resources: stringListToSlice("ingresses"),
×
582
                        Verbs:     stringListToSlice("get", "list", "watch"),
×
583
                },
×
584
                {
×
585
                        APIGroups: stringListToSlice(configOpenshiftIO),
×
586
                        Resources: stringListToSlice("ingresses/status"),
×
587
                        Verbs:     stringListToSlice("update"),
×
588
                },
×
589
                {
×
590
                        APIGroups: stringListToSlice(configOpenshiftIO),
×
591
                        Resources: stringListToSlice("apiservers"),
×
592
                        Verbs:     stringListToSlice("get", "list", "watch"),
×
593
                },
×
594
                {
×
595
                        APIGroups: stringListToSlice(operatorOpenshiftIO),
×
596
                        Resources: stringListToSlice("kubedeschedulers"),
×
597
                        Verbs:     stringListToSlice("get", "list", "watch"),
×
598
                },
×
599
                {
×
600
                        APIGroups: stringListToSlice(configOpenshiftIO),
×
601
                        Resources: stringListToSlice("dnses"),
×
602
                        Verbs:     stringListToSlice("get"),
×
603
                },
×
604
                roleWithAllPermissions("coordination.k8s.io", stringListToSlice("leases")),
×
605
                roleWithAllPermissions("route.openshift.io", stringListToSlice("routes")),
×
606
                {
×
607
                        APIGroups: stringListToSlice("route.openshift.io"),
×
608
                        Resources: stringListToSlice("routes/custom-host"),
×
609
                        Verbs:     stringListToSlice("create", "update", "patch"),
×
610
                },
×
611
                {
×
612
                        APIGroups: stringListToSlice("operators.coreos.com"),
×
613
                        Resources: stringListToSlice("operatorconditions"),
×
614
                        Verbs:     stringListToSlice("get", "list", "watch", "update", "patch"),
×
615
                },
×
616
                roleWithAllPermissions("image.openshift.io", stringListToSlice("imagestreams")),
×
617
                roleWithAllPermissions("console.openshift.io", stringListToSlice("consoleplugins")),
×
618
                {
×
619
                        APIGroups: stringListToSlice("operator.openshift.io"),
×
620
                        Resources: stringListToSlice("consoles"),
×
621
                        Verbs:     stringListToSlice("get", "list", "watch", "update"),
×
622
                },
×
623
                {
×
624
                        APIGroups: stringListToSlice("monitoring.coreos.com"),
×
625
                        Resources: stringListToSlice("alertmanagers", "alertmanagers/api"),
×
626
                        Verbs:     stringListToSlice("get", "list", "create", "delete"),
×
627
                },
×
628
        }
×
629
}
×
630

631
func roleWithAllPermissions(apiGroup string, resources []string) rbacv1.PolicyRule {
×
632
        return rbacv1.PolicyRule{
×
633
                APIGroups: stringListToSlice(apiGroup),
×
634
                Resources: resources,
×
635
                Verbs:     stringListToSlice("get", "list", "watch", "create", "update", "delete", "patch"),
×
636
        }
×
637
}
×
638

639
func GetServiceAccount(namespace string) corev1.ServiceAccount {
×
640
        return createServiceAccount(namespace, hcoName)
×
641
}
×
642

643
func GetCLIDownloadServiceAccount(namespace string) corev1.ServiceAccount {
×
644
        return createServiceAccount(namespace, cliDownloadsName)
×
645
}
×
646

647
func createServiceAccount(namespace, name string) corev1.ServiceAccount {
×
648
        return corev1.ServiceAccount{
×
649
                TypeMeta: metav1.TypeMeta{
×
650
                        APIVersion: "v1",
×
651
                        Kind:       "ServiceAccount",
×
652
                },
×
653
                ObjectMeta: metav1.ObjectMeta{
×
654
                        Name:      name,
×
655
                        Namespace: namespace,
×
656
                        Labels: map[string]string{
×
657
                                "name": name,
×
658
                        },
×
659
                },
×
660
        }
×
661
}
×
662

663
func GetClusterRoleBinding(namespace string) rbacv1.ClusterRoleBinding {
×
664
        return rbacv1.ClusterRoleBinding{
×
665
                TypeMeta: metav1.TypeMeta{
×
666
                        APIVersion: rbacVersionV1,
×
667
                        Kind:       "ClusterRoleBinding",
×
668
                },
×
669
                ObjectMeta: metav1.ObjectMeta{
×
670
                        Name: hcoName,
×
671
                        Labels: map[string]string{
×
672
                                "name": hcoName,
×
673
                        },
×
674
                },
×
675
                RoleRef: rbacv1.RoleRef{
×
676
                        APIGroup: "rbac.authorization.k8s.io",
×
677
                        Kind:     "ClusterRole",
×
678
                        Name:     hcoName,
×
679
                },
×
680
                Subjects: []rbacv1.Subject{
×
681
                        {
×
682
                                Kind:      "ServiceAccount",
×
683
                                Name:      hcoName,
×
684
                                Namespace: namespace,
×
685
                        },
×
686
                },
×
687
        }
×
688
}
×
689

690
func packageErrors(pkg *loader.Package, filterKinds ...packages.ErrorKind) error {
×
691
        toSkip := make(map[packages.ErrorKind]struct{})
×
692
        for _, errKind := range filterKinds {
×
693
                toSkip[errKind] = struct{}{}
×
694
        }
×
695
        var outErr error
×
696
        packages.Visit([]*packages.Package{pkg.Package}, nil, func(pkgRaw *packages.Package) {
×
697
                for _, err := range pkgRaw.Errors {
×
698
                        if _, skip := toSkip[err.Kind]; skip {
×
699
                                continue
×
700
                        }
701
                        outErr = err
×
702
                }
703
        })
704
        return outErr
×
705
}
706

707
const objectType = "object"
708

709
func GetOperatorCRD(relPath string) *extv1.CustomResourceDefinition {
×
710
        pkgs, err := loader.LoadRoots(relPath)
×
711
        if err != nil {
×
712
                panic(err)
×
713
        }
714
        reg := &markers.Registry{}
×
715
        panicOnError(crdmarkers.Register(reg))
×
716

×
717
        parser := &crdgen.Parser{
×
718
                Collector:                  &markers.Collector{Registry: reg},
×
719
                Checker:                    &loader.TypeChecker{},
×
720
                GenerateEmbeddedObjectMeta: true,
×
721
        }
×
722

×
723
        crdgen.AddKnownTypes(parser)
×
724
        if len(pkgs) == 0 {
×
725
                panic("Failed identifying packages")
×
726
        }
727
        for _, p := range pkgs {
×
728
                parser.NeedPackage(p)
×
729
        }
×
730
        groupKind := schema.GroupKind{Kind: util.HyperConvergedKind, Group: util.APIVersionGroup}
×
731
        parser.NeedCRDFor(groupKind, nil)
×
732
        for _, p := range pkgs {
×
733
                err = packageErrors(p, packages.TypeError)
×
734
                if err != nil {
×
735
                        panic(err)
×
736
                }
737
        }
738
        c := parser.CustomResourceDefinitions[groupKind]
×
739
        // enforce validation of CR name to prevent multiple CRs
×
740
        for _, v := range c.Spec.Versions {
×
741
                v.Schema.OpenAPIV3Schema.Properties["metadata"] = extv1.JSONSchemaProps{
×
742
                        Type: objectType,
×
743
                        Properties: map[string]extv1.JSONSchemaProps{
×
744
                                "name": {
×
745
                                        Type:    "string",
×
746
                                        Pattern: hcov1beta1.HyperConvergedName,
×
747
                                },
×
748
                        },
×
749
                }
×
750
        }
×
751
        return &c
×
752
}
753

754
func GetOperatorCR() *hcov1beta1.HyperConverged {
10✔
755
        defaultScheme := runtime.NewScheme()
10✔
756
        _ = hcov1beta1.AddToScheme(defaultScheme)
10✔
757
        _ = hcov1beta1.RegisterDefaults(defaultScheme)
10✔
758
        defaultHco := &hcov1beta1.HyperConverged{
10✔
759
                TypeMeta: metav1.TypeMeta{
10✔
760
                        APIVersion: util.APIVersion,
10✔
761
                        Kind:       util.HyperConvergedKind,
10✔
762
                },
10✔
763
                ObjectMeta: metav1.ObjectMeta{
10✔
764
                        Name: crName,
10✔
765
                }}
10✔
766
        defaultScheme.Default(defaultHco)
10✔
767
        return defaultHco
10✔
768
}
10✔
769

770
// GetInstallStrategyBase returns the basics of an HCO InstallStrategy
771
func GetInstallStrategyBase(params *DeploymentOperatorParams) *csvv1alpha1.StrategyDetailsDeployment {
×
772
        return &csvv1alpha1.StrategyDetailsDeployment{
×
773

×
774
                DeploymentSpecs: []csvv1alpha1.StrategyDeploymentSpec{
×
775
                        {
×
776
                                Name:  hcoDeploymentName,
×
777
                                Spec:  GetDeploymentSpecOperator(params),
×
778
                                Label: getLabels(hcoName, params.HcoKvIoVersion),
×
779
                        },
×
780
                        {
×
781
                                Name:  hcoWhDeploymentName,
×
782
                                Spec:  GetDeploymentSpecWebhook(params.Namespace, params.WebhookImage, params.ImagePullPolicy, params.HcoKvIoVersion, params.Env),
×
783
                                Label: getLabels(hcoNameWebhook, params.HcoKvIoVersion),
×
784
                        },
×
785
                        {
×
786
                                Name:  cliDownloadsName,
×
787
                                Spec:  GetDeploymentSpecCliDownloads(params),
×
788
                                Label: getLabels(cliDownloadsName, params.HcoKvIoVersion),
×
789
                        },
×
790
                },
×
791
                Permissions: []csvv1alpha1.StrategyDeploymentPermissions{},
×
792
                ClusterPermissions: []csvv1alpha1.StrategyDeploymentPermissions{
×
793
                        {
×
794
                                ServiceAccountName: hcoName,
×
795
                                Rules:              GetClusterPermissions(),
×
796
                        },
×
797
                        {
×
798
                                ServiceAccountName: cliDownloadsName,
×
799
                                Rules:              []rbacv1.PolicyRule{},
×
800
                        },
×
801
                },
×
802
        }
×
803
}
×
804

805
type CSVBaseParams struct {
806
        Name            string
807
        Namespace       string
808
        DisplayName     string
809
        MetaDescription string
810
        Description     string
811
        Image           string
812
        Replaces        string
813
        Version         semver.Version
814
        CrdDisplay      string
815
}
816

817
// GetCSVBase returns a base HCO CSV without an InstallStrategy
818
func GetCSVBase(params *CSVBaseParams) *csvv1alpha1.ClusterServiceVersion {
×
819
        almExamples, _ := json.Marshal(
×
820
                map[string]interface{}{
×
821
                        "apiVersion": util.APIVersion,
×
822
                        "kind":       util.HyperConvergedKind,
×
823
                        "metadata": map[string]interface{}{
×
824
                                "name":      packageName,
×
825
                                "namespace": params.Namespace,
×
826
                                "annotations": map[string]string{
×
827
                                        "deployOVS": "false",
×
828
                                },
×
829
                        },
×
830
                        "spec": map[string]interface{}{},
×
831
                })
×
832

×
833
        // Explicitly fail on unvalidated (for any reason) requests:
×
834
        // this can make removing HCO CR harder if HCO webhook is not able
×
835
        // to really validate the requests.
×
836
        // In that case the user can only directly remove the
×
837
        // ValidatingWebhookConfiguration object first (eventually bypassing the OLM if needed).
×
838
        // so failurePolicy = admissionregistrationv1.Fail
×
839

×
840
        validatingWebhook := csvv1alpha1.WebhookDescription{
×
841
                GenerateName:            util.HcoValidatingWebhook,
×
842
                Type:                    csvv1alpha1.ValidatingAdmissionWebhook,
×
843
                DeploymentName:          hcoWhDeploymentName,
×
844
                ContainerPort:           util.WebhookPort,
×
845
                AdmissionReviewVersions: stringListToSlice("v1beta1", "v1"),
×
846
                SideEffects:             ptr.To(admissionregistrationv1.SideEffectClassNone),
×
847
                FailurePolicy:           ptr.To(admissionregistrationv1.Fail),
×
848
                TimeoutSeconds:          ptr.To[int32](10),
×
849
                Rules: []admissionregistrationv1.RuleWithOperations{
×
850
                        {
×
851
                                Operations: []admissionregistrationv1.OperationType{
×
852
                                        admissionregistrationv1.Create,
×
853
                                        admissionregistrationv1.Delete,
×
854
                                        admissionregistrationv1.Update,
×
855
                                },
×
856
                                Rule: admissionregistrationv1.Rule{
×
857
                                        APIGroups:   stringListToSlice(util.APIVersionGroup),
×
858
                                        APIVersions: stringListToSlice(util.APIVersionAlpha, util.APIVersionBeta),
×
859
                                        Resources:   stringListToSlice("hyperconvergeds"),
×
860
                                },
×
861
                        },
×
862
                },
×
863
                WebhookPath: ptr.To(util.HCOWebhookPath),
×
864
        }
×
865

×
866
        mutatingNamespaceWebhook := csvv1alpha1.WebhookDescription{
×
867
                GenerateName:            util.HcoMutatingWebhookNS,
×
868
                Type:                    csvv1alpha1.MutatingAdmissionWebhook,
×
869
                DeploymentName:          hcoWhDeploymentName,
×
870
                ContainerPort:           util.WebhookPort,
×
871
                AdmissionReviewVersions: stringListToSlice("v1beta1", "v1"),
×
872
                SideEffects:             ptr.To(admissionregistrationv1.SideEffectClassNoneOnDryRun),
×
873
                FailurePolicy:           ptr.To(admissionregistrationv1.Fail),
×
874
                TimeoutSeconds:          ptr.To[int32](10),
×
875
                ObjectSelector: &metav1.LabelSelector{
×
876
                        MatchLabels: map[string]string{util.KubernetesMetadataName: params.Namespace},
×
877
                },
×
878
                Rules: []admissionregistrationv1.RuleWithOperations{
×
879
                        {
×
880
                                Operations: []admissionregistrationv1.OperationType{
×
881
                                        admissionregistrationv1.Delete,
×
882
                                },
×
883
                                Rule: admissionregistrationv1.Rule{
×
884
                                        APIGroups:   []string{""},
×
885
                                        APIVersions: stringListToSlice("v1"),
×
886
                                        Resources:   stringListToSlice("namespaces"),
×
887
                                },
×
888
                        },
×
889
                },
×
890
                WebhookPath: ptr.To(util.HCONSWebhookPath),
×
891
        }
×
892

×
893
        mutatingHyperConvergedWebhook := csvv1alpha1.WebhookDescription{
×
894
                GenerateName:            util.HcoMutatingWebhookHyperConverged,
×
895
                Type:                    csvv1alpha1.MutatingAdmissionWebhook,
×
896
                DeploymentName:          hcoWhDeploymentName,
×
897
                ContainerPort:           util.WebhookPort,
×
898
                AdmissionReviewVersions: stringListToSlice("v1beta1", "v1"),
×
899
                SideEffects:             ptr.To(admissionregistrationv1.SideEffectClassNoneOnDryRun),
×
900
                FailurePolicy:           ptr.To(admissionregistrationv1.Fail),
×
901
                TimeoutSeconds:          ptr.To[int32](10),
×
902
                Rules: []admissionregistrationv1.RuleWithOperations{
×
903
                        {
×
904
                                Operations: []admissionregistrationv1.OperationType{
×
905
                                        admissionregistrationv1.Create,
×
906
                                        admissionregistrationv1.Update,
×
907
                                },
×
908
                                Rule: admissionregistrationv1.Rule{
×
909
                                        APIGroups:   stringListToSlice(util.APIVersionGroup),
×
910
                                        APIVersions: stringListToSlice(util.APIVersionAlpha, util.APIVersionBeta),
×
911
                                        Resources:   stringListToSlice("hyperconvergeds"),
×
912
                                },
×
913
                        },
×
914
                },
×
915
                WebhookPath: ptr.To(util.HCOMutatingWebhookPath),
×
916
        }
×
917

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

1100
func InjectVolumesForWebHookCerts(deploy *appsv1.Deployment) {
×
1101
        // check if there is already a volume for api certificates
×
1102
        for _, vol := range deploy.Spec.Template.Spec.Volumes {
×
1103
                if vol.Name == certVolume {
×
1104
                        return
×
1105
                }
×
1106
        }
1107

1108
        volume := corev1.Volume{
×
1109
                Name: certVolume,
×
1110
                VolumeSource: corev1.VolumeSource{
×
1111
                        Secret: &corev1.SecretVolumeSource{
×
1112
                                SecretName:  deploy.Name + "-service-cert",
×
1113
                                DefaultMode: ptr.To[int32](420),
×
1114
                                Items: []corev1.KeyToPath{
×
1115
                                        {
×
1116
                                                Key:  "tls.crt",
×
1117
                                                Path: util.WebhookCertName,
×
1118
                                        },
×
1119
                                        {
×
1120
                                                Key:  "tls.key",
×
1121
                                                Path: util.WebhookKeyName,
×
1122
                                        },
×
1123
                                },
×
1124
                        },
×
1125
                },
×
1126
        }
×
1127
        deploy.Spec.Template.Spec.Volumes = append(deploy.Spec.Template.Spec.Volumes, volume)
×
1128

×
1129
        for index, container := range deploy.Spec.Template.Spec.Containers {
×
1130
                deploy.Spec.Template.Spec.Containers[index].VolumeMounts = append(container.VolumeMounts,
×
1131
                        corev1.VolumeMount{
×
1132
                                Name:      certVolume,
×
1133
                                MountPath: util.DefaultWebhookCertDir,
×
1134
                        })
×
1135
        }
×
1136
}
1137

1138
func getReadinessProbe(endpoint string, port int32) *corev1.Probe {
×
1139
        return &corev1.Probe{
×
1140
                ProbeHandler: corev1.ProbeHandler{
×
1141
                        HTTPGet: &corev1.HTTPGetAction{
×
1142
                                Path: endpoint,
×
1143
                                Port: intstr.IntOrString{
×
1144
                                        Type:   intstr.Int,
×
1145
                                        IntVal: port,
×
1146
                                },
×
1147
                                Scheme: corev1.URISchemeHTTP,
×
1148
                        },
×
1149
                },
×
1150
                InitialDelaySeconds: 5,
×
1151
                PeriodSeconds:       5,
×
1152
                FailureThreshold:    1,
×
1153
        }
×
1154
}
×
1155

1156
func getLivenessProbe(endpoint string, port int32) *corev1.Probe {
×
1157
        return &corev1.Probe{
×
1158
                ProbeHandler: corev1.ProbeHandler{
×
1159
                        HTTPGet: &corev1.HTTPGetAction{
×
1160
                                Path: endpoint,
×
1161
                                Port: intstr.IntOrString{
×
1162
                                        Type:   intstr.Int,
×
1163
                                        IntVal: port,
×
1164
                                },
×
1165
                                Scheme: corev1.URISchemeHTTP,
×
1166
                        },
×
1167
                },
×
1168
                InitialDelaySeconds: 30,
×
1169
                PeriodSeconds:       5,
×
1170
                FailureThreshold:    1,
×
1171
        }
×
1172
}
×
1173

1174
func getMetricsPort() corev1.ContainerPort {
×
1175
        return corev1.ContainerPort{
×
1176
                Name:          util.MetricsPortName,
×
1177
                ContainerPort: util.MetricsPort,
×
1178
                Protocol:      corev1.ProtocolTCP,
×
1179
        }
×
1180
}
×
1181

1182
func stringListToSlice(words ...string) []string {
×
1183
        return words
×
1184
}
×
1185

1186
func panicOnError(err error) {
×
1187
        if err != nil {
×
1188
                panic(err)
×
1189
        }
1190
}
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

© 2026 Coveralls, Inc