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

kubevirt / hyperconverged-cluster-operator / 16809263207

07 Aug 2025 03:45PM UTC coverage: 75.442% (-0.07%) from 75.516%
16809263207

push

github

web-flow
Force recreate metrics endpoint secret to ensure Prometheus config reload (#3688)

* Force recreate metrics endpoint secret

Signed-off-by: João Vilaça <machadovilaca@gmail.com>

* Avoid reconciler nil objects

Signed-off-by: João Vilaça <machadovilaca@gmail.com>

---------

Signed-off-by: João Vilaça <machadovilaca@gmail.com>

10 of 20 new or added lines in 3 files covered. (50.0%)

2 existing lines in 1 file now uncovered.

7164 of 9496 relevant lines covered (75.44%)

1.77 hits per line

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

3.03
/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
        hcoName             = "hyperconverged-cluster-operator"
39
        hcoNameWebhook      = "hyperconverged-cluster-webhook"
40
        hcoDeploymentName   = "hco-operator"
41
        hcoWhDeploymentName = "hco-webhook"
42
        certVolume          = "apiservice-cert"
43

44
        cliDownloadsName = "hyperconverged-cluster-cli-download"
45

46
        kubevirtProjectName = "KubeVirt project"
47
        rbacVersionV1       = "rbac.authorization.k8s.io/v1"
48
)
49

50
var deploymentType = metav1.TypeMeta{
51
        APIVersion: "apps/v1",
52
        Kind:       "Deployment",
53
}
54

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

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

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

×
111
        InjectVolumesForWebHookCerts(&deploy)
×
112
        return deploy
×
113
}
×
114

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

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

154
func GetDeploymentSpecOperator(params *DeploymentOperatorParams) appsv1.DeploymentSpec {
×
155
        envs := buildEnvVars(params)
×
156

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

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

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

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

321
        return envs
×
322
}
323

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

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

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

388
        return labels
×
389
}
390

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

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

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

498
func GetClusterRole() rbacv1.ClusterRole {
×
499
        return rbacv1.ClusterRole{
×
500
                TypeMeta: metav1.TypeMeta{
×
501
                        APIVersion: rbacVersionV1,
×
502
                        Kind:       "ClusterRole",
×
503
                },
×
504
                ObjectMeta: metav1.ObjectMeta{
×
505
                        Name: hcoName,
×
506
                        Labels: map[string]string{
×
507
                                "name": hcoName,
×
508
                        },
×
509
                },
×
510
                Rules: GetClusterPermissions(),
×
511
        }
×
512
}
×
513

514
var (
515
        emptyAPIGroup = []string{""}
516
)
517

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

675
func roleWithAllPermissions(apiGroup string, resources []string) rbacv1.PolicyRule {
×
676
        return rbacv1.PolicyRule{
×
677
                APIGroups: stringListToSlice(apiGroup),
×
678
                Resources: resources,
×
679
                Verbs:     stringListToSlice("get", "list", "watch", "create", "update", "delete", "patch"),
×
680
        }
×
681
}
×
682

683
func GetServiceAccount(namespace string) corev1.ServiceAccount {
×
684
        return createServiceAccount(namespace, hcoName)
×
685
}
×
686

687
func GetCLIDownloadServiceAccount(namespace string) corev1.ServiceAccount {
×
688
        return createServiceAccount(namespace, cliDownloadsName)
×
689
}
×
690

691
func createServiceAccount(namespace, name string) corev1.ServiceAccount {
×
692
        return corev1.ServiceAccount{
×
693
                TypeMeta: metav1.TypeMeta{
×
694
                        APIVersion: "v1",
×
695
                        Kind:       "ServiceAccount",
×
696
                },
×
697
                ObjectMeta: metav1.ObjectMeta{
×
698
                        Name:      name,
×
699
                        Namespace: namespace,
×
700
                        Labels: map[string]string{
×
701
                                "name": name,
×
702
                        },
×
703
                },
×
704
        }
×
705
}
×
706

707
func GetClusterRoleBinding(namespace string) rbacv1.ClusterRoleBinding {
×
708
        return rbacv1.ClusterRoleBinding{
×
709
                TypeMeta: metav1.TypeMeta{
×
710
                        APIVersion: rbacVersionV1,
×
711
                        Kind:       "ClusterRoleBinding",
×
712
                },
×
713
                ObjectMeta: metav1.ObjectMeta{
×
714
                        Name: hcoName,
×
715
                        Labels: map[string]string{
×
716
                                "name": hcoName,
×
717
                        },
×
718
                },
×
719
                RoleRef: rbacv1.RoleRef{
×
720
                        APIGroup: "rbac.authorization.k8s.io",
×
721
                        Kind:     "ClusterRole",
×
722
                        Name:     hcoName,
×
723
                },
×
724
                Subjects: []rbacv1.Subject{
×
725
                        {
×
726
                                Kind:      "ServiceAccount",
×
727
                                Name:      hcoName,
×
728
                                Namespace: namespace,
×
729
                        },
×
730
                },
×
731
        }
×
732
}
×
733

734
func GetOperatorCR() *hcov1beta1.HyperConverged {
11✔
735
        defaultScheme := runtime.NewScheme()
11✔
736
        _ = hcov1beta1.AddToScheme(defaultScheme)
11✔
737
        _ = hcov1beta1.RegisterDefaults(defaultScheme)
11✔
738
        defaultHco := &hcov1beta1.HyperConverged{
11✔
739
                TypeMeta: metav1.TypeMeta{
11✔
740
                        APIVersion: util.APIVersion,
11✔
741
                        Kind:       util.HyperConvergedKind,
11✔
742
                },
11✔
743
                ObjectMeta: metav1.ObjectMeta{
11✔
744
                        Name: crName,
11✔
745
                }}
11✔
746
        defaultScheme.Default(defaultHco)
11✔
747
        return defaultHco
11✔
748
}
11✔
749

750
// GetInstallStrategyBase returns the basics of an HCO InstallStrategy
751
func GetInstallStrategyBase(params *DeploymentOperatorParams) *csvv1alpha1.StrategyDetailsDeployment {
×
752
        return &csvv1alpha1.StrategyDetailsDeployment{
×
753

×
754
                DeploymentSpecs: []csvv1alpha1.StrategyDeploymentSpec{
×
755
                        {
×
756
                                Name:  hcoDeploymentName,
×
757
                                Spec:  GetDeploymentSpecOperator(params),
×
758
                                Label: getLabels(hcoName, params.HcoKvIoVersion),
×
759
                        },
×
760
                        {
×
761
                                Name:  hcoWhDeploymentName,
×
762
                                Spec:  GetDeploymentSpecWebhook(params),
×
763
                                Label: getLabels(hcoNameWebhook, params.HcoKvIoVersion),
×
764
                        },
×
765
                        {
×
766
                                Name:  cliDownloadsName,
×
767
                                Spec:  GetDeploymentSpecCliDownloads(params),
×
768
                                Label: getLabels(cliDownloadsName, params.HcoKvIoVersion),
×
769
                        },
×
770
                },
×
771
                Permissions: []csvv1alpha1.StrategyDeploymentPermissions{},
×
772
                ClusterPermissions: []csvv1alpha1.StrategyDeploymentPermissions{
×
773
                        {
×
774
                                ServiceAccountName: hcoName,
×
775
                                Rules:              GetClusterPermissions(),
×
776
                        },
×
777
                        {
×
778
                                ServiceAccountName: cliDownloadsName,
×
779
                                Rules:              []rbacv1.PolicyRule{},
×
780
                        },
×
781
                },
×
782
        }
×
783
}
×
784

785
type CSVBaseParams struct {
786
        Name            string
787
        Namespace       string
788
        DisplayName     string
789
        MetaDescription string
790
        Description     string
791
        Image           string
792
        Replaces        string
793
        Version         semver.Version
794
        CrdDisplay      string
795
}
796

797
// GetCSVBase returns a base HCO CSV without an InstallStrategy
798
func GetCSVBase(params *CSVBaseParams) *csvv1alpha1.ClusterServiceVersion {
×
799
        almExamples, _ := json.Marshal(
×
800
                map[string]interface{}{
×
801
                        "apiVersion": util.APIVersion,
×
802
                        "kind":       util.HyperConvergedKind,
×
803
                        "metadata": map[string]interface{}{
×
804
                                "name":      packageName,
×
805
                                "namespace": params.Namespace,
×
806
                                "annotations": map[string]string{
×
807
                                        "deployOVS": "false",
×
808
                                },
×
809
                        },
×
810
                        "spec": map[string]interface{}{},
×
811
                })
×
812

×
813
        // Explicitly fail on unvalidated (for any reason) requests:
×
814
        // this can make removing HCO CR harder if HCO webhook is not able
×
815
        // to really validate the requests.
×
816
        // In that case the user can only directly remove the
×
817
        // ValidatingWebhookConfiguration object first (eventually bypassing the OLM if needed).
×
818
        // so failurePolicy = admissionregistrationv1.Fail
×
819

×
820
        validatingWebhook := csvv1alpha1.WebhookDescription{
×
821
                GenerateName:            util.HcoValidatingWebhook,
×
822
                Type:                    csvv1alpha1.ValidatingAdmissionWebhook,
×
823
                DeploymentName:          hcoWhDeploymentName,
×
824
                ContainerPort:           util.WebhookPort,
×
825
                AdmissionReviewVersions: stringListToSlice("v1beta1", "v1"),
×
826
                SideEffects:             ptr.To(admissionregistrationv1.SideEffectClassNone),
×
827
                FailurePolicy:           ptr.To(admissionregistrationv1.Fail),
×
828
                TimeoutSeconds:          ptr.To[int32](10),
×
829
                Rules: []admissionregistrationv1.RuleWithOperations{
×
830
                        {
×
831
                                Operations: []admissionregistrationv1.OperationType{
×
832
                                        admissionregistrationv1.Create,
×
833
                                        admissionregistrationv1.Delete,
×
834
                                        admissionregistrationv1.Update,
×
835
                                },
×
836
                                Rule: admissionregistrationv1.Rule{
×
837
                                        APIGroups:   stringListToSlice(util.APIVersionGroup),
×
838
                                        APIVersions: stringListToSlice(util.APIVersionAlpha, util.APIVersionBeta),
×
839
                                        Resources:   stringListToSlice("hyperconvergeds"),
×
840
                                },
×
841
                        },
×
842
                },
×
843
                WebhookPath: ptr.To(util.HCOWebhookPath),
×
844
        }
×
845

×
846
        mutatingNamespaceWebhook := csvv1alpha1.WebhookDescription{
×
847
                GenerateName:            util.HcoMutatingWebhookNS,
×
848
                Type:                    csvv1alpha1.MutatingAdmissionWebhook,
×
849
                DeploymentName:          hcoWhDeploymentName,
×
850
                ContainerPort:           util.WebhookPort,
×
851
                AdmissionReviewVersions: stringListToSlice("v1beta1", "v1"),
×
852
                SideEffects:             ptr.To(admissionregistrationv1.SideEffectClassNoneOnDryRun),
×
853
                FailurePolicy:           ptr.To(admissionregistrationv1.Fail),
×
854
                TimeoutSeconds:          ptr.To[int32](10),
×
855
                ObjectSelector: &metav1.LabelSelector{
×
856
                        MatchLabels: map[string]string{util.KubernetesMetadataName: params.Namespace},
×
857
                },
×
858
                Rules: []admissionregistrationv1.RuleWithOperations{
×
859
                        {
×
860
                                Operations: []admissionregistrationv1.OperationType{
×
861
                                        admissionregistrationv1.Delete,
×
862
                                },
×
863
                                Rule: admissionregistrationv1.Rule{
×
864
                                        APIGroups:   []string{""},
×
865
                                        APIVersions: stringListToSlice("v1"),
×
866
                                        Resources:   stringListToSlice("namespaces"),
×
867
                                },
×
868
                        },
×
869
                },
×
870
                WebhookPath: ptr.To(util.HCONSWebhookPath),
×
871
        }
×
872

×
873
        mutatingHyperConvergedWebhook := csvv1alpha1.WebhookDescription{
×
874
                GenerateName:            util.HcoMutatingWebhookHyperConverged,
×
875
                Type:                    csvv1alpha1.MutatingAdmissionWebhook,
×
876
                DeploymentName:          hcoWhDeploymentName,
×
877
                ContainerPort:           util.WebhookPort,
×
878
                AdmissionReviewVersions: stringListToSlice("v1beta1", "v1"),
×
879
                SideEffects:             ptr.To(admissionregistrationv1.SideEffectClassNoneOnDryRun),
×
880
                FailurePolicy:           ptr.To(admissionregistrationv1.Fail),
×
881
                TimeoutSeconds:          ptr.To[int32](10),
×
882
                Rules: []admissionregistrationv1.RuleWithOperations{
×
883
                        {
×
884
                                Operations: []admissionregistrationv1.OperationType{
×
885
                                        admissionregistrationv1.Create,
×
886
                                        admissionregistrationv1.Update,
×
887
                                },
×
888
                                Rule: admissionregistrationv1.Rule{
×
889
                                        APIGroups:   stringListToSlice(util.APIVersionGroup),
×
890
                                        APIVersions: stringListToSlice(util.APIVersionAlpha, util.APIVersionBeta),
×
891
                                        Resources:   stringListToSlice("hyperconvergeds"),
×
892
                                },
×
893
                        },
×
894
                },
×
895
                WebhookPath: ptr.To(util.HCOMutatingWebhookPath),
×
896
        }
×
897

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

1080
func InjectVolumesForWebHookCerts(deploy *appsv1.Deployment) {
×
1081
        // check if there is already a volume for api certificates
×
1082
        for _, vol := range deploy.Spec.Template.Spec.Volumes {
×
1083
                if vol.Name == certVolume {
×
1084
                        return
×
1085
                }
×
1086
        }
1087

1088
        volume := corev1.Volume{
×
1089
                Name: certVolume,
×
1090
                VolumeSource: corev1.VolumeSource{
×
1091
                        Secret: &corev1.SecretVolumeSource{
×
1092
                                SecretName:  deploy.Name + "-service-cert",
×
1093
                                DefaultMode: ptr.To[int32](420),
×
1094
                                Items: []corev1.KeyToPath{
×
1095
                                        {
×
1096
                                                Key:  "tls.crt",
×
1097
                                                Path: util.WebhookCertName,
×
1098
                                        },
×
1099
                                        {
×
1100
                                                Key:  "tls.key",
×
1101
                                                Path: util.WebhookKeyName,
×
1102
                                        },
×
1103
                                },
×
1104
                        },
×
1105
                },
×
1106
        }
×
1107
        deploy.Spec.Template.Spec.Volumes = append(deploy.Spec.Template.Spec.Volumes, volume)
×
1108

×
1109
        for index, container := range deploy.Spec.Template.Spec.Containers {
×
1110
                deploy.Spec.Template.Spec.Containers[index].VolumeMounts = append(container.VolumeMounts,
×
1111
                        corev1.VolumeMount{
×
1112
                                Name:      certVolume,
×
1113
                                MountPath: util.DefaultWebhookCertDir,
×
1114
                        })
×
1115
        }
×
1116
}
1117

1118
func getReadinessProbe(endpoint string, port int32) *corev1.Probe {
×
1119
        return &corev1.Probe{
×
1120
                ProbeHandler: corev1.ProbeHandler{
×
1121
                        HTTPGet: &corev1.HTTPGetAction{
×
1122
                                Path: endpoint,
×
1123
                                Port: intstr.IntOrString{
×
1124
                                        Type:   intstr.Int,
×
1125
                                        IntVal: port,
×
1126
                                },
×
1127
                                Scheme: corev1.URISchemeHTTP,
×
1128
                        },
×
1129
                },
×
1130
                InitialDelaySeconds: 5,
×
1131
                PeriodSeconds:       5,
×
1132
                FailureThreshold:    1,
×
1133
        }
×
1134
}
×
1135

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

1154
func getMetricsPort() corev1.ContainerPort {
×
1155
        return corev1.ContainerPort{
×
1156
                Name:          util.MetricsPortName,
×
1157
                ContainerPort: util.MetricsPort,
×
1158
                Protocol:      corev1.ProtocolTCP,
×
1159
        }
×
1160
}
×
1161

1162
func getWebhookPort() corev1.ContainerPort {
×
1163
        return corev1.ContainerPort{
×
1164
                Name:          util.WebhookPortName,
×
1165
                ContainerPort: util.WebhookPort,
×
1166
                Protocol:      corev1.ProtocolTCP,
×
1167
        }
×
1168
}
×
1169

1170
func stringListToSlice(words ...string) []string {
×
1171
        return words
×
1172
}
×
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