Skip to content

Commit 5472371

Browse files
authored
feat(api): fix kotsv1beta1 config values need defaults (#2457)
* feat(api): fix kotsv1beta1 config values need defaults * f * f * f * f * f * f
1 parent ae6ccad commit 5472371

File tree

32 files changed

+1140
-634
lines changed

32 files changed

+1140
-634
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,7 @@ jobs:
904904
- check-images
905905
- check-operator-crds
906906
- check-swagger-docs
907-
if: always()
907+
if: ${{ !cancelled() }}
908908
steps:
909909
# https://docs.github.com/en/actions/learn-github-actions/contexts#needs-context
910910
- name: fail if e2e job was not successful

.github/workflows/kinds.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ jobs:
5959
needs:
6060
- lint
6161
- test
62-
if: always()
62+
if: ${{ !cancelled() }}
6363
steps:
6464
- name: succeed if everything passed
6565
run: echo "Validation succeeded"

.github/workflows/release-prod.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -622,7 +622,7 @@ jobs:
622622
- e2e-docker
623623
- release
624624
- release-app
625-
if: always()
625+
if: ${{ !cancelled() }}
626626
steps:
627627
# https://docs.github.com/en/actions/learn-github-actions/contexts#needs-context
628628
- name: fail if e2e job was not successful

.github/workflows/utils.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
needs:
5757
- lint
5858
- test
59-
if: always()
59+
if: ${{ !cancelled() }}
6060
steps:
6161
- name: succeed if everything passed
6262
run: echo "Validation succeeded"

api/controllers/kubernetes/install/controller.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ type InstallController struct {
4646
tlsConfig types.TLSConfig
4747
license []byte
4848
airgapBundle string
49-
configValues string
49+
configValues map[string]string
5050
endUserConfig *ecv1beta1.Config
5151
store store.Store
5252
ki kubernetesinstallation.Installation
@@ -111,7 +111,7 @@ func WithAirgapBundle(airgapBundle string) InstallControllerOption {
111111
}
112112
}
113113

114-
func WithConfigValues(configValues string) InstallControllerOption {
114+
func WithConfigValues(configValues map[string]string) InstallControllerOption {
115115
return func(c *InstallController) {
116116
c.configValues = configValues
117117
}
@@ -164,6 +164,13 @@ func NewInstallController(opts ...InstallControllerOption) (*InstallController,
164164
opt(controller)
165165
}
166166

167+
if controller.configValues != nil {
168+
err := controller.store.AppConfigStore().SetConfigValues(controller.configValues)
169+
if err != nil {
170+
return nil, fmt.Errorf("set app config values: %w", err)
171+
}
172+
}
173+
167174
// If none is provided, use the default env settings from helm to create a RESTClientGetter
168175
if controller.restClientGetter == nil {
169176
controller.restClientGetter = helmcli.New().RESTClientGetter()
@@ -185,7 +192,6 @@ func NewInstallController(opts ...InstallControllerOption) (*InstallController,
185192
infra.WithTLSConfig(controller.tlsConfig),
186193
infra.WithLicense(controller.license),
187194
infra.WithAirgapBundle(controller.airgapBundle),
188-
infra.WithConfigValues(controller.configValues),
189195
infra.WithReleaseData(controller.releaseData),
190196
infra.WithEndUserConfig(controller.endUserConfig),
191197
)

api/controllers/kubernetes/install/controller_test.go

Lines changed: 70 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,18 @@ import (
99
"github.com/stretchr/testify/mock"
1010
"github.com/stretchr/testify/require"
1111

12+
appconfig "github.com/replicatedhq/embedded-cluster/api/internal/managers/app/config"
1213
"github.com/replicatedhq/embedded-cluster/api/internal/managers/kubernetes/infra"
1314
"github.com/replicatedhq/embedded-cluster/api/internal/managers/kubernetes/installation"
1415
"github.com/replicatedhq/embedded-cluster/api/internal/statemachine"
1516
"github.com/replicatedhq/embedded-cluster/api/internal/store"
1617
"github.com/replicatedhq/embedded-cluster/api/types"
18+
ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1"
1719
"github.com/replicatedhq/embedded-cluster/pkg/kubernetesinstallation"
1820
"github.com/replicatedhq/embedded-cluster/pkg/metrics"
21+
"github.com/replicatedhq/embedded-cluster/pkg/release"
22+
kotsv1beta1 "github.com/replicatedhq/kotskinds/apis/kots/v1beta1"
23+
"github.com/replicatedhq/kotskinds/multitype"
1924
)
2025

2126
func TestGetInstallationConfig(t *testing.T) {
@@ -253,20 +258,49 @@ func TestGetInstallationStatus(t *testing.T) {
253258
}
254259

255260
func TestSetupInfra(t *testing.T) {
261+
// Create an app config
262+
appConfig := kotsv1beta1.Config{
263+
Spec: kotsv1beta1.ConfigSpec{
264+
Groups: []kotsv1beta1.ConfigGroup{
265+
{
266+
Name: "test-group",
267+
Title: "Test Group",
268+
Items: []kotsv1beta1.ConfigItem{
269+
{
270+
Name: "test-item",
271+
Type: "text",
272+
Title: "Test Item",
273+
Default: multitype.BoolOrString{StrVal: "default"},
274+
Value: multitype.BoolOrString{StrVal: "value"},
275+
},
276+
},
277+
},
278+
},
279+
},
280+
}
281+
configValues := kotsv1beta1.ConfigValues{
282+
Spec: kotsv1beta1.ConfigValuesSpec{
283+
Values: map[string]kotsv1beta1.ConfigValue{
284+
"test-item": {Default: "default", Value: "value"},
285+
},
286+
},
287+
}
288+
256289
tests := []struct {
257290
name string
258291
currentState statemachine.State
259292
expectedState statemachine.State
260-
setupMocks func(kubernetesinstallation.Installation, *installation.MockInstallationManager, *infra.MockInfraManager, *metrics.MockReporter, *store.MockStore)
293+
setupMocks func(kubernetesinstallation.Installation, *installation.MockInstallationManager, *infra.MockInfraManager, *metrics.MockReporter, *store.MockStore, *appconfig.MockAppConfigManager)
261294
expectedErr error
262295
}{
263296
{
264297
name: "successful setup",
265298
currentState: StateInstallationConfigured,
266299
expectedState: StateSucceeded,
267-
setupMocks: func(ki kubernetesinstallation.Installation, im *installation.MockInstallationManager, fm *infra.MockInfraManager, mr *metrics.MockReporter, st *store.MockStore) {
300+
setupMocks: func(ki kubernetesinstallation.Installation, im *installation.MockInstallationManager, fm *infra.MockInfraManager, mr *metrics.MockReporter, st *store.MockStore, am *appconfig.MockAppConfigManager) {
268301
mock.InOrder(
269-
fm.On("Install", mock.Anything, ki).Return(nil),
302+
am.On("GetKotsadmConfigValues", appConfig).Return(configValues, nil),
303+
fm.On("Install", mock.Anything, ki, configValues).Return(nil),
270304
// TODO: we are not yet reporting
271305
// mr.On("ReportInstallationSucceeded", mock.Anything),
272306
)
@@ -277,9 +311,10 @@ func TestSetupInfra(t *testing.T) {
277311
name: "install infra error",
278312
currentState: StateInstallationConfigured,
279313
expectedState: StateInfrastructureInstallFailed,
280-
setupMocks: func(ki kubernetesinstallation.Installation, im *installation.MockInstallationManager, fm *infra.MockInfraManager, mr *metrics.MockReporter, st *store.MockStore) {
314+
setupMocks: func(ki kubernetesinstallation.Installation, im *installation.MockInstallationManager, fm *infra.MockInfraManager, mr *metrics.MockReporter, st *store.MockStore, am *appconfig.MockAppConfigManager) {
281315
mock.InOrder(
282-
fm.On("Install", mock.Anything, ki).Return(errors.New("install error")),
316+
am.On("GetKotsadmConfigValues", appConfig).Return(configValues, nil),
317+
fm.On("Install", mock.Anything, ki, configValues).Return(errors.New("install error")),
283318
st.LinuxInfraMockStore.On("GetStatus").Return(types.Status{Description: "install error"}, nil),
284319
// TODO: we are not yet reporting
285320
// mr.On("ReportInstallationFailed", mock.Anything, errors.New("install error")),
@@ -291,9 +326,10 @@ func TestSetupInfra(t *testing.T) {
291326
name: "install infra error without report if infra store fails",
292327
currentState: StateInstallationConfigured,
293328
expectedState: StateInfrastructureInstallFailed,
294-
setupMocks: func(ki kubernetesinstallation.Installation, im *installation.MockInstallationManager, fm *infra.MockInfraManager, mr *metrics.MockReporter, st *store.MockStore) {
329+
setupMocks: func(ki kubernetesinstallation.Installation, im *installation.MockInstallationManager, fm *infra.MockInfraManager, mr *metrics.MockReporter, st *store.MockStore, am *appconfig.MockAppConfigManager) {
295330
mock.InOrder(
296-
fm.On("Install", mock.Anything, ki).Return(errors.New("install error")),
331+
am.On("GetKotsadmConfigValues", appConfig).Return(configValues, nil),
332+
fm.On("Install", mock.Anything, ki, configValues).Return(errors.New("install error")),
297333
st.LinuxInfraMockStore.On("GetStatus").Return(nil, assert.AnError),
298334
)
299335
},
@@ -303,9 +339,10 @@ func TestSetupInfra(t *testing.T) {
303339
name: "install infra panic",
304340
currentState: StateInstallationConfigured,
305341
expectedState: StateInfrastructureInstallFailed,
306-
setupMocks: func(ki kubernetesinstallation.Installation, im *installation.MockInstallationManager, fm *infra.MockInfraManager, mr *metrics.MockReporter, st *store.MockStore) {
342+
setupMocks: func(ki kubernetesinstallation.Installation, im *installation.MockInstallationManager, fm *infra.MockInfraManager, mr *metrics.MockReporter, st *store.MockStore, am *appconfig.MockAppConfigManager) {
307343
mock.InOrder(
308-
fm.On("Install", mock.Anything, ki).Panic("this is a panic"),
344+
am.On("GetKotsadmConfigValues", appConfig).Return(configValues, nil),
345+
fm.On("Install", mock.Anything, ki, configValues).Panic("this is a panic"),
309346
st.LinuxInfraMockStore.On("GetStatus").Return(types.Status{Description: "this is a panic"}, nil),
310347
// TODO: we are not yet reporting
311348
// mr.On("ReportInstallationFailed", mock.Anything, errors.New("this is a panic")),
@@ -317,10 +354,21 @@ func TestSetupInfra(t *testing.T) {
317354
name: "invalid state transition",
318355
currentState: StateNew,
319356
expectedState: StateNew,
320-
setupMocks: func(ki kubernetesinstallation.Installation, im *installation.MockInstallationManager, fm *infra.MockInfraManager, mr *metrics.MockReporter, st *store.MockStore) {
357+
setupMocks: func(ki kubernetesinstallation.Installation, im *installation.MockInstallationManager, fm *infra.MockInfraManager, mr *metrics.MockReporter, st *store.MockStore, am *appconfig.MockAppConfigManager) {
321358
},
322359
expectedErr: assert.AnError, // Just check that an error occurs, don't care about exact message
323360
},
361+
{
362+
name: "config values error",
363+
currentState: StateInstallationConfigured,
364+
expectedState: StateInstallationConfigured,
365+
setupMocks: func(ki kubernetesinstallation.Installation, im *installation.MockInstallationManager, fm *infra.MockInfraManager, mr *metrics.MockReporter, st *store.MockStore, am *appconfig.MockAppConfigManager) {
366+
mock.InOrder(
367+
am.On("GetKotsadmConfigValues", appConfig).Return(kotsv1beta1.ConfigValues{}, assert.AnError),
368+
)
369+
},
370+
expectedErr: assert.AnError,
371+
},
324372
}
325373

326374
for _, tt := range tests {
@@ -334,14 +382,17 @@ func TestSetupInfra(t *testing.T) {
334382
mockInfraManager := &infra.MockInfraManager{}
335383
mockMetricsReporter := &metrics.MockReporter{}
336384
mockStore := &store.MockStore{}
337-
tt.setupMocks(ki, mockInstallationManager, mockInfraManager, mockMetricsReporter, mockStore)
385+
mockAppConfigManager := &appconfig.MockAppConfigManager{}
386+
tt.setupMocks(ki, mockInstallationManager, mockInfraManager, mockMetricsReporter, mockStore, mockAppConfigManager)
338387

339388
controller, err := NewInstallController(
340389
WithInstallation(ki),
341390
WithStateMachine(sm),
342391
WithInstallationManager(mockInstallationManager),
343392
WithInfraManager(mockInfraManager),
393+
WithAppConfigManager(mockAppConfigManager),
344394
WithMetricsReporter(mockMetricsReporter),
395+
WithReleaseData(getTestReleaseData(&appConfig)),
345396
WithStore(mockStore),
346397
)
347398
require.NoError(t, err)
@@ -451,3 +502,11 @@ func TestGetInfra(t *testing.T) {
451502
})
452503
}
453504
}
505+
506+
func getTestReleaseData(appConfig *kotsv1beta1.Config) *release.ReleaseData {
507+
return &release.ReleaseData{
508+
EmbeddedClusterConfig: &ecv1beta1.Config{},
509+
ChannelRelease: &release.ChannelRelease{},
510+
AppConfig: appConfig,
511+
}
512+
}

api/controllers/kubernetes/install/infra.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,18 @@ package install
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"runtime/debug"
78

89
"github.com/replicatedhq/embedded-cluster/api/types"
910
)
1011

1112
func (c *InstallController) SetupInfra(ctx context.Context) (finalErr error) {
13+
if c.releaseData == nil || c.releaseData.AppConfig == nil {
14+
return errors.New("app config not found")
15+
}
16+
1217
lock, err := c.stateMachine.AcquireLock()
1318
if err != nil {
1419
return types.NewConflictError(err)
@@ -23,6 +28,11 @@ func (c *InstallController) SetupInfra(ctx context.Context) (finalErr error) {
2328
}
2429
}()
2530

31+
configValues, err := c.appConfigManager.GetKotsadmConfigValues(*c.releaseData.AppConfig)
32+
if err != nil {
33+
return fmt.Errorf("failed to get kotsadm config values: %w", err)
34+
}
35+
2636
err = c.stateMachine.Transition(lock, StateInfrastructureInstalling)
2737
if err != nil {
2838
return types.NewConflictError(err)
@@ -51,7 +61,7 @@ func (c *InstallController) SetupInfra(ctx context.Context) (finalErr error) {
5161
}
5262
}()
5363

54-
if err := c.infraManager.Install(ctx, c.ki); err != nil {
64+
if err := c.infraManager.Install(ctx, c.ki, configValues); err != nil {
5565
return fmt.Errorf("failed to install infrastructure: %w", err)
5666
}
5767

api/controllers/linux/install/controller.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package install
22

33
import (
44
"context"
5+
"fmt"
56
"sync"
67

78
appconfig "github.com/replicatedhq/embedded-cluster/api/internal/managers/app/config"
@@ -56,7 +57,7 @@ type InstallController struct {
5657
tlsConfig types.TLSConfig
5758
license []byte
5859
airgapBundle string
59-
configValuesFile string
60+
configValues map[string]string
6061
endUserConfig *ecv1beta1.Config
6162
clusterID string
6263
store store.Store
@@ -129,9 +130,9 @@ func WithAirgapBundle(airgapBundle string) InstallControllerOption {
129130
}
130131
}
131132

132-
func WithConfigValuesFile(configValuesFile string) InstallControllerOption {
133+
func WithConfigValues(configValues map[string]string) InstallControllerOption {
133134
return func(c *InstallController) {
134-
c.configValuesFile = configValuesFile
135+
c.configValues = configValues
135136
}
136137
}
137138

@@ -200,6 +201,13 @@ func NewInstallController(opts ...InstallControllerOption) (*InstallController,
200201
opt(controller)
201202
}
202203

204+
if controller.configValues != nil {
205+
err := controller.store.AppConfigStore().SetConfigValues(controller.configValues)
206+
if err != nil {
207+
return nil, fmt.Errorf("set app config values: %w", err)
208+
}
209+
}
210+
203211
if controller.stateMachine == nil {
204212
controller.stateMachine = NewStateMachine(WithStateMachineLogger(controller.logger))
205213
}
@@ -248,7 +256,6 @@ func NewInstallController(opts ...InstallControllerOption) (*InstallController,
248256
infra.WithTLSConfig(controller.tlsConfig),
249257
infra.WithLicense(controller.license),
250258
infra.WithAirgapBundle(controller.airgapBundle),
251-
infra.WithConfigValuesFile(controller.configValuesFile), // CLI file path
252259
infra.WithReleaseData(controller.releaseData),
253260
infra.WithEndUserConfig(controller.endUserConfig),
254261
infra.WithClusterID(controller.clusterID),

0 commit comments

Comments
 (0)