[FEATURE] Config file compatible with Kustomize (#945)

pull/946/head^2
Erik Godding Boye 3 years ago committed by GitHub
parent 08bf145e95
commit 9a2a3ec0ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      docs/usage/configfile.md
  2. 1
      docs/usage/registries.md
  3. 4
      pkg/config/config_test.go
  4. 2
      pkg/config/jsonschema_test.go
  5. 45
      pkg/config/migrate_test.go
  6. 1
      pkg/config/test_assets/config_test_registries.yaml
  7. 1
      pkg/config/test_assets/config_test_simple.yaml
  8. 1
      pkg/config/test_assets/config_test_simple_2.yaml
  9. 1
      pkg/config/test_assets/config_test_simple_invalid_servers.yaml
  10. 56
      pkg/config/test_assets/config_test_simple_migration_v1alpha4.yaml
  11. 5
      pkg/config/types/types.go
  12. 44
      pkg/config/v1alpha4/migrations.go
  13. 6
      pkg/config/v1alpha4/schema.json
  14. 2
      pkg/config/v1alpha4/types.go
  15. 1
      tests/assets/config_env.yaml
  16. 1
      tests/assets/config_test_simple.yaml

@ -52,6 +52,7 @@ Since the config options and the config file are changing quite a bit, it's hard
# k3d configuration file, saved as e.g. /home/me/myk3dcluster.yaml
apiVersion: k3d.io/v1alpha4 # this will change in the future as we make everything more stable
kind: Simple # internally, we also have a Cluster config, which is not yet available externally
metadata:
name: mycluster # name that you want to give to your cluster (will still be prefixed with `k3d-`)
servers: 1 # same as `--servers 1`
agents: 2 # same as `--agents 2`

@ -25,6 +25,7 @@ If you're using a `SimpleConfig` file to configure your k3d cluster, you may as
```yaml
apiVersion: k3d.io/v1alpha4
kind: Simple
metadata:
name: test
servers: 1
agents: 2

@ -44,7 +44,9 @@ func TestReadSimpleConfig(t *testing.T) {
APIVersion: "k3d.io/v1alpha4",
Kind: "Simple",
},
ObjectMeta: configtypes.ObjectMeta{
Name: "test",
},
Servers: 1,
Agents: 2,
ExposeAPI: exposedAPI,
@ -268,7 +270,9 @@ func TestReadSimpleConfigRegistries(t *testing.T) {
APIVersion: "k3d.io/v1alpha4",
Kind: "Simple",
},
ObjectMeta: configtypes.ObjectMeta{
Name: "test",
},
Servers: 1,
Agents: 1,
Registries: conf.SimpleConfigRegistries{

@ -46,7 +46,7 @@ func TestValidateSchemaFail(t *testing.T) {
t.Errorf("Validation of config file %s against the default schema passed where we expected a failure", cfgPath)
}
expectedErrorText := `- name: Invalid type. Expected: string, given: integer
expectedErrorText := `- metadata.name: Invalid type. Expected: string, given: integer
`
if err.Error() != expectedErrorText {

@ -26,14 +26,37 @@ import (
"testing"
"github.com/go-test/deep"
"github.com/rancher/k3d/v5/pkg/config/v1alpha3"
"github.com/rancher/k3d/v5/pkg/config/v1alpha4"
l "github.com/rancher/k3d/v5/pkg/logger"
"github.com/spf13/viper"
)
func TestMigrateV1Alpha2ToV1Alpha3(t *testing.T) {
func TestMigrate(t *testing.T) {
tests := map[string]struct {
targetVersion string
actualPath string
expectedPath string
}{
"V1Alpha2ToV1Alpha3": {
targetVersion: v1alpha3.ApiVersion,
actualPath: "test_assets/config_test_simple_migration_v1alpha2.yaml",
expectedPath: "test_assets/config_test_simple_migration_v1alpha3.yaml",
},
"V1Alpha2ToV1Alpha4": {
targetVersion: v1alpha4.ApiVersion,
actualPath: "test_assets/config_test_simple_migration_v1alpha2.yaml",
expectedPath: "test_assets/config_test_simple_migration_v1alpha4.yaml",
},
"V1Alpha3ToV1Alpha4": {
targetVersion: v1alpha4.ApiVersion,
actualPath: "test_assets/config_test_simple_migration_v1alpha3.yaml",
expectedPath: "test_assets/config_test_simple_migration_v1alpha4.yaml",
},
}
actualPath := "test_assets/config_test_simple_migration_v1alpha2.yaml"
expectedPath := "test_assets/config_test_simple_migration_v1alpha3.yaml"
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
actualViper := viper.New()
expectedViper := viper.New()
@ -41,8 +64,8 @@ func TestMigrateV1Alpha2ToV1Alpha3(t *testing.T) {
actualViper.SetConfigType("yaml")
expectedViper.SetConfigType("yaml")
actualViper.SetConfigFile(actualPath)
expectedViper.SetConfigFile(expectedPath)
actualViper.SetConfigFile(tc.actualPath)
expectedViper.SetConfigFile(tc.expectedPath)
if err := actualViper.ReadInConfig(); err != nil {
t.Fatal(err)
@ -57,8 +80,8 @@ func TestMigrateV1Alpha2ToV1Alpha3(t *testing.T) {
t.Fatal(err)
}
if actualCfg.GetAPIVersion() != DefaultConfigApiVersion {
actualCfg, err = Migrate(actualCfg, DefaultConfigApiVersion)
if actualCfg.GetAPIVersion() != tc.targetVersion {
actualCfg, err = Migrate(actualCfg, tc.targetVersion)
if err != nil {
l.Log().Fatalln(err)
}
@ -73,12 +96,6 @@ func TestMigrateV1Alpha2ToV1Alpha3(t *testing.T) {
t.Fatalf("Actual\n%#v\ndoes not match expected\n%+v\nDiff:\n%#v", actualCfg, expectedCfg, diff)
}
})
}
func TestMigrateV1Alpha2ToV1Alpha4(t *testing.T) {
t.Log("not implemented") // TODO: test migration v1alpha2 to v1alpha4
}
func TestMigrateV1Alpha3ToV1Alpha4(t *testing.T) {
t.Log("not implemented") // TODO: test migration v1alpha3 to v1alpha4
}

@ -1,5 +1,6 @@
apiVersion: k3d.io/v1alpha4
kind: Simple
metadata:
name: test
servers: 1
agents: 1

@ -1,5 +1,6 @@
apiVersion: k3d.io/v1alpha4
kind: Simple
metadata:
name: test
servers: 1
agents: 2

@ -1,4 +1,5 @@
apiVersion: k3d.io/v1alpha4
kind: Simple
metadata:
name: supertest
agents: 8

@ -1,5 +1,6 @@
apiVersion: k3d.io/v1alpha4
kind: Simple
metadata:
name: 1234
servers: 1
agents: 2

@ -0,0 +1,56 @@
apiVersion: k3d.io/v1alpha4
kind: Simple
metadata:
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

@ -27,6 +27,11 @@ type TypeMeta struct {
APIVersion string `mapstructure:"apiVersion,omitempty" yaml:"apiVersion,omitempty" json:"apiVersion,omitempty"`
}
// ObjectMeta got its name from the Kubernetes counterpart.
type ObjectMeta struct {
Name string `mapstructure:"name,omitempty" yaml:"name,omitempty" json:"name,omitempty"`
}
// Config interface.
type Config interface {
GetKind() string

@ -23,6 +23,7 @@ THE SOFTWARE.
package v1alpha4
import (
"encoding/json"
"fmt"
configtypes "github.com/rancher/k3d/v5/pkg/config/types"
@ -52,5 +53,48 @@ func MigrateV1Alpha2(input configtypes.Config) (configtypes.Config, error) {
func MigrateV1Alpha3(input configtypes.Config) (configtypes.Config, error) {
l.Log().Debugln("Migrating v1alpha3 to v1alpha4")
/*
* We're migrating matching fields between versions by marshalling to JSON and back
*/
injson, err := json.Marshal(input)
if err != nil {
return nil, err
}
/*
* Migrate config of `kind: Simple`
*/
if input.GetKind() == "Simple" {
cfgIntermediate := v1alpha3.SimpleConfig{}
if err := json.Unmarshal(injson, &cfgIntermediate); err != nil {
return nil, err
}
intermediateJSON, err := json.Marshal(cfgIntermediate)
if err != nil {
return nil, err
}
cfg := SimpleConfig{}
if err := json.Unmarshal(intermediateJSON, &cfg); err != nil {
return nil, err
}
cfg.Name = cfgIntermediate.Name
/*
* Finalizing
*/
cfg.APIVersion = ApiVersion
l.Log().Debugf("Migrated config: %+v", cfg)
return cfg, nil
}
l.Log().Debugf("No migration needed for %s#%s -> %s#%s", input.GetAPIVersion(), input.GetKind(), ApiVersion, input.GetKind())
return input, nil
}

@ -21,10 +21,16 @@
],
"default": "Simple"
},
"metadata": {
"type": "object",
"properties": {
"name": {
"description": "Name of the cluster (must be a valid hostname and will be prefixed with 'k3d-'). Example: 'mycluster'.",
"type": "string",
"format": "hostname"
}
},
"additionalProperties": false
},
"servers": {
"type": "number",

@ -136,7 +136,7 @@ type SimpleConfigRegistries struct {
// SimpleConfig describes the toplevel k3d configuration file.
type SimpleConfig struct {
config.TypeMeta `mapstructure:",squash" yaml:",inline"`
Name string `mapstructure:"name" yaml:"name,omitempty" json:"name,omitempty"`
config.ObjectMeta `mapstructure:"metadata" yaml:"metadata,omitempty" json:"metadata,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"`

@ -1,4 +1,5 @@
apiVersion: k3d.io/v1alpha4
kind: Simple
metadata:
name: testenvexpand
servers: ${K3D_TEST_SERVERS}

@ -1,5 +1,6 @@
apiVersion: k3d.io/v1alpha4
kind: Simple
metadata:
name: test
servers: 3
agents: 2

Loading…
Cancel
Save