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

kubevirt / hyperconverged-cluster-operator / 21356570114

26 Jan 2026 11:48AM UTC coverage: 75.948% (-0.09%) from 76.038%
21356570114

Pull #3977

github

web-flow
Merge 335ae0e82 into 4ce018c73
Pull Request #3977: WIP: POC: add api v1

380 of 558 new or added lines in 8 files covered. (68.1%)

9 existing lines in 1 file now uncovered.

8753 of 11525 relevant lines covered (75.95%)

1.77 hits per line

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

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

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

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

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

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

35
const DisableOperandDeletionAnnotation = "console.openshift.io/disable-operand-delete"
36

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

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

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

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

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

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

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

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

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

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

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

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

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

322
        if params.AddNetworkPolicyLabels {
×
323
                envs = append(envs, corev1.EnvVar{
×
324
                        Name:  util.DeployNetworkPoliciesEnvV,
×
325
                        Value: "true",
×
326
                })
×
327
        }
×
328

329
        return envs
×
330
}
331

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

380
func getLabels(name, hcoKvIoVersion string) map[string]string {
×
381
        return map[string]string{
×
382
                "name":                 name,
×
383
                util.AppLabelVersion:   hcoKvIoVersion,
×
384
                util.AppLabelPartOf:    util.HyperConvergedCluster,
×
385
                util.AppLabelComponent: string(util.AppComponentDeployment),
×
386
        }
×
387
}
×
388

389
func getLabelsWithNetworkPolicies(deploymentName string, params *DeploymentOperatorParams) map[string]string {
×
390
        labels := getLabels(deploymentName, params.HcoKvIoVersion)
×
391
        if params.AddNetworkPolicyLabels {
×
392
                labels[util.AllowEgressToDNSAndAPIServerLabel] = "true"
×
393
                labels[util.AllowIngressToMetricsEndpointLabel] = "true"
×
394
        }
×
395

396
        return labels
×
397
}
398

399
func GetStdPodSecurityContext() *corev1.PodSecurityContext {
3✔
400
        return &corev1.PodSecurityContext{
3✔
401
                RunAsNonRoot: ptr.To(true),
3✔
402
                SeccompProfile: &corev1.SeccompProfile{
3✔
403
                        Type: corev1.SeccompProfileTypeRuntimeDefault,
3✔
404
                },
3✔
405
        }
3✔
406
}
3✔
407

408
func GetStdContainerSecurityContext() *corev1.SecurityContext {
3✔
409
        return &corev1.SecurityContext{
3✔
410
                AllowPrivilegeEscalation: ptr.To(false),
3✔
411
                Capabilities: &corev1.Capabilities{
3✔
412
                        Drop: []corev1.Capability{"ALL"},
3✔
413
                },
3✔
414
        }
3✔
415
}
3✔
416

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

510
func GetClusterRole() rbacv1.ClusterRole {
×
511
        return rbacv1.ClusterRole{
×
512
                TypeMeta: metav1.TypeMeta{
×
513
                        APIVersion: rbacVersionV1,
×
514
                        Kind:       "ClusterRole",
×
515
                },
×
516
                ObjectMeta: metav1.ObjectMeta{
×
517
                        Name: util.HCOOperatorName,
×
518
                        Labels: map[string]string{
×
519
                                "name": util.HCOOperatorName,
×
520
                        },
×
521
                },
×
522
                Rules: GetClusterPermissions(),
×
523
        }
×
524
}
×
525

526
var (
527
        emptyAPIGroup = []string{""}
528
)
529

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

694
func roleWithAllPermissions(apiGroup string, resources []string) rbacv1.PolicyRule {
×
695
        return rbacv1.PolicyRule{
×
696
                APIGroups: stringListToSlice(apiGroup),
×
697
                Resources: resources,
×
698
                Verbs:     stringListToSlice("get", "list", "watch", "create", "update", "delete", "patch"),
×
699
        }
×
700
}
×
701

702
func GetServiceAccount(namespace string) corev1.ServiceAccount {
×
703
        return createServiceAccount(namespace, util.HCOOperatorName)
×
704
}
×
705

706
func GetCLIDownloadServiceAccount(namespace string) corev1.ServiceAccount {
×
707
        return createServiceAccount(namespace, util.CLIDownloadsName)
×
708
}
×
709

710
func createServiceAccount(namespace, name string) corev1.ServiceAccount {
×
711
        return corev1.ServiceAccount{
×
712
                TypeMeta: metav1.TypeMeta{
×
713
                        APIVersion: "v1",
×
714
                        Kind:       "ServiceAccount",
×
715
                },
×
716
                ObjectMeta: metav1.ObjectMeta{
×
717
                        Name:      name,
×
718
                        Namespace: namespace,
×
719
                        Labels: map[string]string{
×
720
                                "name": name,
×
721
                        },
×
722
                },
×
723
        }
×
724
}
×
725

726
func GetClusterRoleBinding(namespace string) rbacv1.ClusterRoleBinding {
×
727
        return rbacv1.ClusterRoleBinding{
×
728
                TypeMeta: metav1.TypeMeta{
×
729
                        APIVersion: rbacVersionV1,
×
730
                        Kind:       "ClusterRoleBinding",
×
731
                },
×
732
                ObjectMeta: metav1.ObjectMeta{
×
733
                        Name: util.HCOOperatorName,
×
734
                        Labels: map[string]string{
×
735
                                "name": util.HCOOperatorName,
×
736
                        },
×
737
                },
×
738
                RoleRef: rbacv1.RoleRef{
×
739
                        APIGroup: "rbac.authorization.k8s.io",
×
740
                        Kind:     "ClusterRole",
×
741
                        Name:     util.HCOOperatorName,
×
742
                },
×
743
                Subjects: []rbacv1.Subject{
×
744
                        {
×
745
                                Kind:      "ServiceAccount",
×
746
                                Name:      util.HCOOperatorName,
×
747
                                Namespace: namespace,
×
748
                        },
×
749
                },
×
750
        }
×
751
}
×
752

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

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

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

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

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

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

×
NEW
839
        validatingWebhook := createHCValidatingWebhook(util.HcoValidatingWebhook, util.APIVersionV1, util.HCOWebhookPath)
×
NEW
840
        v1Beta1ValidatingWebhook := createHCValidatingWebhook(util.HcoV1Beta1ValidatingWebhook, util.APIVersionBeta, util.HCOWebhookV1Beta1Path)
×
NEW
841
        mutatingNamespaceWebhook := createMutatingNSWebhook(params)
×
NEW
842
        mutatingHyperConvergedWebhook := createMutatingHCWebhook(util.HcoMutatingWebhookHyperConverged, util.APIVersionV1, util.HCOMutatingWebhookPath)
×
NEW
843
        v1Beta1MutatingHyperConvergedWebhook := createMutatingHCWebhook(util.HcoV1Beta1MutatingWebhookHyperConverged, util.APIVersionBeta, util.HCOV1Beta1MutatingWebhookPath)
×
844

×
845
        return &csvv1alpha1.ClusterServiceVersion{
×
846
                TypeMeta: metav1.TypeMeta{
×
847
                        APIVersion: "operators.coreos.com/v1alpha1",
×
848
                        Kind:       "ClusterServiceVersion",
×
849
                },
×
850
                ObjectMeta: metav1.ObjectMeta{
×
851
                        Name:      fmt.Sprintf("%v.v%v", params.Name, params.Version.String()),
×
852
                        Namespace: params.Namespace,
×
853
                        Annotations: map[string]string{
×
854
                                "alm-examples":                   string(almExamples),
×
855
                                "capabilities":                   "Deep Insights",
×
856
                                "certified":                      "false",
×
857
                                "categories":                     "OpenShift Optional",
×
858
                                "containerImage":                 params.Image,
×
859
                                DisableOperandDeletionAnnotation: "true",
×
860
                                "createdAt":                      time.Now().Format("2006-01-02 15:04:05"),
×
861
                                "description":                    params.MetaDescription,
×
862
                                "repository":                     "https://github.com/kubevirt/hyperconverged-cluster-operator",
×
863
                                "support":                        "false",
×
864
                                "operatorframework.io/suggested-namespace":         params.Namespace,
×
865
                                "operatorframework.io/initialization-resource":     string(almExamples),
×
866
                                "operators.openshift.io/infrastructure-features":   `["disconnected","proxy-aware"]`, // TODO: deprecated, remove once all the tools support "features.operators.openshift.io/*"
×
867
                                "features.operators.openshift.io/disconnected":     "true",
×
868
                                "features.operators.openshift.io/fips-compliant":   "false",
×
869
                                "features.operators.openshift.io/proxy-aware":      "true",
×
870
                                "features.operators.openshift.io/cnf":              "false",
×
871
                                "features.operators.openshift.io/cni":              "true",
×
872
                                "features.operators.openshift.io/csi":              "true",
×
873
                                "features.operators.openshift.io/tls-profiles":     "true",
×
874
                                "features.operators.openshift.io/token-auth-aws":   "false",
×
875
                                "features.operators.openshift.io/token-auth-azure": "false",
×
876
                                "features.operators.openshift.io/token-auth-gcp":   "false",
×
877
                                "openshift.io/required-scc":                        "restricted-v2",
×
878
                        },
×
879
                },
×
880
                Spec: csvv1alpha1.ClusterServiceVersionSpec{
×
881
                        DisplayName: params.DisplayName,
×
882
                        Description: params.Description,
×
883
                        Keywords:    stringListToSlice("KubeVirt", "Virtualization"),
×
884
                        Version:     csvVersion.OperatorVersion{Version: params.Version},
×
885
                        Maintainers: []csvv1alpha1.Maintainer{
×
886
                                {
×
887
                                        Name:  kubevirtProjectName,
×
888
                                        Email: "kubevirt-dev@googlegroups.com",
×
889
                                },
×
890
                        },
×
891
                        Maturity: "alpha",
×
892
                        Provider: csvv1alpha1.AppLink{
×
893
                                Name: kubevirtProjectName,
×
894
                                // https://github.com/operator-framework/operator-courier/issues/173
×
895
                                // URL:  "https://kubevirt.io",
×
896
                        },
×
897
                        Links: []csvv1alpha1.AppLink{
×
898
                                {
×
899
                                        Name: kubevirtProjectName,
×
900
                                        URL:  "https://kubevirt.io",
×
901
                                },
×
902
                                {
×
903
                                        Name: "Source Code",
×
904
                                        URL:  "https://github.com/kubevirt/hyperconverged-cluster-operator",
×
905
                                },
×
906
                        },
×
907
                        Icon: []csvv1alpha1.Icon{
×
908
                                {
×
909
                                        MediaType: "image/svg+xml",
×
910
                                        Data:      params.Icon,
×
911
                                },
×
912
                        },
×
913
                        Labels: map[string]string{
×
914
                                "alm-owner-kubevirt": packageName,
×
915
                                "operated-by":        packageName,
×
916
                        },
×
917
                        Selector: &metav1.LabelSelector{
×
918
                                MatchLabels: map[string]string{
×
919
                                        "alm-owner-kubevirt": packageName,
×
920
                                        "operated-by":        packageName,
×
921
                                },
×
922
                        },
×
923
                        InstallModes: []csvv1alpha1.InstallMode{
×
924
                                {
×
925
                                        Type:      csvv1alpha1.InstallModeTypeOwnNamespace,
×
926
                                        Supported: false,
×
927
                                },
×
928
                                {
×
929
                                        Type:      csvv1alpha1.InstallModeTypeSingleNamespace,
×
930
                                        Supported: false,
×
931
                                },
×
932
                                {
×
933
                                        Type:      csvv1alpha1.InstallModeTypeMultiNamespace,
×
934
                                        Supported: false,
×
935
                                },
×
936
                                {
×
937
                                        Type:      csvv1alpha1.InstallModeTypeAllNamespaces,
×
938
                                        Supported: true,
×
939
                                },
×
940
                        },
×
941
                        // Skip this in favor of having a separate function to get
×
942
                        // the actual StrategyDetailsDeployment when merging CSVs
×
943
                        InstallStrategy: csvv1alpha1.NamedInstallStrategy{},
×
944
                        WebhookDefinitions: []csvv1alpha1.WebhookDescription{
×
945
                                validatingWebhook,
×
NEW
946
                                v1Beta1ValidatingWebhook,
×
947
                                mutatingNamespaceWebhook,
×
948
                                mutatingHyperConvergedWebhook,
×
NEW
949
                                v1Beta1MutatingHyperConvergedWebhook,
×
950
                        },
×
951
                        CustomResourceDefinitions: csvv1alpha1.CustomResourceDefinitions{
×
952
                                Owned: []csvv1alpha1.CRDDescription{
×
953
                                        {
×
954
                                                Name:        "hyperconvergeds.hco.kubevirt.io",
×
955
                                                Version:     util.CurrentAPIVersion,
×
956
                                                Kind:        util.HyperConvergedKind,
×
957
                                                DisplayName: params.CrdDisplay + " Deployment",
×
958
                                                Description: "Represents the deployment of " + params.CrdDisplay,
×
959
                                                // TODO: move this to annotations on hyperconverged_types.go once kubebuilder
×
960
                                                // properly supports SpecDescriptors as the operator-sdk already does
×
961
                                                SpecDescriptors: []csvv1alpha1.SpecDescriptor{
×
962
                                                        {
×
963
                                                                DisplayName: "Infra components node affinity",
×
964
                                                                Description: "nodeAffinity describes node affinity scheduling rules for the infra pods.",
×
965
                                                                Path:        "infra.nodePlacement.affinity.nodeAffinity",
×
966
                                                                XDescriptors: stringListToSlice(
×
967
                                                                        "urn:alm:descriptor:com.tectonic.ui:nodeAffinity",
×
968
                                                                ),
×
969
                                                        },
×
970
                                                        {
×
971
                                                                DisplayName: "Infra components pod affinity",
×
972
                                                                Description: "podAffinity describes pod affinity scheduling rules for the infra pods.",
×
973
                                                                Path:        "infra.nodePlacement.affinity.podAffinity",
×
974
                                                                XDescriptors: stringListToSlice(
×
975
                                                                        "urn:alm:descriptor:com.tectonic.ui:podAffinity",
×
976
                                                                ),
×
977
                                                        },
×
978
                                                        {
×
979
                                                                DisplayName: "Infra components pod anti-affinity",
×
980
                                                                Description: "podAntiAffinity describes pod anti affinity scheduling rules for the infra pods.",
×
981
                                                                Path:        "infra.nodePlacement.affinity.podAntiAffinity",
×
982
                                                                XDescriptors: stringListToSlice(
×
983
                                                                        "urn:alm:descriptor:com.tectonic.ui:podAntiAffinity",
×
984
                                                                ),
×
985
                                                        },
×
986
                                                        {
×
987
                                                                DisplayName: "Workloads components node affinity",
×
988
                                                                Description: "nodeAffinity describes node affinity scheduling rules for the workloads pods.",
×
989
                                                                Path:        "workloads.nodePlacement.affinity.nodeAffinity",
×
990
                                                                XDescriptors: stringListToSlice(
×
991
                                                                        "urn:alm:descriptor:com.tectonic.ui:nodeAffinity",
×
992
                                                                ),
×
993
                                                        },
×
994
                                                        {
×
995
                                                                DisplayName: "Workloads components pod affinity",
×
996
                                                                Description: "podAffinity describes pod affinity scheduling rules for the workloads pods.",
×
997
                                                                Path:        "workloads.nodePlacement.affinity.podAffinity",
×
998
                                                                XDescriptors: stringListToSlice(
×
999
                                                                        "urn:alm:descriptor:com.tectonic.ui:podAffinity",
×
1000
                                                                ),
×
1001
                                                        },
×
1002
                                                        {
×
1003
                                                                DisplayName: "Workloads components pod anti-affinity",
×
1004
                                                                Description: "podAntiAffinity describes pod anti affinity scheduling rules for the workloads pods.",
×
1005
                                                                Path:        "workloads.nodePlacement.affinity.podAntiAffinity",
×
1006
                                                                XDescriptors: stringListToSlice(
×
1007
                                                                        "urn:alm:descriptor:com.tectonic.ui:podAntiAffinity",
×
1008
                                                                ),
×
1009
                                                        },
×
1010
                                                        {
×
1011
                                                                DisplayName: "HIDDEN FIELDS - operator version",
×
1012
                                                                Description: "HIDDEN FIELDS - operator version.",
×
1013
                                                                Path:        "version",
×
1014
                                                                XDescriptors: stringListToSlice(
×
1015
                                                                        "urn:alm:descriptor:com.tectonic.ui:hidden",
×
1016
                                                                ),
×
1017
                                                        },
×
1018
                                                },
×
1019
                                                StatusDescriptors: []csvv1alpha1.StatusDescriptor{},
×
1020
                                        },
×
1021
                                },
×
1022
                                Required: []csvv1alpha1.CRDDescription{},
×
1023
                        },
×
1024
                },
×
1025
        }
×
1026
}
×
1027

NEW
1028
func createMutatingHCWebhook(name, apiVersion, path string) csvv1alpha1.WebhookDescription {
×
NEW
1029
        return csvv1alpha1.WebhookDescription{
×
NEW
1030
                GenerateName:            name,
×
NEW
1031
                Type:                    csvv1alpha1.MutatingAdmissionWebhook,
×
NEW
1032
                DeploymentName:          hcoWhDeploymentName,
×
NEW
1033
                ContainerPort:           util.WebhookPort,
×
NEW
1034
                AdmissionReviewVersions: stringListToSlice("v1beta1", "v1"),
×
NEW
1035
                SideEffects:             ptr.To(admissionregistrationv1.SideEffectClassNoneOnDryRun),
×
NEW
1036
                FailurePolicy:           ptr.To(admissionregistrationv1.Fail),
×
NEW
1037
                MatchPolicy:             ptr.To(admissionregistrationv1.Exact),
×
NEW
1038
                TimeoutSeconds:          ptr.To[int32](10),
×
NEW
1039
                Rules: []admissionregistrationv1.RuleWithOperations{
×
NEW
1040
                        {
×
NEW
1041
                                Operations: []admissionregistrationv1.OperationType{
×
NEW
1042
                                        admissionregistrationv1.Create,
×
NEW
1043
                                        admissionregistrationv1.Update,
×
NEW
1044
                                },
×
NEW
1045
                                Rule: admissionregistrationv1.Rule{
×
NEW
1046
                                        APIGroups:   stringListToSlice(util.APIVersionGroup),
×
NEW
1047
                                        APIVersions: stringListToSlice(apiVersion),
×
NEW
1048
                                        Resources:   stringListToSlice("hyperconvergeds"),
×
NEW
1049
                                },
×
NEW
1050
                        },
×
NEW
1051
                },
×
NEW
1052
                WebhookPath: &path,
×
NEW
1053
        }
×
NEW
1054
}
×
1055

NEW
1056
func createMutatingNSWebhook(params *CSVBaseParams) csvv1alpha1.WebhookDescription {
×
NEW
1057
        return csvv1alpha1.WebhookDescription{
×
NEW
1058
                GenerateName:            util.HcoMutatingWebhookNS,
×
NEW
1059
                Type:                    csvv1alpha1.MutatingAdmissionWebhook,
×
NEW
1060
                DeploymentName:          hcoWhDeploymentName,
×
NEW
1061
                ContainerPort:           util.WebhookPort,
×
NEW
1062
                AdmissionReviewVersions: stringListToSlice("v1beta1", "v1"),
×
NEW
1063
                SideEffects:             ptr.To(admissionregistrationv1.SideEffectClassNoneOnDryRun),
×
NEW
1064
                FailurePolicy:           ptr.To(admissionregistrationv1.Fail),
×
NEW
1065
                TimeoutSeconds:          ptr.To[int32](10),
×
NEW
1066
                ObjectSelector: &metav1.LabelSelector{
×
NEW
1067
                        MatchLabels: map[string]string{util.KubernetesMetadataName: params.Namespace},
×
NEW
1068
                },
×
NEW
1069
                Rules: []admissionregistrationv1.RuleWithOperations{
×
NEW
1070
                        {
×
NEW
1071
                                Operations: []admissionregistrationv1.OperationType{
×
NEW
1072
                                        admissionregistrationv1.Delete,
×
NEW
1073
                                },
×
NEW
1074
                                Rule: admissionregistrationv1.Rule{
×
NEW
1075
                                        APIGroups:   []string{""},
×
NEW
1076
                                        APIVersions: stringListToSlice("v1"),
×
NEW
1077
                                        Resources:   stringListToSlice("namespaces"),
×
NEW
1078
                                },
×
NEW
1079
                        },
×
NEW
1080
                },
×
NEW
1081
                WebhookPath: ptr.To(util.HCONSWebhookPath),
×
NEW
1082
        }
×
NEW
1083
}
×
1084

NEW
1085
func createHCValidatingWebhook(name, apiVersion, path string) csvv1alpha1.WebhookDescription {
×
NEW
1086
        return csvv1alpha1.WebhookDescription{
×
NEW
1087
                GenerateName:            name,
×
NEW
1088
                Type:                    csvv1alpha1.ValidatingAdmissionWebhook,
×
NEW
1089
                DeploymentName:          hcoWhDeploymentName,
×
NEW
1090
                ContainerPort:           util.WebhookPort,
×
NEW
1091
                AdmissionReviewVersions: stringListToSlice("v1beta1", "v1"),
×
NEW
1092
                SideEffects:             ptr.To(admissionregistrationv1.SideEffectClassNone),
×
NEW
1093
                FailurePolicy:           ptr.To(admissionregistrationv1.Fail),
×
NEW
1094
                MatchPolicy:             ptr.To(admissionregistrationv1.Exact),
×
NEW
1095
                TimeoutSeconds:          ptr.To[int32](10),
×
NEW
1096
                Rules: []admissionregistrationv1.RuleWithOperations{
×
NEW
1097
                        {
×
NEW
1098
                                Operations: []admissionregistrationv1.OperationType{
×
NEW
1099
                                        admissionregistrationv1.Create,
×
NEW
1100
                                        admissionregistrationv1.Delete,
×
NEW
1101
                                        admissionregistrationv1.Update,
×
NEW
1102
                                },
×
NEW
1103
                                Rule: admissionregistrationv1.Rule{
×
NEW
1104
                                        APIGroups:   stringListToSlice(util.APIVersionGroup),
×
NEW
1105
                                        APIVersions: stringListToSlice(apiVersion),
×
NEW
1106
                                        Resources:   stringListToSlice("hyperconvergeds"),
×
NEW
1107
                                },
×
NEW
1108
                        },
×
NEW
1109
                },
×
NEW
1110
                WebhookPath: ptr.To(path),
×
NEW
1111
        }
×
NEW
1112
}
×
1113

1114
func InjectVolumesForWebHookCerts(deploy *appsv1.Deployment) {
×
1115
        // check if there is already a volume for api certificates
×
1116
        for _, vol := range deploy.Spec.Template.Spec.Volumes {
×
1117
                if vol.Name == certVolume {
×
1118
                        return
×
1119
                }
×
1120
        }
1121

1122
        volume := corev1.Volume{
×
1123
                Name: certVolume,
×
1124
                VolumeSource: corev1.VolumeSource{
×
1125
                        Secret: &corev1.SecretVolumeSource{
×
1126
                                SecretName:  deploy.Name + "-service-cert",
×
1127
                                DefaultMode: ptr.To[int32](420),
×
1128
                                Items: []corev1.KeyToPath{
×
1129
                                        {
×
1130
                                                Key:  "tls.crt",
×
1131
                                                Path: util.WebhookCertName,
×
1132
                                        },
×
1133
                                        {
×
1134
                                                Key:  "tls.key",
×
1135
                                                Path: util.WebhookKeyName,
×
1136
                                        },
×
1137
                                },
×
1138
                        },
×
1139
                },
×
1140
        }
×
1141
        deploy.Spec.Template.Spec.Volumes = append(deploy.Spec.Template.Spec.Volumes, volume)
×
1142

×
1143
        for index, container := range deploy.Spec.Template.Spec.Containers {
×
1144
                deploy.Spec.Template.Spec.Containers[index].VolumeMounts = append(container.VolumeMounts,
×
1145
                        corev1.VolumeMount{
×
1146
                                Name:      certVolume,
×
1147
                                MountPath: util.DefaultWebhookCertDir,
×
1148
                        })
×
1149
        }
×
1150
}
1151

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

1170
func getLivenessProbe(endpoint string, port int32) *corev1.Probe {
×
1171
        return &corev1.Probe{
×
1172
                ProbeHandler: corev1.ProbeHandler{
×
1173
                        HTTPGet: &corev1.HTTPGetAction{
×
1174
                                Path: endpoint,
×
1175
                                Port: intstr.IntOrString{
×
1176
                                        Type:   intstr.Int,
×
1177
                                        IntVal: port,
×
1178
                                },
×
1179
                                Scheme: corev1.URISchemeHTTP,
×
1180
                        },
×
1181
                },
×
1182
                InitialDelaySeconds: 30,
×
1183
                PeriodSeconds:       5,
×
1184
                FailureThreshold:    1,
×
1185
        }
×
1186
}
×
1187

1188
func getMetricsPort() corev1.ContainerPort {
×
1189
        return corev1.ContainerPort{
×
1190
                Name:          util.MetricsPortName,
×
1191
                ContainerPort: util.MetricsPort,
×
1192
                Protocol:      corev1.ProtocolTCP,
×
1193
        }
×
1194
}
×
1195

1196
func getWebhookPort() corev1.ContainerPort {
×
1197
        return corev1.ContainerPort{
×
1198
                Name:          util.WebhookPortName,
×
1199
                ContainerPort: util.WebhookPort,
×
1200
                Protocol:      corev1.ProtocolTCP,
×
1201
        }
×
1202
}
×
1203

1204
func stringListToSlice(words ...string) []string {
×
1205
        return words
×
1206
}
×
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