From 594e3ced3fa521be2feea06d750957e734785e77 Mon Sep 17 00:00:00 2001 From: Thorsten Klein Date: Wed, 13 Oct 2021 21:05:35 +0200 Subject: [PATCH] config: fix failing v1alpha2 -> v1alpha3 migration (#799) - add validation as extra step after migration - add missing json struct tags to new v1alpha3 config fields - add unit tests - add missing `omitempty` tags to configs to avoid (un-)marshalling issues - drop `string` type for `time.Duration` type field in JSON Schema (doesn't work properly sometimes due to broken handling of time.Duration as per https://github.com/golang/go/issues/10275) --- pkg/config/jsonschema.go | 7 +- pkg/config/migrate.go | 16 ++- pkg/config/migrate_test.go | 76 ++++++++++++ ...config_test_simple_migration_v1alpha2.yaml | 51 ++++++++ ...config_test_simple_migration_v1alpha3.yaml | 55 +++++++++ pkg/config/v1alpha2/types.go | 74 ++++++------ pkg/config/v1alpha3/schema.json | 1 - pkg/config/v1alpha3/types.go | 110 +++++++++--------- tests/assets/config_test_simple.yaml | 1 - ...config_test_simple_migration_v1alpha3.yaml | 1 - 10 files changed, 295 insertions(+), 97 deletions(-) create mode 100644 pkg/config/migrate_test.go create mode 100755 pkg/config/test_assets/config_test_simple_migration_v1alpha2.yaml create mode 100755 pkg/config/test_assets/config_test_simple_migration_v1alpha3.yaml diff --git a/pkg/config/jsonschema.go b/pkg/config/jsonschema.go index 116984646..19b756dfc 100644 --- a/pkg/config/jsonschema.go +++ b/pkg/config/jsonschema.go @@ -53,7 +53,7 @@ func ValidateSchemaFile(filepath string, schema []byte) error { } // ValidateSchema validates a YAML construct (non-struct representation) against a JSON Schema -func ValidateSchema(content map[string]interface{}, schemaJSON []byte) error { +func ValidateSchema(content interface{}, schemaJSON []byte) error { contentYaml, err := yaml.Marshal(content) if err != nil { @@ -64,6 +64,11 @@ func ValidateSchema(content map[string]interface{}, schemaJSON []byte) error { return err } + return ValidateSchemaJSON(contentJSON, schemaJSON) + +} + +func ValidateSchemaJSON(contentJSON []byte, schemaJSON []byte) error { if bytes.Equal(contentJSON, []byte("null")) { contentJSON = []byte("{}") // non-json yaml struct } diff --git a/pkg/config/migrate.go b/pkg/config/migrate.go index d0040d801..35e698667 100644 --- a/pkg/config/migrate.go +++ b/pkg/config/migrate.go @@ -35,6 +35,20 @@ func Migrate(config types.Config, targetVersion string) (types.Config, error) { return nil, fmt.Errorf("no migration possible from '%s' to '%s'", config.GetAPIVersion(), targetVersion) } - return migration(config) + cfg, err := migration(config) + if err != nil { + return nil, fmt.Errorf("error migrating config: %w", err) + } + + schema, err := GetSchemaByVersion(cfg.GetAPIVersion()) + if err != nil { + return nil, fmt.Errorf("error getting schema for config apiVersion %s: %w", cfg.GetAPIVersion(), err) + } + + if err := ValidateSchema(cfg, schema); err != nil { + return config, fmt.Errorf("post-migrate schema validation failed: %w", err) + } + + return cfg, err } diff --git a/pkg/config/migrate_test.go b/pkg/config/migrate_test.go new file mode 100644 index 000000000..cfcb2ea8c --- /dev/null +++ b/pkg/config/migrate_test.go @@ -0,0 +1,76 @@ +/* +Copyright © 2020-2021 The k3d Author(s) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +package config + +import ( + "testing" + + "github.com/go-test/deep" + l "github.com/rancher/k3d/v5/pkg/logger" + "github.com/spf13/viper" +) + +func TestMigrateV1Alpha2ToV1Alpha3(t *testing.T) { + + actualPath := "test_assets/config_test_simple_migration_v1alpha2.yaml" + expectedPath := "test_assets/config_test_simple_migration_v1alpha3.yaml" + + actualViper := viper.New() + expectedViper := viper.New() + + actualViper.SetConfigType("yaml") + expectedViper.SetConfigType("yaml") + + actualViper.SetConfigFile(actualPath) + expectedViper.SetConfigFile(expectedPath) + + if err := actualViper.ReadInConfig(); err != nil { + t.Fatal(err) + } + + if err := expectedViper.ReadInConfig(); err != nil { + t.Fatal(err) + } + + actualCfg, err := FromViper(actualViper) + if err != nil { + t.Fatal(err) + } + + if actualCfg.GetAPIVersion() != DefaultConfigApiVersion { + actualCfg, err = Migrate(actualCfg, DefaultConfigApiVersion) + if err != nil { + l.Log().Fatalln(err) + } + } + + expectedCfg, err := FromViper(expectedViper) + if err != nil { + t.Fatal(err) + } + + if diff := deep.Equal(actualCfg, expectedCfg); diff != nil { + t.Fatalf("Actual\n%#v\ndoes not match expected\n%+v\nDiff:\n%#v", actualCfg, expectedCfg, diff) + } + +} diff --git a/pkg/config/test_assets/config_test_simple_migration_v1alpha2.yaml b/pkg/config/test_assets/config_test_simple_migration_v1alpha2.yaml new file mode 100755 index 000000000..e58d896c0 --- /dev/null +++ b/pkg/config/test_assets/config_test_simple_migration_v1alpha2.yaml @@ -0,0 +1,51 @@ +apiVersion: k3d.io/v1alpha2 +kind: Simple +name: test +servers: 3 +agents: 2 +kubeAPI: + hostIP: "0.0.0.0" + hostPort: "6446" +#image: rancher/k3s:latest +volumes: + - volume: /my/path:/some/path + nodeFilters: + - all +ports: + - port: 80:80 + nodeFilters: + - loadbalancer + - port: 0.0.0.0:443:443 + nodeFilters: + - loadbalancer +env: + - envVar: bar=baz,bob + nodeFilters: + - all +labels: + - label: foo=bar + nodeFilters: + - server[0] + - loadbalancer +registries: + create: true + use: [] + config: | + mirrors: + "my.company.registry": + endpoint: + - http://my.company.registry:5000 + +options: + k3d: + wait: true + timeout: "360s" # should be pretty high for multi-server clusters to allow for a proper startup routine + disableLoadbalancer: false + disableImageVolume: false + k3s: + extraServerArgs: + - --tls-san=127.0.0.1 + extraAgentArgs: [] + kubeconfig: + updateDefaultKubeconfig: true + switchCurrentContext: true diff --git a/pkg/config/test_assets/config_test_simple_migration_v1alpha3.yaml b/pkg/config/test_assets/config_test_simple_migration_v1alpha3.yaml new file mode 100755 index 000000000..1f36147b4 --- /dev/null +++ b/pkg/config/test_assets/config_test_simple_migration_v1alpha3.yaml @@ -0,0 +1,55 @@ +apiVersion: k3d.io/v1alpha3 +kind: Simple +name: test +servers: 3 +agents: 2 +kubeAPI: + hostIP: "0.0.0.0" + hostPort: "6446" +#image: rancher/k3s:latest +volumes: + - volume: /my/path:/some/path + nodeFilters: + - all +ports: + - port: 80:80 + nodeFilters: + - loadbalancer + - port: 0.0.0.0:443:443 + nodeFilters: + - loadbalancer +env: + - envVar: bar=baz,bob + nodeFilters: + - all +registries: + create: + name: k3d-test-registry + host: "0.0.0.0" + hostPort: random + config: | + mirrors: + "my.company.registry": + endpoint: + - http://my.company.registry:5000 + +options: + k3d: + wait: true + timeout: "360s" # should be pretty high for multi-server clusters to allow for a proper startup routine + disableLoadbalancer: false + disableImageVolume: false + k3s: + extraArgs: + - arg: --tls-san=127.0.0.1 + nodeFilters: + - server:* + kubeconfig: + updateDefaultKubeconfig: true + switchCurrentContext: true + runtime: + labels: + - label: foo=bar + nodeFilters: + - server:0 + - loadbalancer diff --git a/pkg/config/v1alpha2/types.go b/pkg/config/v1alpha2/types.go index c78068781..c5e4fe127 100644 --- a/pkg/config/v1alpha2/types.go +++ b/pkg/config/v1alpha2/types.go @@ -57,23 +57,23 @@ var DefaultConfig = fmt.Sprintf( ) type VolumeWithNodeFilters struct { - Volume string `mapstructure:"volume" yaml:"volume" json:"volume,omitempty"` - NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters" json:"nodeFilters,omitempty"` + Volume string `mapstructure:"volume" yaml:"volume,omitempty" json:"volume,omitempty"` + NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters,omitempty" json:"nodeFilters,omitempty"` } type PortWithNodeFilters struct { - Port string `mapstructure:"port" yaml:"port" json:"port,omitempty"` - NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters" json:"nodeFilters,omitempty"` + Port string `mapstructure:"port" yaml:"port,omitempty" json:"port,omitempty"` + NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters,omitempty" json:"nodeFilters,omitempty"` } type LabelWithNodeFilters struct { - Label string `mapstructure:"label" yaml:"label" json:"label,omitempty"` - NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters" json:"nodeFilters,omitempty"` + Label string `mapstructure:"label" yaml:"label,omitempty" json:"label,omitempty"` + NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters,omitempty" json:"nodeFilters,omitempty"` } type EnvVarWithNodeFilters struct { - EnvVar string `mapstructure:"envVar" yaml:"envVar" json:"envVar,omitempty"` - NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters" json:"nodeFilters,omitempty"` + EnvVar string `mapstructure:"envVar" yaml:"envVar,omitempty" json:"envVar,omitempty"` + NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters,omitempty" json:"nodeFilters,omitempty"` } // SimpleConfigOptionsKubeconfig describes the set of options referring to the kubeconfig during cluster creation. @@ -83,49 +83,49 @@ type SimpleConfigOptionsKubeconfig struct { } type SimpleConfigOptions struct { - K3dOptions SimpleConfigOptionsK3d `mapstructure:"k3d" yaml:"k3d"` - K3sOptions SimpleConfigOptionsK3s `mapstructure:"k3s" yaml:"k3s"` - KubeconfigOptions SimpleConfigOptionsKubeconfig `mapstructure:"kubeconfig" yaml:"kubeconfig"` - Runtime SimpleConfigOptionsRuntime `mapstructure:"runtime" yaml:"runtime"` + K3dOptions SimpleConfigOptionsK3d `mapstructure:"k3d" yaml:"k3d" json:"k3d"` + K3sOptions SimpleConfigOptionsK3s `mapstructure:"k3s" yaml:"k3s" json:"k3s"` + KubeconfigOptions SimpleConfigOptionsKubeconfig `mapstructure:"kubeconfig" yaml:"kubeconfig" json:"kubeconfig"` + Runtime SimpleConfigOptionsRuntime `mapstructure:"runtime" yaml:"runtime" json:"runtime"` } type SimpleConfigOptionsRuntime struct { - GPURequest string `mapstructure:"gpuRequest" yaml:"gpuRequest"` - ServersMemory string `mapstructure:"serversMemory" yaml:"serversMemory"` - AgentsMemory string `mapstructure:"agentsMemory" yaml:"agentsMemory"` + GPURequest string `mapstructure:"gpuRequest,omitempty" yaml:"gpuRequest,omitempty" json:"gpuRequest,omitempty"` + ServersMemory string `mapstructure:"serversMemory,omitempty" yaml:"serversMemory,omitempty" json:"serversMemory,omitempty"` + AgentsMemory string `mapstructure:"agentsMemory,omitempty" yaml:"agentsMemory,omitempty" json:"agentsMemory,omitempty"` } type SimpleConfigOptionsK3d struct { - Wait bool `mapstructure:"wait" yaml:"wait"` - Timeout time.Duration `mapstructure:"timeout" yaml:"timeout"` - DisableLoadbalancer bool `mapstructure:"disableLoadbalancer" yaml:"disableLoadbalancer"` - DisableImageVolume bool `mapstructure:"disableImageVolume" yaml:"disableImageVolume"` - NoRollback bool `mapstructure:"disableRollback" yaml:"disableRollback"` - PrepDisableHostIPInjection bool `mapstructure:"disableHostIPInjection" yaml:"disableHostIPInjection"` - NodeHookActions []k3d.NodeHookAction `mapstructure:"nodeHookActions" yaml:"nodeHookActions,omitempty"` + Wait bool `mapstructure:"wait" yaml:"wait" json:"wait"` + Timeout time.Duration `mapstructure:"timeout" yaml:"timeout,omitempty" json:"timeout,omitempty"` + DisableLoadbalancer bool `mapstructure:"disableLoadbalancer" yaml:"disableLoadbalancer" json:"disableLoadbalancer"` + DisableImageVolume bool `mapstructure:"disableImageVolume" yaml:"disableImageVolume" json:"disableImageVolume"` + NoRollback bool `mapstructure:"disableRollback" yaml:"disableRollback" json:"disableRollback"` + PrepDisableHostIPInjection bool `mapstructure:"disableHostIPInjection" json:"disableHostIPInjection"` + NodeHookActions []k3d.NodeHookAction `mapstructure:"nodeHookActions" yaml:"nodeHookActions,omitempty" json:"nodeHookActions,omitempty"` } type SimpleConfigOptionsK3s struct { - ExtraServerArgs []string `mapstructure:"extraServerArgs" yaml:"extraServerArgs"` - ExtraAgentArgs []string `mapstructure:"extraAgentArgs" yaml:"extraAgentArgs"` + ExtraServerArgs []string `mapstructure:"extraServerArgs,omitempty" yaml:"extraServerArgs,omitempty" json:"extraServerArgs,omitempty"` + ExtraAgentArgs []string `mapstructure:"extraAgentArgs,omitempty" yaml:"extraAgentArgs,omitempty" json:"extraAgentArgs,omitempty"` } // SimpleConfig describes the toplevel k3d configuration file. type SimpleConfig struct { configtypes.TypeMeta `mapstructure:",squash" yaml:",inline"` - Name string `mapstructure:"name" yaml:"name" json:"name,omitempty"` - Servers int `mapstructure:"servers" yaml:"servers" json:"servers,omitempty"` //nolint:lll // default 1 - Agents int `mapstructure:"agents" yaml:"agents" json:"agents,omitempty"` //nolint:lll // default 0 - ExposeAPI SimpleExposureOpts `mapstructure:"kubeAPI" yaml:"kubeAPI" json:"kubeAPI,omitempty"` - Image string `mapstructure:"image" yaml:"image" json:"image,omitempty"` - Network string `mapstructure:"network" yaml:"network" json:"network,omitempty"` - Subnet string `mapstructure:"subnet" yaml:"subnet" json:"subnet,omitempty"` - ClusterToken string `mapstructure:"token" yaml:"clusterToken" json:"clusterToken,omitempty"` // default: auto-generated - Volumes []VolumeWithNodeFilters `mapstructure:"volumes" yaml:"volumes" json:"volumes,omitempty"` - Ports []PortWithNodeFilters `mapstructure:"ports" yaml:"ports" json:"ports,omitempty"` - Labels []LabelWithNodeFilters `mapstructure:"labels" yaml:"labels" json:"labels,omitempty"` - Options SimpleConfigOptions `mapstructure:"options" yaml:"options" json:"options,omitempty"` - Env []EnvVarWithNodeFilters `mapstructure:"env" yaml:"env" json:"env,omitempty"` + Name string `mapstructure:"name" yaml:"name,omitempty" json:"name,omitempty"` + Servers int `mapstructure:"servers" yaml:"servers,omitempty" json:"servers,omitempty"` //nolint:lll // default 1 + Agents int `mapstructure:"agents" yaml:"agents,omitempty" json:"agents,omitempty"` //nolint:lll // default 0 + ExposeAPI SimpleExposureOpts `mapstructure:"kubeAPI" yaml:"kubeAPI,omitempty" json:"kubeAPI,omitempty"` + Image string `mapstructure:"image" yaml:"image,omitempty" json:"image,omitempty"` + Network string `mapstructure:"network" yaml:"network,omitempty" json:"network,omitempty"` + Subnet string `mapstructure:"subnet" yaml:"subnet,omitempty" json:"subnet,omitempty"` + ClusterToken string `mapstructure:"token" yaml:"clusterToken,omitempty" json:"clusterToken,omitempty"` // default: auto-generated + Volumes []VolumeWithNodeFilters `mapstructure:"volumes" yaml:"volumes,omitempty" json:"volumes,omitempty"` + Ports []PortWithNodeFilters `mapstructure:"ports" yaml:"ports,omitempty" json:"ports,omitempty"` + Labels []LabelWithNodeFilters `mapstructure:"labels" yaml:"labels,omitempty" json:"labels,omitempty"` + Options SimpleConfigOptions `mapstructure:"options" yaml:"options,omitempty" json:"options,omitempty"` + Env []EnvVarWithNodeFilters `mapstructure:"env" yaml:"env,omitempty" json:"env,omitempty"` Registries struct { Use []string `mapstructure:"use" yaml:"use,omitempty" json:"use,omitempty"` Create bool `mapstructure:"create" yaml:"create,omitempty" json:"create,omitempty"` diff --git a/pkg/config/v1alpha3/schema.json b/pkg/config/v1alpha3/schema.json index 95dc17e5b..ac1b64142 100644 --- a/pkg/config/v1alpha3/schema.json +++ b/pkg/config/v1alpha3/schema.json @@ -119,7 +119,6 @@ "default": true }, "timeout": { - "type": "string", "examples": [ "60s", "1m", diff --git a/pkg/config/v1alpha3/types.go b/pkg/config/v1alpha3/types.go index 490a82c48..027cfe0b2 100644 --- a/pkg/config/v1alpha3/types.go +++ b/pkg/config/v1alpha3/types.go @@ -57,34 +57,34 @@ var DefaultConfig = fmt.Sprintf( ) type VolumeWithNodeFilters struct { - Volume string `mapstructure:"volume" yaml:"volume" json:"volume,omitempty"` - NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters" json:"nodeFilters,omitempty"` + Volume string `mapstructure:"volume" yaml:"volume,omitempty" json:"volume,omitempty"` + NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters,omitempty" json:"nodeFilters,omitempty"` } type PortWithNodeFilters struct { - Port string `mapstructure:"port" yaml:"port" json:"port,omitempty"` - NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters" json:"nodeFilters,omitempty"` + Port string `mapstructure:"port" yaml:"port,omitempty" json:"port,omitempty"` + NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters,omitempty" json:"nodeFilters,omitempty"` } type LabelWithNodeFilters struct { - Label string `mapstructure:"label" yaml:"label" json:"label,omitempty"` - NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters" json:"nodeFilters,omitempty"` + Label string `mapstructure:"label" yaml:"label,omitempty" json:"label,omitempty"` + NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters,omitempty" json:"nodeFilters,omitempty"` } type EnvVarWithNodeFilters struct { - EnvVar string `mapstructure:"envVar" yaml:"envVar" json:"envVar,omitempty"` - NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters" json:"nodeFilters,omitempty"` + EnvVar string `mapstructure:"envVar" yaml:"envVar,omitempty" json:"envVar,omitempty"` + NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters,omitempty" json:"nodeFilters,omitempty"` } type K3sArgWithNodeFilters struct { - Arg string `mapstructure:"arg" yaml:"arg" json:"arg,omitempty"` - NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters" json:"nodeFilters,omitempty"` + Arg string `mapstructure:"arg" yaml:"arg,omitempty" json:"arg,omitempty"` + NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters,omitempty" json:"nodeFilters,omitempty"` } type SimpleConfigRegistryCreateConfig struct { - Name string `mapstructure:"name" yaml:"name" json:"name"` - Host string `mapstructure:"host" yaml:"host" json:"host"` - HostPort string `mapstructure:"hostPort" yaml:"hostPort" json:"hostPort"` + Name string `mapstructure:"name" yaml:"name,omitempty" json:"name,omitempty"` + Host string `mapstructure:"host" yaml:"host,omitempty" json:"host,omitempty"` + HostPort string `mapstructure:"hostPort" yaml:"hostPort,omitempty" json:"hostPort,omitempty"` } // SimpleConfigOptionsKubeconfig describes the set of options referring to the kubeconfig during cluster creation. @@ -94,36 +94,36 @@ type SimpleConfigOptionsKubeconfig struct { } type SimpleConfigOptions struct { - K3dOptions SimpleConfigOptionsK3d `mapstructure:"k3d" yaml:"k3d"` - K3sOptions SimpleConfigOptionsK3s `mapstructure:"k3s" yaml:"k3s"` - KubeconfigOptions SimpleConfigOptionsKubeconfig `mapstructure:"kubeconfig" yaml:"kubeconfig"` - Runtime SimpleConfigOptionsRuntime `mapstructure:"runtime" yaml:"runtime"` + K3dOptions SimpleConfigOptionsK3d `mapstructure:"k3d" yaml:"k3d" json:"k3d"` + K3sOptions SimpleConfigOptionsK3s `mapstructure:"k3s" yaml:"k3s" json:"k3s"` + KubeconfigOptions SimpleConfigOptionsKubeconfig `mapstructure:"kubeconfig" yaml:"kubeconfig" json:"kubeconfig"` + Runtime SimpleConfigOptionsRuntime `mapstructure:"runtime" yaml:"runtime" json:"runtime"` } type SimpleConfigOptionsRuntime struct { - GPURequest string `mapstructure:"gpuRequest" yaml:"gpuRequest"` - ServersMemory string `mapstructure:"serversMemory" yaml:"serversMemory"` - AgentsMemory string `mapstructure:"agentsMemory" yaml:"agentsMemory"` - Labels []LabelWithNodeFilters `mapstructure:"labels" yaml:"labels"` + GPURequest string `mapstructure:"gpuRequest" yaml:"gpuRequest,omitempty" json:"gpuRequest,omitempty"` + ServersMemory string `mapstructure:"serversMemory" yaml:"serversMemory,omitempty" json:"serversMemory,omitempty"` + AgentsMemory string `mapstructure:"agentsMemory" yaml:"agentsMemory,omitempty" json:"agentsMemory,omitempty"` + Labels []LabelWithNodeFilters `mapstructure:"labels" yaml:"labels,omitempty" json:"labels,omitempty"` } type SimpleConfigOptionsK3d struct { - Wait bool `mapstructure:"wait" yaml:"wait"` - Timeout time.Duration `mapstructure:"timeout" yaml:"timeout"` - DisableLoadbalancer bool `mapstructure:"disableLoadbalancer" yaml:"disableLoadbalancer"` - DisableImageVolume bool `mapstructure:"disableImageVolume" yaml:"disableImageVolume"` - NoRollback bool `mapstructure:"disableRollback" yaml:"disableRollback"` - NodeHookActions []k3d.NodeHookAction `mapstructure:"nodeHookActions" yaml:"nodeHookActions,omitempty"` - Loadbalancer SimpleConfigOptionsK3dLoadbalancer `mapstructure:"loadbalancer" yaml:"loadbalancer,omitempty"` + Wait bool `mapstructure:"wait" yaml:"wait" json:"wait"` + Timeout time.Duration `mapstructure:"timeout" yaml:"timeout,omitempty" json:"timeout,omitempty"` + DisableLoadbalancer bool `mapstructure:"disableLoadbalancer" yaml:"disableLoadbalancer" json:"disableLoadbalancer"` + DisableImageVolume bool `mapstructure:"disableImageVolume" yaml:"disableImageVolume" json:"disableImageVolume"` + NoRollback bool `mapstructure:"disableRollback" yaml:"disableRollback" json:"disableRollback"` + NodeHookActions []k3d.NodeHookAction `mapstructure:"nodeHookActions" yaml:"nodeHookActions,omitempty" json:"nodeHookActions,omitempty"` + Loadbalancer SimpleConfigOptionsK3dLoadbalancer `mapstructure:"loadbalancer" yaml:"loadbalancer,omitempty" json:"loadbalancer,omitempty"` } type SimpleConfigOptionsK3dLoadbalancer struct { - ConfigOverrides []string `mapstructure:"configOverrides" yaml:"configOverrides,omitempty"` + ConfigOverrides []string `mapstructure:"configOverrides" yaml:"configOverrides,omitempty" json:"configOverrides,omitempty"` } type SimpleConfigOptionsK3s struct { - ExtraArgs []K3sArgWithNodeFilters `mapstructure:"extraArgs" yaml:"extraArgs"` - NodeLabels []LabelWithNodeFilters `mapstructure:"nodeLabels" yaml:"nodeLabels"` + ExtraArgs []K3sArgWithNodeFilters `mapstructure:"extraArgs" yaml:"extraArgs,omitempty" json:"extraArgs,omitempty"` + NodeLabels []LabelWithNodeFilters `mapstructure:"nodeLabels" yaml:"nodeLabels,omitempty" json:"nodeLabels,omitempty"` } type SimpleConfigRegistries struct { @@ -141,35 +141,35 @@ type SimpleConfigRegistriesIntermediateV1alpha2 struct { // SimpleConfig describes the toplevel k3d configuration file. type SimpleConfig struct { config.TypeMeta `mapstructure:",squash" yaml:",inline"` - Name string `mapstructure:"name" yaml:"name" json:"name,omitempty"` - Servers int `mapstructure:"servers" yaml:"servers" json:"servers,omitempty"` //nolint:lll // default 1 - Agents int `mapstructure:"agents" yaml:"agents" json:"agents,omitempty"` //nolint:lll // default 0 - ExposeAPI SimpleExposureOpts `mapstructure:"kubeAPI" yaml:"kubeAPI" json:"kubeAPI,omitempty"` - Image string `mapstructure:"image" yaml:"image" json:"image,omitempty"` - Network string `mapstructure:"network" yaml:"network" json:"network,omitempty"` - Subnet string `mapstructure:"subnet" yaml:"subnet" json:"subnet,omitempty"` - ClusterToken string `mapstructure:"token" yaml:"clusterToken" json:"clusterToken,omitempty"` // default: auto-generated - Volumes []VolumeWithNodeFilters `mapstructure:"volumes" yaml:"volumes" json:"volumes,omitempty"` - Ports []PortWithNodeFilters `mapstructure:"ports" yaml:"ports" json:"ports,omitempty"` - Options SimpleConfigOptions `mapstructure:"options" yaml:"options" json:"options,omitempty"` - Env []EnvVarWithNodeFilters `mapstructure:"env" yaml:"env" json:"env,omitempty"` + Name string `mapstructure:"name" yaml:"name,omitempty" json:"name,omitempty"` + Servers int `mapstructure:"servers" yaml:"servers,omitempty" json:"servers,omitempty"` //nolint:lll // default 1 + Agents int `mapstructure:"agents" yaml:"agents,omitempty" json:"agents,omitempty"` //nolint:lll // default 0 + ExposeAPI SimpleExposureOpts `mapstructure:"kubeAPI" yaml:"kubeAPI,omitempty" json:"kubeAPI,omitempty"` + Image string `mapstructure:"image" yaml:"image,omitempty" json:"image,omitempty"` + Network string `mapstructure:"network" yaml:"network,omitempty" json:"network,omitempty"` + Subnet string `mapstructure:"subnet" yaml:"subnet,omitempty" json:"subnet,omitempty"` + ClusterToken string `mapstructure:"token" yaml:"clusterToken,omitempty" json:"clusterToken,omitempty"` // default: auto-generated + Volumes []VolumeWithNodeFilters `mapstructure:"volumes" yaml:"volumes,omitempty" json:"volumes,omitempty"` + Ports []PortWithNodeFilters `mapstructure:"ports" yaml:"ports,omitempty" json:"ports,omitempty"` + Options SimpleConfigOptions `mapstructure:"options" yaml:"options,omitempty" json:"options,omitempty"` + Env []EnvVarWithNodeFilters `mapstructure:"env" yaml:"env,omitempty" json:"env,omitempty"` Registries SimpleConfigRegistries `mapstructure:"registries" yaml:"registries,omitempty" json:"registries,omitempty"` } type SimpleConfigIntermediateV1alpha2 struct { config.TypeMeta `mapstructure:",squash" yaml:",inline"` - Name string `mapstructure:"name" yaml:"name" json:"name,omitempty"` - Servers int `mapstructure:"servers" yaml:"servers" json:"servers,omitempty"` //nolint:lll // default 1 - Agents int `mapstructure:"agents" yaml:"agents" json:"agents,omitempty"` //nolint:lll // default 0 - ExposeAPI SimpleExposureOpts `mapstructure:"kubeAPI" yaml:"kubeAPI" json:"kubeAPI,omitempty"` - Image string `mapstructure:"image" yaml:"image" json:"image,omitempty"` - Network string `mapstructure:"network" yaml:"network" json:"network,omitempty"` - Subnet string `mapstructure:"subnet" yaml:"subnet" json:"subnet,omitempty"` - ClusterToken string `mapstructure:"token" yaml:"clusterToken" json:"clusterToken,omitempty"` // default: auto-generated - Volumes []VolumeWithNodeFilters `mapstructure:"volumes" yaml:"volumes" json:"volumes,omitempty"` - Ports []PortWithNodeFilters `mapstructure:"ports" yaml:"ports" json:"ports,omitempty"` - Options SimpleConfigOptions `mapstructure:"options" yaml:"options" json:"options,omitempty"` - Env []EnvVarWithNodeFilters `mapstructure:"env" yaml:"env" json:"env,omitempty"` + Name string `mapstructure:"name" yaml:"name,omitempty" json:"name,omitempty"` + Servers int `mapstructure:"servers" yaml:"servers,omitempty" json:"servers,omitempty"` //nolint:lll // default 1 + Agents int `mapstructure:"agents" yaml:"agents,omitempty" json:"agents,omitempty"` //nolint:lll // default 0 + ExposeAPI SimpleExposureOpts `mapstructure:"kubeAPI" yaml:"kubeAPI,omitempty" json:"kubeAPI,omitempty"` + Image string `mapstructure:"image" yaml:"image,omitempty" json:"image,omitempty"` + Network string `mapstructure:"network" yaml:"network,omitempty" json:"network,omitempty"` + Subnet string `mapstructure:"subnet" yaml:"subnet,omitempty" json:"subnet,omitempty"` + ClusterToken string `mapstructure:"token" yaml:"clusterToken,omitempty" json:"clusterToken,omitempty"` // default: auto-generated + Volumes []VolumeWithNodeFilters `mapstructure:"volumes" yaml:"volumes,omitempty" json:"volumes,omitempty"` + Ports []PortWithNodeFilters `mapstructure:"ports" yaml:"ports,omitempty" json:"ports,omitempty"` + Options SimpleConfigOptions `mapstructure:"options" yaml:"options,omitempty" json:"options,omitempty"` + Env []EnvVarWithNodeFilters `mapstructure:"env" yaml:"env,omitempty" json:"env,omitempty"` Registries SimpleConfigRegistriesIntermediateV1alpha2 `mapstructure:"registries" yaml:"registries,omitempty" json:"registries,omitempty"` } diff --git a/tests/assets/config_test_simple.yaml b/tests/assets/config_test_simple.yaml index 03eca617b..02aeb5f51 100755 --- a/tests/assets/config_test_simple.yaml +++ b/tests/assets/config_test_simple.yaml @@ -31,7 +31,6 @@ registries: "my.company.registry": endpoint: - http://my.company.registry:5000 - options: k3d: wait: true diff --git a/tests/assets/config_test_simple_migration_v1alpha3.yaml b/tests/assets/config_test_simple_migration_v1alpha3.yaml index 4d4e147fe..1f36147b4 100755 --- a/tests/assets/config_test_simple_migration_v1alpha3.yaml +++ b/tests/assets/config_test_simple_migration_v1alpha3.yaml @@ -27,7 +27,6 @@ registries: name: k3d-test-registry host: "0.0.0.0" hostPort: random - use: [] config: | mirrors: "my.company.registry":