cli: state file validation (#2523)

* re-use `ReadFromFile` in `CreateOrRead`

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* [wip]: add constraints

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* [wip] error formatting

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* wip

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* formatted error messages

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* state file validation

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* linter fixes

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* allow overriding the constraints

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* dont validate on read

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* add pre-create constraints

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* [wip]

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* finish pre-init validation test

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* finish post-init validation

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* use state file validation in CLI

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* fix apply tests

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* Update internal/validation/errors.go

Co-authored-by: Daniel Weiße <66256922+daniel-weisse@users.noreply.github.com>

* use transformator for tests

* tidy

* use empty check directly

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* Update cli/internal/state/state.go

Co-authored-by: Daniel Weiße <66256922+daniel-weisse@users.noreply.github.com>

* Update cli/internal/state/state.go

Co-authored-by: Daniel Weiße <66256922+daniel-weisse@users.noreply.github.com>

* Update cli/internal/state/state.go

Co-authored-by: Daniel Weiße <66256922+daniel-weisse@users.noreply.github.com>

* Update cli/internal/state/state.go

Co-authored-by: Daniel Weiße <66256922+daniel-weisse@users.noreply.github.com>

* conditional validation per CSP

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* tidy

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* fix rebase

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* add default case

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* validate state-file as last input

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

---------

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>
Co-authored-by: Daniel Weiße <66256922+daniel-weisse@users.noreply.github.com>
This commit is contained in:
Moritz Sanft 2023-11-03 15:47:03 +01:00 committed by GitHub
parent eaec73cca4
commit 744a605602
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 1779 additions and 247 deletions

View file

@ -33,18 +33,10 @@ import (
)
func TestUpgradeApply(t *testing.T) {
defaultState := state.New().
SetInfrastructure(state.Infrastructure{
APIServerCertSANs: []string{},
UID: "uid",
Name: "kubernetes-uid", // default test cfg uses "kubernetes" prefix
InitSecret: []byte{0x42},
}).
SetClusterValues(state.ClusterValues{MeasurementSalt: []byte{0x41}})
fsWithStateFileAndTfState := func() file.Handler {
fh := file.NewHandler(afero.NewMemMapFs())
require.NoError(t, fh.MkdirAll(constants.TerraformWorkingDir))
require.NoError(t, fh.WriteYAML(constants.StateFilename, defaultState))
require.NoError(t, fh.WriteYAML(constants.StateFilename, defaultAzureStateFile()))
return fh
}
@ -63,20 +55,20 @@ func TestUpgradeApply(t *testing.T) {
kubeUpgrader: &stubKubernetesUpgrader{currentConfig: config.DefaultForAzureSEVSNP()},
helmUpgrader: stubApplier{},
terraformUpgrader: &stubTerraformUpgrader{},
flags: applyFlags{yes: true},
flags: applyFlags{yes: true, skipPhases: skipPhases{skipInitPhase: struct{}{}}},
fh: fsWithStateFileAndTfState,
fhAssertions: func(require *require.Assertions, assert *assert.Assertions, fh file.Handler) {
gotState, err := state.ReadFromFile(fh, constants.StateFilename)
require.NoError(err)
assert.Equal("v1", gotState.Version)
assert.Equal(defaultState, gotState)
assert.Equal(defaultAzureStateFile(), gotState)
},
},
"id file and state file do not exist": {
kubeUpgrader: &stubKubernetesUpgrader{currentConfig: config.DefaultForAzureSEVSNP()},
helmUpgrader: stubApplier{},
terraformUpgrader: &stubTerraformUpgrader{},
flags: applyFlags{yes: true},
flags: applyFlags{yes: true, skipPhases: skipPhases{skipInitPhase: struct{}{}}},
fh: func() file.Handler {
return file.NewHandler(afero.NewMemMapFs())
},
@ -90,7 +82,7 @@ func TestUpgradeApply(t *testing.T) {
helmUpgrader: stubApplier{},
terraformUpgrader: &stubTerraformUpgrader{},
wantErr: true,
flags: applyFlags{yes: true},
flags: applyFlags{yes: true, skipPhases: skipPhases{skipInitPhase: struct{}{}}},
fh: fsWithStateFileAndTfState,
},
"nodeVersion in progress error": {
@ -100,7 +92,7 @@ func TestUpgradeApply(t *testing.T) {
},
helmUpgrader: stubApplier{},
terraformUpgrader: &stubTerraformUpgrader{},
flags: applyFlags{yes: true},
flags: applyFlags{yes: true, skipPhases: skipPhases{skipInitPhase: struct{}{}}},
fh: fsWithStateFileAndTfState,
},
"helm other error": {
@ -110,7 +102,7 @@ func TestUpgradeApply(t *testing.T) {
helmUpgrader: stubApplier{err: assert.AnError},
terraformUpgrader: &stubTerraformUpgrader{},
wantErr: true,
flags: applyFlags{yes: true},
flags: applyFlags{yes: true, skipPhases: skipPhases{skipInitPhase: struct{}{}}},
fh: fsWithStateFileAndTfState,
},
"abort": {
@ -140,7 +132,7 @@ func TestUpgradeApply(t *testing.T) {
helmUpgrader: stubApplier{},
terraformUpgrader: &stubTerraformUpgrader{planTerraformErr: assert.AnError},
wantErr: true,
flags: applyFlags{yes: true},
flags: applyFlags{yes: true, skipPhases: skipPhases{skipInitPhase: struct{}{}}},
fh: fsWithStateFileAndTfState,
},
"apply terraform error": {
@ -153,7 +145,7 @@ func TestUpgradeApply(t *testing.T) {
terraformDiff: true,
},
wantErr: true,
flags: applyFlags{yes: true},
flags: applyFlags{yes: true, skipPhases: skipPhases{skipInitPhase: struct{}{}}},
fh: fsWithStateFileAndTfState,
},
"outdated K8s patch version": {
@ -167,7 +159,7 @@ func TestUpgradeApply(t *testing.T) {
require.NoError(t, err)
return semver.NewFromInt(v.Major(), v.Minor(), v.Patch()-1, "").String()
}(),
flags: applyFlags{yes: true},
flags: applyFlags{yes: true, skipPhases: skipPhases{skipInitPhase: struct{}{}}},
fh: fsWithStateFileAndTfState,
},
"outdated K8s version": {
@ -177,7 +169,7 @@ func TestUpgradeApply(t *testing.T) {
helmUpgrader: stubApplier{},
terraformUpgrader: &stubTerraformUpgrader{},
customK8sVersion: "v1.20.0",
flags: applyFlags{yes: true},
flags: applyFlags{yes: true, skipPhases: skipPhases{skipInitPhase: struct{}{}}},
wantErr: true,
fh: fsWithStateFileAndTfState,
},
@ -191,6 +183,7 @@ func TestUpgradeApply(t *testing.T) {
skipPhases: skipPhases{
skipInfrastructurePhase: struct{}{}, skipHelmPhase: struct{}{},
skipK8sPhase: struct{}{}, skipImagePhase: struct{}{},
skipInitPhase: struct{}{},
},
yes: true,
},
@ -205,7 +198,7 @@ func TestUpgradeApply(t *testing.T) {
flags: applyFlags{
skipPhases: skipPhases{
skipInfrastructurePhase: struct{}{}, skipHelmPhase: struct{}{},
skipK8sPhase: struct{}{},
skipK8sPhase: struct{}{}, skipInitPhase: struct{}{},
},
yes: true,
},
@ -219,10 +212,13 @@ func TestUpgradeApply(t *testing.T) {
terraformUpgrader: &mockTerraformUpgrader{},
flags: applyFlags{
yes: true,
skipPhases: skipPhases{
skipInitPhase: struct{}{},
},
},
fh: func() file.Handler {
fh := file.NewHandler(afero.NewMemMapFs())
require.NoError(t, fh.WriteYAML(constants.StateFilename, defaultState))
require.NoError(t, fh.WriteYAML(constants.StateFilename, defaultAzureStateFile()))
return fh
},
},
@ -230,7 +226,7 @@ func TestUpgradeApply(t *testing.T) {
kubeUpgrader: &stubKubernetesUpgrader{currentConfig: &config.AzureTrustedLaunch{}},
helmUpgrader: stubApplier{},
terraformUpgrader: &stubTerraformUpgrader{},
flags: applyFlags{yes: true},
flags: applyFlags{yes: true, skipPhases: skipPhases{skipInitPhase: struct{}{}}},
fh: fsWithStateFileAndTfState,
wantErr: true,
},