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

kubevirt / hyperconverged-cluster-operator / 13135756026

04 Feb 2025 12:44PM UTC coverage: 72.123% (+0.2%) from 71.962%
13135756026

Pull #3281

github

nunnatsa
add e2e test for customized DL link

Signed-off-by: Nahshon Unna-Tsameret <nunnatsa@redhat.com>
Pull Request #3281: Allow customizing the CLI download link

199 of 277 new or added lines in 11 files covered. (71.84%)

2 existing lines in 1 file now uncovered.

6261 of 8681 relevant lines covered (72.12%)

0.79 hits per line

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

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

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

9
        "k8s.io/utils/ptr"
10

11
        "github.com/blang/semver/v4"
12
        csvVersion "github.com/operator-framework/api/pkg/lib/version"
13
        csvv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
14
        "golang.org/x/tools/go/packages"
15
        admissionregistrationv1 "k8s.io/api/admissionregistration/v1"
16
        appsv1 "k8s.io/api/apps/v1"
17
        corev1 "k8s.io/api/core/v1"
18
        v1 "k8s.io/api/core/v1"
19
        rbacv1 "k8s.io/api/rbac/v1"
20
        extv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
21
        "k8s.io/apimachinery/pkg/api/resource"
22
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23
        "k8s.io/apimachinery/pkg/runtime"
24
        "k8s.io/apimachinery/pkg/runtime/schema"
25
        "k8s.io/apimachinery/pkg/util/intstr"
26
        crdgen "sigs.k8s.io/controller-tools/pkg/crd"
27
        crdmarkers "sigs.k8s.io/controller-tools/pkg/crd/markers"
28
        "sigs.k8s.io/controller-tools/pkg/loader"
29
        "sigs.k8s.io/controller-tools/pkg/markers"
30

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

37
        hcov1beta1 "github.com/kubevirt/hyperconverged-cluster-operator/api/v1beta1"
38
        "github.com/kubevirt/hyperconverged-cluster-operator/pkg/util"
39
        hcoutil "github.com/kubevirt/hyperconverged-cluster-operator/pkg/util"
40
)
41

42
const DisableOperandDeletionAnnotation = "console.openshift.io/disable-operand-delete"
43

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

53
        cliDownloadsName = "hyperconverged-cluster-cli-download"
54

55
        kubevirtProjectName = "KubeVirt project"
56
        rbacVersionV1       = "rbac.authorization.k8s.io/v1"
57
)
58

59
var deploymentType = metav1.TypeMeta{
60
        APIVersion: "apps/v1",
61
        Kind:       "Deployment",
62
}
63

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

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

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

×
117
        InjectVolumesForWebHookCerts(&deploy)
×
118
        return deploy
×
119
}
×
120

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

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

160
func GetDeploymentSpecOperator(params *DeploymentOperatorParams) appsv1.DeploymentSpec {
×
161
        envs := buildEnvVars(params)
×
162

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

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

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

308
        return envs
×
309
}
310

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

354
func getLabels(name, hcoKvIoVersion string) map[string]string {
×
355
        return map[string]string{
×
356
                "name":                    name,
×
357
                hcoutil.AppLabelVersion:   hcoKvIoVersion,
×
358
                hcoutil.AppLabelPartOf:    hcoutil.HyperConvergedCluster,
×
359
                hcoutil.AppLabelComponent: string(hcoutil.AppComponentDeployment),
×
360
        }
×
361
}
×
362

363
func GetStdPodSecurityContext() *v1.PodSecurityContext {
1✔
364
        return &v1.PodSecurityContext{
1✔
365
                RunAsNonRoot: ptr.To(true),
1✔
366
                SeccompProfile: &v1.SeccompProfile{
1✔
367
                        Type: corev1.SeccompProfileTypeRuntimeDefault,
1✔
368
                },
1✔
369
        }
1✔
370
}
1✔
371

372
func GetStdContainerSecurityContext() *v1.SecurityContext {
1✔
373
        return &v1.SecurityContext{
1✔
374
                AllowPrivilegeEscalation: ptr.To(false),
1✔
375
                Capabilities: &v1.Capabilities{
1✔
376
                        Drop: []v1.Capability{"ALL"},
1✔
377
                },
1✔
378
        }
1✔
379
}
1✔
380

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

465
func GetClusterRole() rbacv1.ClusterRole {
×
466
        return rbacv1.ClusterRole{
×
467
                TypeMeta: metav1.TypeMeta{
×
468
                        APIVersion: rbacVersionV1,
×
469
                        Kind:       "ClusterRole",
×
470
                },
×
471
                ObjectMeta: metav1.ObjectMeta{
×
472
                        Name: hcoName,
×
473
                        Labels: map[string]string{
×
474
                                "name": hcoName,
×
475
                        },
×
476
                },
×
477
                Rules: GetClusterPermissions(),
×
478
        }
×
479
}
×
480

481
var (
482
        emptyAPIGroup = []string{""}
483
)
484

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

621
func roleWithAllPermissions(apiGroup string, resources []string) rbacv1.PolicyRule {
×
622
        return rbacv1.PolicyRule{
×
623
                APIGroups: stringListToSlice(apiGroup),
×
624
                Resources: resources,
×
625
                Verbs:     stringListToSlice("get", "list", "watch", "create", "update", "delete", "patch"),
×
626
        }
×
627
}
×
628

629
func GetServiceAccount(namespace string) v1.ServiceAccount {
×
630
        return v1.ServiceAccount{
×
631
                TypeMeta: metav1.TypeMeta{
×
632
                        APIVersion: "v1",
×
633
                        Kind:       "ServiceAccount",
×
634
                },
×
635
                ObjectMeta: metav1.ObjectMeta{
×
636
                        Name:      hcoName,
×
637
                        Namespace: namespace,
×
638
                        Labels: map[string]string{
×
639
                                "name": hcoName,
×
640
                        },
×
641
                },
×
642
        }
×
643
}
×
644

645
func GetClusterRoleBinding(namespace string) rbacv1.ClusterRoleBinding {
×
646
        return rbacv1.ClusterRoleBinding{
×
647
                TypeMeta: metav1.TypeMeta{
×
648
                        APIVersion: rbacVersionV1,
×
649
                        Kind:       "ClusterRoleBinding",
×
650
                },
×
651
                ObjectMeta: metav1.ObjectMeta{
×
652
                        Name: hcoName,
×
653
                        Labels: map[string]string{
×
654
                                "name": hcoName,
×
655
                        },
×
656
                },
×
657
                RoleRef: rbacv1.RoleRef{
×
658
                        APIGroup: "rbac.authorization.k8s.io",
×
659
                        Kind:     "ClusterRole",
×
660
                        Name:     hcoName,
×
661
                },
×
662
                Subjects: []rbacv1.Subject{
×
663
                        {
×
664
                                Kind:      "ServiceAccount",
×
665
                                Name:      hcoName,
×
666
                                Namespace: namespace,
×
667
                        },
×
668
                },
×
669
        }
×
670
}
×
671

672
func packageErrors(pkg *loader.Package, filterKinds ...packages.ErrorKind) error {
×
673
        toSkip := make(map[packages.ErrorKind]struct{})
×
674
        for _, errKind := range filterKinds {
×
675
                toSkip[errKind] = struct{}{}
×
676
        }
×
677
        var outErr error
×
678
        packages.Visit([]*packages.Package{pkg.Package}, nil, func(pkgRaw *packages.Package) {
×
679
                for _, err := range pkgRaw.Errors {
×
680
                        if _, skip := toSkip[err.Kind]; skip {
×
681
                                continue
×
682
                        }
683
                        outErr = err
×
684
                }
685
        })
686
        return outErr
×
687
}
688

689
const objectType = "object"
690

691
func GetOperatorCRD(relPath string) *extv1.CustomResourceDefinition {
×
692
        pkgs, err := loader.LoadRoots(relPath)
×
693
        if err != nil {
×
694
                panic(err)
×
695
        }
696
        reg := &markers.Registry{}
×
697
        panicOnError(crdmarkers.Register(reg))
×
698

×
699
        parser := &crdgen.Parser{
×
700
                Collector:                  &markers.Collector{Registry: reg},
×
701
                Checker:                    &loader.TypeChecker{},
×
702
                GenerateEmbeddedObjectMeta: true,
×
703
        }
×
704

×
705
        crdgen.AddKnownTypes(parser)
×
706
        if len(pkgs) == 0 {
×
707
                panic("Failed identifying packages")
×
708
        }
709
        for _, p := range pkgs {
×
710
                parser.NeedPackage(p)
×
711
        }
×
712
        groupKind := schema.GroupKind{Kind: util.HyperConvergedKind, Group: util.APIVersionGroup}
×
713
        parser.NeedCRDFor(groupKind, nil)
×
714
        for _, p := range pkgs {
×
715
                err = packageErrors(p, packages.TypeError)
×
716
                if err != nil {
×
717
                        panic(err)
×
718
                }
719
        }
720
        c := parser.CustomResourceDefinitions[groupKind]
×
721
        // enforce validation of CR name to prevent multiple CRs
×
722
        for _, v := range c.Spec.Versions {
×
723
                v.Schema.OpenAPIV3Schema.Properties["metadata"] = extv1.JSONSchemaProps{
×
724
                        Type: objectType,
×
725
                        Properties: map[string]extv1.JSONSchemaProps{
×
726
                                "name": {
×
727
                                        Type:    "string",
×
728
                                        Pattern: hcov1beta1.HyperConvergedName,
×
729
                                },
×
730
                        },
×
731
                }
×
732
        }
×
733
        return &c
×
734
}
735

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1152
func stringListToSlice(words ...string) []string {
×
1153
        return words
×
1154
}
×
1155

1156
func int32Ptr(i int32) *int32 {
×
1157
        return &i
×
1158
}
×
1159

1160
func panicOnError(err error) {
×
1161
        if err != nil {
×
1162
                panic(err)
×
1163
        }
1164
}
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