Skip to content

Commit a98ea43

Browse files
authored
feat(module): add migration disable tls annotation support (#2198)
Add support for enabling and disabling KubeVirt live migration TLS via a temporary annotation on ModuleConfig/virtualization. The change introduces parsing of the virtualization.deckhouse.io/disable-tls annotation in the module hook, stores the effective value in internal module values, passes it to the rendered KubeVirt migration configuration, and propagates it to the migration configuration injected into KVVMI status. --------- Signed-off-by: Daniil Antoshin <daniil.antoshin@flant.com>
1 parent f389570 commit a98ea43

7 files changed

Lines changed: 93 additions & 1 deletion

File tree

images/hooks/pkg/hooks/migration-config/hook.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"context"
2121
"fmt"
2222
"strconv"
23+
"strings"
2324

2425
"k8s.io/utils/ptr"
2526

@@ -36,16 +37,19 @@ const (
3637
completionTimeoutPerGiBAnnotation = "virtualization.deckhouse.io/completion-timeout-per-gib"
3738
parallelOutboundMigrationsPerNodeAnnotation = "virtualization.deckhouse.io/parallel-outbound-migrations-per-node"
3839
progressTimeoutAnnotation = "virtualization.deckhouse.io/progress-timeout"
40+
disableTLSAnnotation = "virtualization.deckhouse.io/disable-tls"
3941

4042
bandwidthPerMigrationValuesPath = "virtualization.internal.virtConfig.bandwidthPerMigration"
4143
completionTimeoutPerGiBValuesPath = "virtualization.internal.virtConfig.completionTimeoutPerGiB"
4244
parallelOutboundMigrationsPerNodeValuesPath = "virtualization.internal.virtConfig.parallelOutboundMigrationsPerNode"
4345
progressTimeoutValuesPath = "virtualization.internal.virtConfig.progressTimeout"
46+
disableTLSValuesPath = "virtualization.internal.virtConfig.disableTLS"
4447

4548
defaultBandwidthPerMigration = "640Mi"
4649
defaultCompletionTimeoutPerGiB = 800
4750
defaultParallelOutboundMigrationsPerNode = 1
4851
defaultProgressTimeout = 150
52+
defaultDisableTLS = false
4953
)
5054

5155
// migrationParams defines migration parameters configurable via ModuleConfig annotations.
@@ -72,6 +76,11 @@ var migrationParams = []migrationParam{
7276
valuesPath: progressTimeoutValuesPath,
7377
defaultValue: defaultProgressTimeout,
7478
},
79+
{
80+
annotation: disableTLSAnnotation,
81+
valuesPath: disableTLSValuesPath,
82+
defaultValue: defaultDisableTLS,
83+
},
7584
}
7685

7786
type migrationParam struct {
@@ -87,6 +96,12 @@ func (p migrationParam) resolve(annos map[string]string) (any, error) {
8796
}
8897

8998
switch p.defaultValue.(type) {
99+
case bool:
100+
v, err := strconv.ParseBool(strings.ToLower(val))
101+
if err != nil {
102+
return nil, fmt.Errorf("failed to parse %q annotation: %w", p.annotation, err)
103+
}
104+
return v, nil
90105
case int:
91106
v, err := strconv.Atoi(val)
92107
if err != nil {
@@ -102,6 +117,8 @@ func (p migrationParam) resolve(annos map[string]string) (any, error) {
102117

103118
func (p migrationParam) getCurrent(input *pkg.HookInput) any {
104119
switch p.defaultValue.(type) {
120+
case bool:
121+
return input.Values.Get(p.valuesPath).Bool()
105122
case int:
106123
return int(input.Values.Get(p.valuesPath).Int())
107124
case string:

images/hooks/pkg/hooks/migration-config/hook_test.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ var _ = Describe("MigrationConfig", func() {
8484
completionTimeoutPerGiBAnnotation: "1200",
8585
parallelOutboundMigrationsPerNodeAnnotation: "5",
8686
progressTimeoutAnnotation: "300",
87+
disableTLSAnnotation: "true",
8788
}))
8889

8990
values.GetMock.Set(func(path string) gjson.Result {
@@ -96,6 +97,8 @@ var _ = Describe("MigrationConfig", func() {
9697
return gjson.Result{Type: gjson.Number, Num: defaultParallelOutboundMigrationsPerNode}
9798
case progressTimeoutValuesPath:
9899
return gjson.Result{Type: gjson.Number, Num: defaultProgressTimeout}
100+
case disableTLSValuesPath:
101+
return gjson.Result{Type: gjson.False}
99102
}
100103
return gjson.Result{}
101104
})
@@ -111,6 +114,7 @@ var _ = Describe("MigrationConfig", func() {
111114
Expect(setValues).To(HaveKeyWithValue(completionTimeoutPerGiBValuesPath, 1200))
112115
Expect(setValues).To(HaveKeyWithValue(parallelOutboundMigrationsPerNodeValuesPath, 5))
113116
Expect(setValues).To(HaveKeyWithValue(progressTimeoutValuesPath, 300))
117+
Expect(setValues).To(HaveKeyWithValue(disableTLSValuesPath, true))
114118
})
115119

116120
It("Should set defaults when no annotations present", func() {
@@ -126,6 +130,8 @@ var _ = Describe("MigrationConfig", func() {
126130
return gjson.Result{Type: gjson.Number, Num: 9999}
127131
case progressTimeoutValuesPath:
128132
return gjson.Result{Type: gjson.Number, Num: 9999}
133+
case disableTLSValuesPath:
134+
return gjson.Result{Type: gjson.True}
129135
}
130136
return gjson.Result{}
131137
})
@@ -141,6 +147,7 @@ var _ = Describe("MigrationConfig", func() {
141147
Expect(setValues).To(HaveKeyWithValue(completionTimeoutPerGiBValuesPath, defaultCompletionTimeoutPerGiB))
142148
Expect(setValues).To(HaveKeyWithValue(parallelOutboundMigrationsPerNodeValuesPath, defaultParallelOutboundMigrationsPerNode))
143149
Expect(setValues).To(HaveKeyWithValue(progressTimeoutValuesPath, defaultProgressTimeout))
150+
Expect(setValues).To(HaveKeyWithValue(disableTLSValuesPath, defaultDisableTLS))
144151
})
145152

146153
It("Should not set values when current matches target", func() {
@@ -149,6 +156,7 @@ var _ = Describe("MigrationConfig", func() {
149156
completionTimeoutPerGiBAnnotation: "800",
150157
parallelOutboundMigrationsPerNodeAnnotation: "1",
151158
progressTimeoutAnnotation: "150",
159+
disableTLSAnnotation: "false",
152160
}))
153161

154162
values.GetMock.Set(func(path string) gjson.Result {
@@ -161,6 +169,8 @@ var _ = Describe("MigrationConfig", func() {
161169
return gjson.Result{Type: gjson.Number, Num: defaultParallelOutboundMigrationsPerNode}
162170
case progressTimeoutValuesPath:
163171
return gjson.Result{Type: gjson.Number, Num: defaultProgressTimeout}
172+
case disableTLSValuesPath:
173+
return gjson.Result{Type: gjson.False}
164174
}
165175
return gjson.Result{}
166176
})
@@ -175,6 +185,8 @@ var _ = Describe("MigrationConfig", func() {
175185

176186
values.GetMock.Set(func(path string) gjson.Result {
177187
switch path {
188+
case disableTLSValuesPath:
189+
return gjson.Result{Type: gjson.False}
178190
case bandwidthPerMigrationValuesPath:
179191
return gjson.Result{Type: gjson.String, Str: defaultBandwidthPerMigration}
180192
default:
@@ -189,6 +201,35 @@ var _ = Describe("MigrationConfig", func() {
189201
))))
190202
})
191203

204+
It("Should fail on invalid boolean annotation", func() {
205+
setSnapshots(newSnapshot(map[string]string{
206+
disableTLSAnnotation: "not-a-bool",
207+
}))
208+
209+
values.GetMock.Set(func(path string) gjson.Result {
210+
switch path {
211+
case bandwidthPerMigrationValuesPath:
212+
return gjson.Result{Type: gjson.String, Str: defaultBandwidthPerMigration}
213+
case completionTimeoutPerGiBValuesPath:
214+
return gjson.Result{Type: gjson.Number, Num: defaultCompletionTimeoutPerGiB}
215+
case parallelOutboundMigrationsPerNodeValuesPath:
216+
return gjson.Result{Type: gjson.Number, Num: defaultParallelOutboundMigrationsPerNode}
217+
case progressTimeoutValuesPath:
218+
return gjson.Result{Type: gjson.Number, Num: defaultProgressTimeout}
219+
case disableTLSValuesPath:
220+
return gjson.Result{Type: gjson.False}
221+
default:
222+
return gjson.Result{}
223+
}
224+
})
225+
226+
err := reconcile(context.Background(), newInput())
227+
Expect(err).To(MatchError(ContainSubstring(fmt.Sprintf(
228+
"failed to parse %q annotation:",
229+
disableTLSAnnotation,
230+
))))
231+
})
232+
192233
It("Should set only one param from annotation and defaults for the rest", func() {
193234
setSnapshots(newSnapshot(map[string]string{
194235
parallelOutboundMigrationsPerNodeAnnotation: "5",
@@ -204,6 +245,8 @@ var _ = Describe("MigrationConfig", func() {
204245
return gjson.Result{Type: gjson.Number, Num: defaultParallelOutboundMigrationsPerNode}
205246
case progressTimeoutValuesPath:
206247
return gjson.Result{Type: gjson.Number, Num: defaultProgressTimeout}
248+
case disableTLSValuesPath:
249+
return gjson.Result{Type: gjson.False}
207250
}
208251
return gjson.Result{}
209252
})

images/virtualization-artifact/pkg/controller/livemigration/internal/dynamic_settings_handler_test.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,26 @@ var _ = Describe("TestDynamicSettingsHandler", func() {
108108

109109
Expect(kvvmi.Status.MigrationState.MigrationConfiguration).ShouldNot(BeNil(), "Should set migrationConfiguration")
110110
})
111+
112+
It("Should propagate DisableTLS from KubeVirt config", func() {
113+
vm := newVM()
114+
kvvmi := newKVVMI()
115+
kvvmi.Status.MigrationState = &virtv1.VirtualMachineInstanceMigrationState{}
116+
117+
kvConfig := newKVConfig()
118+
kvConfig.Spec.Configuration.MigrationConfiguration = &virtv1.MigrationConfiguration{
119+
DisableTLS: ptr.To(true),
120+
}
121+
122+
fakeClient := setupEnvironment(kvvmi, vm, kvConfig)
123+
h := NewDynamicSettingsHandler(fakeClient)
124+
_, err := h.Handle(ctx, kvvmi)
125+
Expect(err).NotTo(HaveOccurred())
126+
127+
Expect(kvvmi.Status.MigrationState.MigrationConfiguration).ShouldNot(BeNil(), "Should set migrationConfiguration")
128+
Expect(kvvmi.Status.MigrationState.MigrationConfiguration.DisableTLS).ShouldNot(BeNil(), "Should propagate DisableTLS")
129+
Expect(*kvvmi.Status.MigrationState.MigrationConfiguration.DisableTLS).To(BeTrue())
130+
})
111131
})
112132

113133
When("Observe KVVMI with completed migration", func() {

images/virtualization-artifact/pkg/livemigration/migration_configuration.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ func NewMigrationConfiguration(allowAutoConverge bool, kvconfig virtv1.KubeVirt)
6363
progressTimeout := MigrationProgressTimeout
6464
completionTimeoutPerGiB := MigrationCompletionTimeoutPerGiB
6565
defaultUnsafeMigrationOverride := DefaultUnsafeMigrationOverride
66+
disableTLS := false
67+
if kvconfig.Spec.Configuration.MigrationConfiguration != nil && kvconfig.Spec.Configuration.MigrationConfiguration.DisableTLS != nil {
68+
disableTLS = *kvconfig.Spec.Configuration.MigrationConfiguration.DisableTLS
69+
}
6670
allowPostCopy := MigrationAllowPostCopy
6771
allowWorkloadDisruption := MigrationAllowWorkloadDisruption
6872

@@ -77,7 +81,7 @@ func NewMigrationConfiguration(allowAutoConverge bool, kvconfig virtv1.KubeVirt)
7781
AllowAutoConverge: &allowAutoConverge,
7882
AllowPostCopy: &allowPostCopy,
7983
AllowWorkloadDisruption: &allowWorkloadDisruption,
80-
DisableTLS: nil,
84+
DisableTLS: &disableTLS,
8185
Network: nil,
8286
MatchSELinuxLevelOnMigration: nil,
8387
}

openapi/values.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ properties:
141141
type: integer
142142
progressTimeout:
143143
type: integer
144+
disableTLS:
145+
type: boolean
144146
moduleConfig:
145147
type: object
146148
additionalProperties: true

templates/kubevirt/_kubevirt_helpers.tpl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,14 @@ spec:
102102
{{- .Values.virtualization.internal | dig "virtConfig" "progressTimeout" 150 -}}
103103
{{- end -}}
104104

105+
{{- define "kubevirt.disable_tls" -}}
106+
{{- .Values.virtualization.internal | dig "virtConfig" "disableTLS" false -}}
107+
{{- end -}}
108+
105109
{{- define "kubevirt.migrations" -}}
106110
bandwidthPerMigration: {{ include "kubevirt.bandwidth_per_migration" . }}
107111
completionTimeoutPerGiB: {{ include "kubevirt.completion_timeout_per_gib" . }}
112+
disableTLS: {{ include "kubevirt.disable_tls" . }}
108113
parallelMigrationsPerCluster: {{ include "kubevirt.parallel_migrations_per_cluster" . }}
109114
parallelOutboundMigrationsPerNode: {{ include "kubevirt.parallel_outbound_migrations_per_node" . }}
110115
progressTimeout: {{ include "kubevirt.progress_timeout" . }}

tools/kubeconform/fixtures/module-values.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,7 @@ virtualization:
403403
phase: Deployed
404404
bandwidthPerMigration: 640Mi
405405
completionTimeoutPerGiB: 800
406+
disableTLS: false
406407
parallelMigrationsPerCluster: 2
407408
parallelOutboundMigrationsPerNode: 10
408409
progressTimeout: 150

0 commit comments

Comments
 (0)