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

kubevirt / hyperconverged-cluster-operator / 13310017403

13 Feb 2025 02:31PM UTC coverage: 72.286% (+0.3%) from 71.958%
13310017403

Pull #3281

github

nunnatsa
add missing permissions

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

302 of 402 new or added lines in 12 files covered. (75.12%)

5 existing lines in 2 files now uncovered.

6359 of 8797 relevant lines covered (72.29%)

0.8 hits per line

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

3.11
/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(hcoutil.ReadinessEndpointName, hcoutil.HealthProbePort),
×
187
                                                LivenessProbe:   getLivenessProbe(hcoutil.LivenessEndpointName, hcoutil.HealthProbePort),
×
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
                                                ReadinessProbe:  getReadinessProbe("/health", 8080),
×
347
                                                LivenessProbe:   getLivenessProbe("/health", 8080),
×
348
                                        },
×
349
                                },
×
350
                                PriorityClassName: "system-cluster-critical",
×
351
                        },
×
352
                },
×
353
        }
×
354
}
×
355

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

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

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

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

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

483
var (
484
        emptyAPIGroup = []string{""}
485
)
486

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

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

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

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

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

686
const objectType = "object"
687

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

×
696
        parser := &crdgen.Parser{
×
697
                Collector:                  &markers.Collector{Registry: reg},
×
698
                Checker:                    &loader.TypeChecker{},
×
699
                GenerateEmbeddedObjectMeta: true,
×
700
        }
×
701

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1149
func stringListToSlice(words ...string) []string {
×
1150
        return words
×
1151
}
×
1152

1153
func int32Ptr(i int32) *int32 {
×
1154
        return &i
×
1155
}
×
1156

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