[BREAKING] Config File Enhancements: v1alpha3, migrations, generic k3s-args (#605)
Excerpt: - new version v1alpha3 with k3s extraArgs using node filters - reflected in CLI via --k3s-arg - new migration option to migrate (internally and via cli) from v1alpha2 to v1alpha3 - enhancements to how config files are being read - e2e tests for config file migration
This commit is contained in:
parent
774af31d24
commit
99fe3c75c4
@ -38,7 +38,7 @@ import (
|
||||
cliutil "github.com/rancher/k3d/v4/cmd/util"
|
||||
k3dCluster "github.com/rancher/k3d/v4/pkg/client"
|
||||
"github.com/rancher/k3d/v4/pkg/config"
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha2"
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha3"
|
||||
"github.com/rancher/k3d/v4/pkg/runtimes"
|
||||
k3d "github.com/rancher/k3d/v4/pkg/types"
|
||||
"github.com/rancher/k3d/v4/version"
|
||||
@ -77,11 +77,6 @@ func initConfig() {
|
||||
if _, err := os.Stat(configFile); err != nil {
|
||||
log.Fatalf("Failed to stat config file %s: %+v", configFile, err)
|
||||
}
|
||||
log.Tracef("Schema: %+v", conf.JSONSchema)
|
||||
|
||||
if err := config.ValidateSchemaFile(configFile, []byte(conf.JSONSchema)); err != nil {
|
||||
log.Fatalf("Schema Validation failed for config file %s: %+v", configFile, err)
|
||||
}
|
||||
|
||||
// try to read config into memory (viper map structure)
|
||||
if err := cfgViper.ReadInConfig(); err != nil {
|
||||
@ -92,7 +87,16 @@ func initConfig() {
|
||||
log.Fatalf("Failed to read config file %s: %+v", configFile, err)
|
||||
}
|
||||
|
||||
log.Infof("Using config file %s", cfgViper.ConfigFileUsed())
|
||||
schema, err := config.GetSchemaByVersion(cfgViper.GetString("apiVersion"))
|
||||
if err != nil {
|
||||
log.Fatalf("Cannot validate config file %s: %+v", configFile, err)
|
||||
}
|
||||
|
||||
if err := config.ValidateSchemaFile(configFile, schema); err != nil {
|
||||
log.Fatalf("Schema Validation failed for config file %s: %+v", configFile, err)
|
||||
}
|
||||
|
||||
log.Infof("Using config file %s (%s#%s)", cfgViper.ConfigFileUsed(), strings.ToLower(cfgViper.GetString("apiVersion")), strings.ToLower(cfgViper.GetString("kind")))
|
||||
}
|
||||
if log.GetLevel() >= log.DebugLevel {
|
||||
c, _ := yaml.Marshal(cfgViper.AllSettings())
|
||||
@ -121,19 +125,35 @@ func NewCmdClusterCreate() *cobra.Command {
|
||||
/*************************
|
||||
* Compute Configuration *
|
||||
*************************/
|
||||
cfg, err := config.FromViperSimple(cfgViper)
|
||||
if cfgViper.GetString("apiversion") == "" {
|
||||
cfgViper.Set("apiversion", config.DefaultConfigApiVersion)
|
||||
}
|
||||
if cfgViper.GetString("kind") == "" {
|
||||
cfgViper.Set("kind", "Simple")
|
||||
}
|
||||
cfg, err := config.FromViper(cfgViper)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
log.Debugf("========== Simple Config ==========\n%+v\n==========================\n", cfg)
|
||||
if cfg.GetAPIVersion() != config.DefaultConfigApiVersion {
|
||||
log.Warnf("Default config apiVersion is '%s', but you're using '%s': consider migrating.", config.DefaultConfigApiVersion, cfg.GetAPIVersion())
|
||||
cfg, err = config.Migrate(cfg, config.DefaultConfigApiVersion)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
cfg, err = applyCLIOverrides(cfg)
|
||||
simpleCfg := cfg.(conf.SimpleConfig)
|
||||
|
||||
log.Debugf("========== Simple Config ==========\n%+v\n==========================\n", simpleCfg)
|
||||
|
||||
simpleCfg, err = applyCLIOverrides(simpleCfg)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to apply CLI overrides: %+v", err)
|
||||
}
|
||||
|
||||
log.Debugf("========== Merged Simple Config ==========\n%+v\n==========================\n", cfg)
|
||||
log.Debugf("========== Merged Simple Config ==========\n%+v\n==========================\n", simpleCfg)
|
||||
|
||||
/**************************************
|
||||
* Transform, Process & Validate Configuration *
|
||||
@ -141,10 +161,10 @@ func NewCmdClusterCreate() *cobra.Command {
|
||||
|
||||
// Set the name
|
||||
if len(args) != 0 {
|
||||
cfg.Name = args[0]
|
||||
simpleCfg.Name = args[0]
|
||||
}
|
||||
|
||||
clusterConfig, err := config.TransformSimpleToClusterConfig(cmd.Context(), runtimes.SelectedRuntime, cfg)
|
||||
clusterConfig, err := config.TransformSimpleToClusterConfig(cmd.Context(), runtimes.SelectedRuntime, simpleCfg)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
@ -178,7 +198,7 @@ func NewCmdClusterCreate() *cobra.Command {
|
||||
if err := k3dCluster.ClusterRun(cmd.Context(), runtimes.SelectedRuntime, clusterConfig); err != nil {
|
||||
// rollback if creation failed
|
||||
log.Errorln(err)
|
||||
if cfg.Options.K3dOptions.NoRollback { // TODO: move rollback mechanics to pkg/
|
||||
if simpleCfg.Options.K3dOptions.NoRollback { // TODO: move rollback mechanics to pkg/
|
||||
log.Fatalln("Cluster creation FAILED, rollback deactivated.")
|
||||
}
|
||||
// rollback if creation failed
|
||||
@ -202,7 +222,7 @@ func NewCmdClusterCreate() *cobra.Command {
|
||||
|
||||
if clusterConfig.KubeconfigOpts.UpdateDefaultKubeconfig {
|
||||
log.Debugf("Updating default kubeconfig with a new context for cluster %s", clusterConfig.Cluster.Name)
|
||||
if _, err := k3dCluster.KubeconfigGetWrite(cmd.Context(), runtimes.SelectedRuntime, &clusterConfig.Cluster, "", &k3dCluster.WriteKubeConfigOptions{UpdateExisting: true, OverwriteExisting: false, UpdateCurrentContext: cfg.Options.KubeconfigOptions.SwitchCurrentContext}); err != nil {
|
||||
if _, err := k3dCluster.KubeconfigGetWrite(cmd.Context(), runtimes.SelectedRuntime, &clusterConfig.Cluster, "", &k3dCluster.WriteKubeConfigOptions{UpdateExisting: true, OverwriteExisting: false, UpdateCurrentContext: simpleCfg.Options.KubeconfigOptions.SwitchCurrentContext}); err != nil {
|
||||
log.Warningln(err)
|
||||
}
|
||||
}
|
||||
@ -266,6 +286,10 @@ func NewCmdClusterCreate() *cobra.Command {
|
||||
cmd.Flags().StringArrayP("label", "l", nil, "Add label to node container (Format: `KEY[=VALUE][@NODEFILTER[;NODEFILTER...]]`\n - Example: `k3d cluster create --agents 2 -l \"my.label@agent[0,1]\" -l \"other.label=somevalue@server[0]\"`")
|
||||
_ = ppViper.BindPFlag("cli.labels", cmd.Flags().Lookup("label"))
|
||||
|
||||
/* k3s */
|
||||
cmd.Flags().StringArray("k3s-arg", nil, "Additional args passed to k3s command (Format: `ARG@NODEFILTER[;@NODEFILTER]`)\n - Example: `k3d cluster create --k3s-arg \"--disable=traefik@server[0]\"")
|
||||
_ = cfgViper.BindPFlag("cli.k3sargs", cmd.Flags().Lookup("k3s-arg"))
|
||||
|
||||
/******************
|
||||
* "Normal" Flags *
|
||||
******************
|
||||
@ -340,13 +364,6 @@ func NewCmdClusterCreate() *cobra.Command {
|
||||
cmd.Flags().String("registry-config", "", "Specify path to an extra registries.yaml file")
|
||||
_ = cfgViper.BindPFlag("registries.config", cmd.Flags().Lookup("registry-config"))
|
||||
|
||||
/* k3s */
|
||||
cmd.Flags().StringArray("k3s-server-arg", nil, "Additional args passed to the `k3s server` command on server nodes (new flag per arg)")
|
||||
_ = cfgViper.BindPFlag("options.k3s.extraserverargs", cmd.Flags().Lookup("k3s-server-arg"))
|
||||
|
||||
cmd.Flags().StringArray("k3s-agent-arg", nil, "Additional args passed to the `k3s agent` command on agent nodes (new flag per arg)")
|
||||
_ = cfgViper.BindPFlag("options.k3s.extraagentargs", cmd.Flags().Lookup("k3s-agent-arg"))
|
||||
|
||||
/* Subcommands */
|
||||
|
||||
// done
|
||||
@ -520,5 +537,30 @@ func applyCLIOverrides(cfg conf.SimpleConfig) (conf.SimpleConfig, error) {
|
||||
|
||||
log.Tracef("EnvFilterMap: %+v", envFilterMap)
|
||||
|
||||
// --k3s-arg
|
||||
argFilterMap := make(map[string][]string, 1)
|
||||
for _, argFlag := range ppViper.GetStringSlice("cli.k3sargs") {
|
||||
|
||||
// split node filter from the specified arg
|
||||
arg, filters, err := cliutil.SplitFiltersFromFlag(argFlag)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
// create new entry or append filter to existing entry
|
||||
if _, exists := argFilterMap[arg]; exists {
|
||||
argFilterMap[arg] = append(argFilterMap[arg], filters...)
|
||||
} else {
|
||||
argFilterMap[arg] = filters
|
||||
}
|
||||
}
|
||||
|
||||
for arg, nodeFilters := range argFilterMap {
|
||||
cfg.Options.K3sOptions.ExtraArgs = append(cfg.Options.K3sOptions.ExtraArgs, conf.K3sArgWithNodeFilters{
|
||||
Arg: arg,
|
||||
NodeFilters: nodeFilters,
|
||||
})
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ func NewCmdConfig() *cobra.Command {
|
||||
}
|
||||
|
||||
cmd.AddCommand(NewCmdConfigInit())
|
||||
cmd.AddCommand(NewCmdConfigMigrate())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
config "github.com/rancher/k3d/v4/pkg/config/v1alpha2"
|
||||
config "github.com/rancher/k3d/v4/pkg/config/v1alpha3"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
111
cmd/config/configMigrate.go
Normal file
111
cmd/config/configMigrate.go
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
Copyright © 2020 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 (
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/k3d/v4/pkg/config"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// NewCmdConfigMigrate returns a new cobra command
|
||||
func NewCmdConfigMigrate() *cobra.Command {
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "migrate INPUT OUTPUT",
|
||||
Args: cobra.RangeArgs(1, 2),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
configFile := args[0]
|
||||
|
||||
if _, err := os.Stat(configFile); err != nil {
|
||||
log.Fatalf("Failed to stat config file %s: %+v", configFile, err)
|
||||
}
|
||||
|
||||
cfgViper := viper.New()
|
||||
cfgViper.SetConfigType("yaml")
|
||||
|
||||
cfgViper.SetConfigFile(configFile)
|
||||
|
||||
// try to read config into memory (viper map structure)
|
||||
if err := cfgViper.ReadInConfig(); err != nil {
|
||||
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
||||
log.Fatalf("Config file %s not found: %+v", configFile, err)
|
||||
}
|
||||
// config file found but some other error happened
|
||||
log.Fatalf("Failed to read config file %s: %+v", configFile, err)
|
||||
}
|
||||
|
||||
schema, err := config.GetSchemaByVersion(cfgViper.GetString("apiVersion"))
|
||||
if err != nil {
|
||||
log.Fatalf("Cannot validate config file %s: %+v", configFile, err)
|
||||
}
|
||||
|
||||
if err := config.ValidateSchemaFile(configFile, schema); err != nil {
|
||||
log.Fatalf("Schema Validation failed for config file %s: %+v", configFile, err)
|
||||
}
|
||||
|
||||
log.Infof("Using config file %s (%s#%s)", cfgViper.ConfigFileUsed(), strings.ToLower(cfgViper.GetString("apiVersion")), strings.ToLower(cfgViper.GetString("kind")))
|
||||
|
||||
cfg, err := config.FromViper(cfgViper)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
if cfg.GetAPIVersion() != config.DefaultConfigApiVersion {
|
||||
cfg, err = config.Migrate(cfg, config.DefaultConfigApiVersion)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
yamlout, err := yaml.Marshal(cfg)
|
||||
if err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
output := "-"
|
||||
|
||||
if len(args) > 1 {
|
||||
output = args[1]
|
||||
}
|
||||
|
||||
if output == "-" {
|
||||
if _, err := os.Stdout.Write(yamlout); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
} else {
|
||||
if err := os.WriteFile(output, yamlout, os.ModeAppend); err != nil {
|
||||
log.Fatalln(err)
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
@ -6,6 +6,8 @@ The code will output files in [`../docs/usage/commands/`](../docs/usage/commands
|
||||
|
||||
## Run
|
||||
|
||||
- may required a `replace github.com/rancher/k3d/v4 => PATH/TO/LOCAL/REPO` in the `go.mod`
|
||||
|
||||
```bash
|
||||
# ensure that you're in the docgen dir, as the relative path to the docs/ dir is hardcoded
|
||||
cd docgen
|
||||
|
@ -7,11 +7,8 @@ require (
|
||||
github.com/containerd/cgroups v0.0.0-20210414074453-680c246289fb // indirect
|
||||
github.com/containerd/containerd v1.5.0-rc.1 // indirect
|
||||
github.com/containerd/continuity v0.0.0-20210315143101-93e15499afd5 // indirect
|
||||
github.com/docker/cli v20.10.6+incompatible // indirect
|
||||
github.com/docker/docker v20.10.6+incompatible // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/imdario/mergo v0.3.12 // indirect
|
||||
github.com/magiconair/properties v1.8.5 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.1 // indirect
|
||||
github.com/pelletier/go-toml v1.9.0 // indirect
|
||||
@ -26,7 +23,6 @@ require (
|
||||
google.golang.org/genproto v0.0.0-20210413151531-c14fb6ef47c3 // indirect
|
||||
google.golang.org/grpc v1.37.0 // indirect
|
||||
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||
k8s.io/client-go v0.21.0 // indirect
|
||||
k8s.io/utils v0.0.0-20210305010621-2afb4311ab10 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.1 // indirect
|
||||
)
|
||||
|
@ -39,7 +39,6 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX
|
||||
github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
|
||||
github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
@ -212,7 +211,6 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
|
||||
github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ=
|
||||
@ -227,17 +225,15 @@ github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
|
||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/docker/cli v20.10.5+incompatible h1:bjflayQbWg+xOkF2WPEAOi4Y7zWhR7ptoPhV/VqLVDE=
|
||||
github.com/docker/cli v20.10.5+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v20.10.6+incompatible h1:LAyI6Lnwv+AUjtp2ZyN1lxqXBtkeFUqm4H7CZMWZuP8=
|
||||
github.com/docker/cli v20.10.6+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/distribution v0.0.0-20171011171712-7484e51bf6af/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/docker v20.10.5+incompatible h1:o5WL5onN4awYGwrW7+oTn5x9AF2prw7V0Ox8ZEkoCdg=
|
||||
github.com/docker/docker v20.10.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker v20.10.6+incompatible h1:oXI3Vas8TI8Eu/EjH4srKHJBVqraSzJybhxY7Om9faQ=
|
||||
github.com/docker/docker v20.10.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||
github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
|
||||
@ -253,7 +249,6 @@ github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZ
|
||||
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
|
||||
github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
|
||||
github.com/dvyukov/go-fuzz v0.0.0-20201127111758-49e582c6c23d/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw=
|
||||
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
|
||||
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
|
||||
@ -286,9 +281,8 @@ github.com/go-lintpack/lintpack v0.5.2/go.mod h1:NwZuYi2nUHho8XEIZ6SIxihrnPoqBTD
|
||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-logr/logr v0.2.0 h1:QvGt2nLcHH0WK9orKa+ppBPAxREcH364nPUedEpK0TY=
|
||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-logr/logr v0.4.0 h1:K7/B1jt6fIBQVd4Owv2MqGQClcgf0R266+7C/QjRcLc=
|
||||
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
@ -458,9 +452,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
|
||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
|
||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||
github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
|
||||
@ -494,12 +487,12 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
|
||||
github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
|
||||
@ -537,7 +530,6 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh
|
||||
github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag=
|
||||
github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A=
|
||||
github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c=
|
||||
github.com/moby/sys/mount v0.2.0 h1:WhCW5B355jtxndN5ovugJlMFJawbUODuW8fSnEH6SSM=
|
||||
github.com/moby/sys/mount v0.2.0/go.mod h1:aAivFE2LB3W4bACsUXChRHQ0qKWsetY4Y9V7sxOougM=
|
||||
github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A=
|
||||
@ -564,8 +556,6 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20160627004424-a22cb81b2ecd/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20171102151520-eafdab6b0663/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
|
||||
github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
|
||||
github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo=
|
||||
@ -660,8 +650,6 @@ github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
|
||||
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
|
||||
@ -795,11 +783,6 @@ go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
|
||||
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
|
||||
go4.org/intern v0.0.0-20210108033219-3eb7198706b2 h1:VFTf+jjIgsldaz/Mr00VaCSswHJrI2hIjQygE/W4IMg=
|
||||
go4.org/intern v0.0.0-20210108033219-3eb7198706b2/go.mod h1:vLqJ+12kCw61iCWsPto0EOHhBS+o4rO5VIucbc9g2Cc=
|
||||
go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222175341-b30ae309168e/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
|
||||
go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063 h1:1tk03FUNpulq2cuWpXZWj649rwJpk0d20rxWiopKRmc=
|
||||
go4.org/unsafe/assume-no-moving-gc v0.0.0-20201222180813-1025295fd063/go.mod h1:FftLjUGFEDu5k8lt0ddY+HcrH/qU/0qk+H8j9/nTl3E=
|
||||
golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
@ -815,7 +798,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@ -892,7 +875,6 @@ golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1 h1:4qWs8cYYH6PoEFy4dfhDFgoMGkwAcETd+MmPdCPMzUc=
|
||||
@ -985,7 +967,6 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -993,9 +974,7 @@ golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210414055047-fe65e336abe0 h1:g9s1Ppvvun/fI+BptTMj909BBIcGrzQ32k9FNlcevOE=
|
||||
golang.org/x/sys v0.0.0-20210414055047-fe65e336abe0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72 h1:VqE9gduFZ4dbR7XoL77lHFp0/DyDUBKSXK7CMFkVcV0=
|
||||
golang.org/x/term v0.0.0-20210406210042-72f3dc4e9b72/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@ -1012,9 +991,8 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e h1:EHBhcS0mlXEAVwNyO2dLfjToGsyY4j24pTs2ScHnX7s=
|
||||
golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE=
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20170915040203-e531a2a1c15f/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
@ -1176,9 +1154,8 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
@ -1218,22 +1195,17 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||
inet.af/netaddr v0.0.0-20210403172118-1e1430f727e0 h1:ANl7piXB3SHmhwTNeTO0yl0yf4gO3/aaFjcBCdH9Ftg=
|
||||
inet.af/netaddr v0.0.0-20210403172118-1e1430f727e0/go.mod h1:I2i9ONCXRZDnG1+7O8fSuYzjcPxHQXrIfzD/IkR87x4=
|
||||
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
|
||||
k8s.io/api v0.20.4 h1:xZjKidCirayzX6tHONRQyTNDVIR55TYVqgATqo6ZULY=
|
||||
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
|
||||
k8s.io/api v0.21.0 h1:gu5iGF4V6tfVCQ/R+8Hc0h7H1JuEhzyEi9S4R5LM8+Y=
|
||||
k8s.io/api v0.21.0/go.mod h1:+YbrhBBGgsxbF6o6Kj4KJPJnBmAKuXDeS3E18bgHNVU=
|
||||
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.20.4 h1:vhxQ0PPUUU2Ns1b9r4/UFp13UPs8cw2iOoTjnY9faa0=
|
||||
k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
|
||||
k8s.io/apimachinery v0.21.0 h1:3Fx+41if+IRavNcKOz09FwEXDBG6ORh6iMsTSelhkMA=
|
||||
k8s.io/apimachinery v0.21.0/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY=
|
||||
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
|
||||
k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
|
||||
k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
|
||||
k8s.io/client-go v0.20.4 h1:85crgh1IotNkLpKYKZHVNI1JT86nr/iDCvq2iWKsql4=
|
||||
k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
|
||||
k8s.io/client-go v0.21.0 h1:n0zzzJsAQmJngpC0IhgFcApZyoGXPrDIAD601HD09ag=
|
||||
k8s.io/client-go v0.21.0/go.mod h1:nNBytTF9qPFDEhoqgEPaarobC8QPae13bElIVHzIglA=
|
||||
k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
|
||||
k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
|
||||
k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM=
|
||||
@ -1241,11 +1213,9 @@ k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
|
||||
k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
|
||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
|
||||
k8s.io/klog/v2 v2.4.0 h1:7+X0fUguPyrKEC4WjH8iGDg3laWgMo5tMnRTIGTTxGQ=
|
||||
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
|
||||
k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts=
|
||||
k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
|
||||
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
|
||||
k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
|
||||
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20210305010621-2afb4311ab10 h1:u5rPykqiCpL+LBfjRkXvnK71gOgIdmq3eHUEkPrbeTI=
|
||||
@ -1258,7 +1228,6 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.1 h1:nYqY2A6oy37sKLYuSBXuQhbj4JVclzJK13BOIvJG5XU=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
|
||||
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
|
||||
|
@ -25,16 +25,16 @@ k3d cluster create NAME [flags]
|
||||
- Example: `k3d cluster create --servers 3 --api-port 0.0.0.0:6550`
|
||||
-c, --config string Path of a config file to use
|
||||
-e, --env KEY[=VALUE][@NODEFILTER[;NODEFILTER...]] Add environment variables to nodes (Format: KEY[=VALUE][@NODEFILTER[;NODEFILTER...]]
|
||||
- Example: `k3d cluster create --agents 2 -e "HTTP_PROXY=my.proxy.com" -e "SOME_KEY=SOME_VAL@server[0]"`
|
||||
- Example: `k3d cluster create --agents 2 -e "HTTP_PROXY=my.proxy.com@server[0]" -e "SOME_KEY=SOME_VAL@server[0]"`
|
||||
--gpus string GPU devices to add to the cluster node containers ('all' to pass all GPUs) [From docker]
|
||||
-h, --help help for create
|
||||
-i, --image string Specify k3s image that you want to use for the nodes
|
||||
--k3s-agent-arg k3s agent Additional args passed to the k3s agent command on agent nodes (new flag per arg)
|
||||
--k3s-server-arg k3s server Additional args passed to the k3s server command on server nodes (new flag per arg)
|
||||
--k3s-arg ARG@NODEFILTER[;@NODEFILTER] Additional args passed to k3s command (Format: ARG@NODEFILTER[;@NODEFILTER])
|
||||
- Example: `k3d cluster create --k3s-arg "--disable=traefik@server[0]"
|
||||
--kubeconfig-switch-context Directly switch the default kubeconfig's current-context to the new cluster's context (requires --kubeconfig-update-default) (default true)
|
||||
--kubeconfig-update-default Directly update the default kubeconfig with the new cluster's context (default true)
|
||||
-l, --label KEY[=VALUE][@NODEFILTER[;NODEFILTER...]] Add label to node container (Format: KEY[=VALUE][@NODEFILTER[;NODEFILTER...]]
|
||||
- Example: `k3d cluster create --agents 2 -l "my.label@agent[0,1]" -v "other.label=somevalue@server[0]"`
|
||||
- Example: `k3d cluster create --agents 2 -l "my.label@agent[0,1]" -l "other.label=somevalue@server[0]"`
|
||||
--network string Join an existing network
|
||||
--no-hostip Disable the automatic injection of the Host IP as 'host.k3d.internal' into the containers and CoreDNS
|
||||
--no-image-volume Disable the creation of a volume for importing images
|
||||
|
@ -28,4 +28,5 @@ k3d config [flags]
|
||||
|
||||
* [k3d](k3d.md) - https://k3d.io/ -> Run k3s in Docker!
|
||||
* [k3d config init](k3d_config_init.md) -
|
||||
* [k3d config migrate](k3d_config_migrate.md) -
|
||||
|
||||
|
@ -1,15 +1,15 @@
|
||||
## k3d docgen
|
||||
## k3d config migrate
|
||||
|
||||
|
||||
Generate command docs
|
||||
|
||||
```
|
||||
k3d docgen [flags]
|
||||
k3d config migrate INPUT OUTPUT [flags]
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-h, --help help for docgen
|
||||
-h, --help help for migrate
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
@ -22,5 +22,5 @@ k3d docgen [flags]
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [k3d](k3d.md) - https://k3d.io/ -> Run k3s in Docker!
|
||||
* [k3d config](k3d_config.md) - Work with config file(s)
|
||||
|
@ -13,14 +13,15 @@ k3d node create NAME [flags]
|
||||
### Options
|
||||
|
||||
```
|
||||
-c, --cluster string Select the cluster that the node shall connect to. (default "k3s-default")
|
||||
-h, --help help for create
|
||||
-i, --image string Specify k3s image used for the node(s) (default "docker.io/rancher/k3s:v1.20.0-k3s2")
|
||||
--memory string Memory limit imposed on the node [From docker]
|
||||
--replicas int Number of replicas of this node specification. (default 1)
|
||||
--role string Specify node role [server, agent] (default "agent")
|
||||
--timeout duration Maximum waiting time for '--wait' before canceling/returning.
|
||||
--wait Wait for the node(s) to be ready before returning.
|
||||
-c, --cluster string Select the cluster that the node shall connect to. (default "k3s-default")
|
||||
-h, --help help for create
|
||||
-i, --image string Specify k3s image used for the node(s) (default "docker.io/rancher/k3s:v1.20.0-k3s2")
|
||||
--k3s-node-label strings Specify k3s node labels in format "foo=bar"
|
||||
--memory string Memory limit imposed on the node [From docker]
|
||||
--replicas int Number of replicas of this node specification. (default 1)
|
||||
--role string Specify node role [server, agent] (default "agent")
|
||||
--timeout duration Maximum waiting time for '--wait' before canceling/returning.
|
||||
--wait Wait for the node(s) to be ready before returning.
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
@ -25,13 +25,13 @@ Using a config file is as easy as putting it in a well-known place in your file
|
||||
|
||||
As of the time of writing this documentation, the config file only **requires** you to define two fields:
|
||||
|
||||
- `apiVersion` to match the version of the config file that you want to use (at this time it would be `apiVersion: k3d.io/v1alpha2`)
|
||||
- `apiVersion` to match the version of the config file that you want to use (at this time it would be `apiVersion: k3d.io/v1alpha3`)
|
||||
- `kind` to define the kind of config file that you want to use (currently we only have the `Simple` config)
|
||||
|
||||
So this would be the minimal config file, which configures absolutely nothing:
|
||||
|
||||
```yaml
|
||||
apiVersion: k3d.io/v1alpha2
|
||||
apiVersion: k3d.io/v1alpha3
|
||||
kind: Simple
|
||||
```
|
||||
|
||||
@ -43,7 +43,7 @@ Currently, the config file is still in an Alpha-State, meaning, that it is subje
|
||||
!!! info "Validation via JSON-Schema"
|
||||
k3d uses a [JSON-Schema](https://json-schema.org/) to describe the expected format and fields of the configuration file.
|
||||
This schema is also used to [validate](https://github.com/xeipuuv/gojsonschema#validation) a user-given config file.
|
||||
This JSON-Schema can be found in the specific config version sub-directory in the repository (e.g. [here for `v1alpha2`](https://github.com/rancher/k3d/blob/main/pkg/config/v1alpha2/schema.json)) and could be used to lookup supported fields or by linters to validate the config file, e.g. in your code editor.
|
||||
This JSON-Schema can be found in the specific config version sub-directory in the repository (e.g. [here for `v1alpha3`](https://github.com/rancher/k3d/blob/main/pkg/config/v1alpha3/schema.json)) and could be used to lookup supported fields or by linters to validate the config file, e.g. in your code editor.
|
||||
|
||||
### All Options: Example
|
||||
|
||||
@ -51,7 +51,7 @@ Since the config options and the config file are changing quite a bit, it's hard
|
||||
|
||||
```yaml
|
||||
# k3d configuration file, saved as e.g. /home/me/myk3dcluster.yaml
|
||||
apiVersion: k3d.io/v1alpha2 # this will change in the future as we make everything more stable
|
||||
apiVersion: k3d.io/v1alpha3 # 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
|
||||
name: mycluster # name that you want to give to your cluster (will still be prefixed with `k3d-`)
|
||||
servers: 1 # same as `--servers 1`
|
||||
@ -98,9 +98,10 @@ options:
|
||||
disableRollback: false # same as `--no-Rollback`
|
||||
disableHostIPInjection: false # same as `--no-hostip`
|
||||
k3s: # options passed on to K3s itself
|
||||
extraServerArgs: # additional arguments passed to the `k3s server` command; same as `--k3s-server-arg`
|
||||
- --tls-san=my.host.domain
|
||||
extraAgentArgs: [] # addditional arguments passed to the `k3s agent` command; same as `--k3s-agent-arg`
|
||||
extraArgs: # additional arguments passed to the `k3s server|agent` command; same as `--k3s-arg`
|
||||
- arg: --tls-san=my.host.domain
|
||||
nodeFilters:
|
||||
- server[*]
|
||||
kubeconfig:
|
||||
updateDefaultKubeconfig: true # add new cluster to your default Kubeconfig; same as `--kubeconfig-update-default` (default: true)
|
||||
switchCurrentContext: true # also set current-context to the new cluster's context; same as `--kubeconfig-switch-context` (default: true)
|
||||
|
@ -29,7 +29,7 @@ This file can also be used for providing additional information necessary for ac
|
||||
If you're using a `SimpleConfig` file to configure your k3d cluster, you may as well embed the registries.yaml in there directly:
|
||||
|
||||
```yaml
|
||||
apiVersion: k3d.io/v1alpha2
|
||||
apiVersion: k3d.io/v1alpha3
|
||||
kind: Simple
|
||||
name: test
|
||||
servers: 1
|
||||
|
@ -36,7 +36,7 @@ import (
|
||||
"github.com/docker/go-connections/nat"
|
||||
"github.com/imdario/mergo"
|
||||
"github.com/rancher/k3d/v4/pkg/actions"
|
||||
config "github.com/rancher/k3d/v4/pkg/config/v1alpha2"
|
||||
config "github.com/rancher/k3d/v4/pkg/config/v1alpha3"
|
||||
k3drt "github.com/rancher/k3d/v4/pkg/runtimes"
|
||||
"github.com/rancher/k3d/v4/pkg/runtimes/docker"
|
||||
runtimeErr "github.com/rancher/k3d/v4/pkg/runtimes/errors"
|
||||
|
@ -29,43 +29,51 @@ import (
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha2"
|
||||
"github.com/rancher/k3d/v4/pkg/config/v1alpha2"
|
||||
"github.com/rancher/k3d/v4/pkg/config/v1alpha3"
|
||||
defaultConfig "github.com/rancher/k3d/v4/pkg/config/v1alpha3"
|
||||
|
||||
types "github.com/rancher/k3d/v4/pkg/config/types"
|
||||
)
|
||||
|
||||
func FromViperSimple(config *viper.Viper) (conf.SimpleConfig, error) {
|
||||
const DefaultConfigApiVersion = defaultConfig.ApiVersion
|
||||
|
||||
var cfg conf.SimpleConfig
|
||||
|
||||
// determine config kind
|
||||
if config.GetString("kind") != "" && strings.ToLower(config.GetString("kind")) != "simple" {
|
||||
return cfg, fmt.Errorf("Wrong `kind` '%s' != 'simple' in config file", config.GetString("kind"))
|
||||
}
|
||||
|
||||
if err := config.Unmarshal(&cfg); err != nil {
|
||||
log.Errorln("Failed to unmarshal File config")
|
||||
|
||||
return cfg, err
|
||||
}
|
||||
|
||||
return cfg, nil
|
||||
var Schemas = map[string]string{
|
||||
v1alpha2.ApiVersion: v1alpha2.JSONSchema,
|
||||
v1alpha3.ApiVersion: v1alpha3.JSONSchema,
|
||||
}
|
||||
|
||||
func FromViper(config *viper.Viper) (conf.Config, error) {
|
||||
func GetSchemaByVersion(apiVersion string) ([]byte, error) {
|
||||
schema, ok := Schemas[strings.ToLower(apiVersion)]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unsupported apiVersion '%s'", apiVersion)
|
||||
}
|
||||
return []byte(schema), nil
|
||||
}
|
||||
|
||||
var cfg conf.Config
|
||||
func FromViper(config *viper.Viper) (types.Config, error) {
|
||||
|
||||
// determine config kind
|
||||
switch strings.ToLower(config.GetString("kind")) {
|
||||
case "simple":
|
||||
cfg = conf.SimpleConfig{}
|
||||
case "cluster":
|
||||
cfg = conf.ClusterConfig{}
|
||||
case "clusterlist":
|
||||
cfg = conf.ClusterListConfig{}
|
||||
var cfg types.Config
|
||||
var err error
|
||||
|
||||
apiVersion := strings.ToLower(config.GetString("apiversion"))
|
||||
kind := strings.ToLower(config.GetString("kind"))
|
||||
|
||||
log.Tracef("Trying to read config apiVersion='%s', kind='%s'", apiVersion, kind)
|
||||
|
||||
switch apiVersion {
|
||||
case "k3d.io/v1alpha2":
|
||||
cfg, err = v1alpha2.GetConfigByKind(kind)
|
||||
case "k3d.io/v1alpha3":
|
||||
cfg, err = v1alpha3.GetConfigByKind(kind)
|
||||
case "":
|
||||
return nil, fmt.Errorf("Missing `kind` in config file")
|
||||
cfg, err = defaultConfig.GetConfigByKind(kind)
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown `kind` '%s' in config file", config.GetString("kind"))
|
||||
return nil, fmt.Errorf("cannot read config with apiversion '%s'", config.GetString("apiversion"))
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := config.Unmarshal(&cfg); err != nil {
|
||||
@ -76,3 +84,12 @@ func FromViper(config *viper.Viper) (conf.Config, error) {
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
func getMigrations(version string) map[string]func(types.Config) (types.Config, error) {
|
||||
switch version {
|
||||
case v1alpha3.ApiVersion:
|
||||
return v1alpha3.Migrations
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,8 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/go-test/deep"
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha2"
|
||||
configtypes "github.com/rancher/k3d/v4/pkg/config/types"
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha3"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
k3d "github.com/rancher/k3d/v4/pkg/types"
|
||||
@ -39,8 +40,8 @@ func TestReadSimpleConfig(t *testing.T) {
|
||||
exposedAPI.HostPort = "6443"
|
||||
|
||||
expectedConfig := conf.SimpleConfig{
|
||||
TypeMeta: conf.TypeMeta{
|
||||
APIVersion: "k3d.io/v1alpha2",
|
||||
TypeMeta: configtypes.TypeMeta{
|
||||
APIVersion: "k3d.io/v1alpha3",
|
||||
Kind: "Simple",
|
||||
},
|
||||
Name: "test",
|
||||
@ -83,8 +84,12 @@ func TestReadSimpleConfig(t *testing.T) {
|
||||
DisableImageVolume: false,
|
||||
},
|
||||
K3sOptions: conf.SimpleConfigOptionsK3s{
|
||||
ExtraServerArgs: []string{"--tls-san=127.0.0.1"},
|
||||
ExtraAgentArgs: []string{},
|
||||
ExtraArgs: []conf.K3sArgWithNodeFilters{
|
||||
{
|
||||
Arg: "--tls-san=127.0.0.1",
|
||||
NodeFilters: []string{"server[*]"},
|
||||
},
|
||||
},
|
||||
},
|
||||
KubeconfigOptions: conf.SimpleConfigOptionsKubeconfig{
|
||||
UpdateDefaultKubeconfig: true,
|
||||
@ -107,7 +112,7 @@ func TestReadSimpleConfig(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
cfg, err := FromViperSimple(config)
|
||||
cfg, err := FromViper(config)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@ -123,8 +128,8 @@ func TestReadSimpleConfig(t *testing.T) {
|
||||
func TestReadClusterConfig(t *testing.T) {
|
||||
|
||||
expectedConfig := conf.ClusterConfig{
|
||||
TypeMeta: conf.TypeMeta{
|
||||
APIVersion: "k3d.io/v1alpha2",
|
||||
TypeMeta: configtypes.TypeMeta{
|
||||
APIVersion: "k3d.io/v1alpha3",
|
||||
Kind: "Cluster",
|
||||
},
|
||||
Cluster: k3d.Cluster{
|
||||
@ -168,8 +173,8 @@ func TestReadClusterConfig(t *testing.T) {
|
||||
func TestReadClusterListConfig(t *testing.T) {
|
||||
|
||||
expectedConfig := conf.ClusterListConfig{
|
||||
TypeMeta: conf.TypeMeta{
|
||||
APIVersion: "k3d.io/v1alpha2",
|
||||
TypeMeta: configtypes.TypeMeta{
|
||||
APIVersion: "k3d.io/v1alpha3",
|
||||
Kind: "ClusterList",
|
||||
},
|
||||
Clusters: []k3d.Cluster{
|
||||
@ -237,7 +242,7 @@ func TestReadUnknownConfig(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err := FromViperSimple(config)
|
||||
_, err := FromViper(config)
|
||||
if err == nil {
|
||||
t.Fail()
|
||||
}
|
||||
|
@ -24,14 +24,14 @@ package config
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/rancher/k3d/v4/pkg/config/v1alpha2"
|
||||
"github.com/rancher/k3d/v4/pkg/config/v1alpha3"
|
||||
)
|
||||
|
||||
func TestValidateSchema(t *testing.T) {
|
||||
|
||||
cfgPath := "./test_assets/config_test_simple.yaml"
|
||||
|
||||
if err := ValidateSchemaFile(cfgPath, []byte(v1alpha2.JSONSchema)); err != nil {
|
||||
if err := ValidateSchemaFile(cfgPath, []byte(v1alpha3.JSONSchema)); err != nil {
|
||||
t.Errorf("Validation of config file %s against the default schema failed: %+v", cfgPath, err)
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ func TestValidateSchemaFail(t *testing.T) {
|
||||
cfgPath := "./test_assets/config_test_simple_invalid_servers.yaml"
|
||||
|
||||
var err error
|
||||
if err = ValidateSchemaFile(cfgPath, []byte(v1alpha2.JSONSchema)); err == nil {
|
||||
if err = ValidateSchemaFile(cfgPath, []byte(v1alpha3.JSONSchema)); err == nil {
|
||||
t.Errorf("Validation of config file %s against the default schema passed where we expected a failure", cfgPath)
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ package config
|
||||
|
||||
import (
|
||||
"github.com/imdario/mergo"
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha2"
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha3"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -25,7 +25,8 @@ package config
|
||||
import (
|
||||
"testing"
|
||||
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha2"
|
||||
configtypes "github.com/rancher/k3d/v4/pkg/config/types"
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha3"
|
||||
"github.com/spf13/viper"
|
||||
"gotest.tools/assert"
|
||||
)
|
||||
@ -34,7 +35,7 @@ func TestMergeSimpleConfig(t *testing.T) {
|
||||
srcConfig := "./test_assets/config_test_simple.yaml"
|
||||
destConfig := "./test_assets/config_test_simple_2.yaml"
|
||||
|
||||
var src, dest conf.Config
|
||||
var src, dest configtypes.Config
|
||||
var err error
|
||||
|
||||
cfg1 := viper.New()
|
||||
@ -45,11 +46,11 @@ func TestMergeSimpleConfig(t *testing.T) {
|
||||
cfg2.SetConfigFile(destConfig)
|
||||
_ = cfg2.ReadInConfig()
|
||||
|
||||
if src, err = FromViperSimple(cfg1); err != nil {
|
||||
if src, err = FromViper(cfg1); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if dest, err = FromViperSimple(cfg2); err != nil {
|
||||
if dest, err = FromViper(cfg2); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
40
pkg/config/migrate.go
Normal file
40
pkg/config/migrate.go
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright © 2020 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 (
|
||||
"fmt"
|
||||
|
||||
types "github.com/rancher/k3d/v4/pkg/config/types"
|
||||
)
|
||||
|
||||
func Migrate(config types.Config, targetVersion string) (types.Config, error) {
|
||||
|
||||
migration, ok := getMigrations(targetVersion)[config.GetAPIVersion()]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no migration possible from '%s' to '%s'", config.GetAPIVersion(), targetVersion)
|
||||
}
|
||||
|
||||
return migration(config)
|
||||
|
||||
}
|
@ -23,7 +23,7 @@ THE SOFTWARE.
|
||||
package config
|
||||
|
||||
import (
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha2"
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha3"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha3"
|
||||
"github.com/rancher/k3d/v4/pkg/runtimes"
|
||||
"github.com/spf13/viper"
|
||||
"gotest.tools/assert"
|
||||
@ -38,14 +39,14 @@ func TestProcessClusterConfig(t *testing.T) {
|
||||
vip.SetConfigFile(cfgFile)
|
||||
_ = vip.ReadInConfig()
|
||||
|
||||
cfg, err := FromViperSimple(vip)
|
||||
cfg, err := FromViper(vip)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
t.Logf("\n========== Read Config and transform to cluster ==========\n%+v\n=================================\n", cfg)
|
||||
|
||||
clusterCfg, err := TransformSimpleToClusterConfig(context.Background(), runtimes.Docker, cfg)
|
||||
clusterCfg, err := TransformSimpleToClusterConfig(context.Background(), runtimes.Docker, cfg.(conf.SimpleConfig))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
apiVersion: k3d.io/v1alpha2
|
||||
apiVersion: k3d.io/v1alpha3
|
||||
kind: Cluster
|
||||
name: foo
|
||||
nodes:
|
||||
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
apiVersion: k3d.io/v1alpha2
|
||||
apiVersion: k3d.io/v1alpha3
|
||||
kind: ClusterList
|
||||
clusters:
|
||||
- name: foo
|
||||
|
@ -1,4 +1,4 @@
|
||||
apiVersion: k3d.io/v1alpha2
|
||||
apiVersion: k3d.io/v1alpha3
|
||||
kind: Simple
|
||||
name: test
|
||||
servers: 1
|
||||
@ -25,7 +25,7 @@ env:
|
||||
labels:
|
||||
- label: foo=bar
|
||||
nodeFilters:
|
||||
- server[0]
|
||||
- "server[0]"
|
||||
- loadbalancer
|
||||
|
||||
options:
|
||||
@ -35,9 +35,10 @@ options:
|
||||
disableLoadbalancer: false
|
||||
disableImageVolume: false
|
||||
k3s:
|
||||
extraServerArgs:
|
||||
- --tls-san=127.0.0.1
|
||||
extraAgentArgs: []
|
||||
extraArgs:
|
||||
- arg: --tls-san=127.0.0.1
|
||||
nodeFilters:
|
||||
- "server[*]"
|
||||
kubeconfig:
|
||||
updateDefaultKubeconfig: true
|
||||
switchCurrentContext: true
|
||||
switchCurrentContext: true
|
||||
|
@ -1,4 +1,4 @@
|
||||
apiVersion: k3d.io/v1alpha2
|
||||
apiVersion: k3d.io/v1alpha3
|
||||
kind: Simple
|
||||
name: supertest
|
||||
agents: 8
|
@ -1,4 +1,4 @@
|
||||
apiVersion: k3d.io/v1alpha2
|
||||
apiVersion: k3d.io/v1alpha3
|
||||
kind: Simple
|
||||
name: 1234
|
||||
servers: 1
|
||||
@ -35,9 +35,10 @@ options:
|
||||
disableLoadbalancer: false
|
||||
disableImageVolume: false
|
||||
k3s:
|
||||
extraServerArgs:
|
||||
- --tls-san=127.0.0.1
|
||||
extraAgentArgs: []
|
||||
extraArgs:
|
||||
- arg: --tls-san=127.0.0.1
|
||||
nodeFilters:
|
||||
- "server[*]"
|
||||
kubeconfig:
|
||||
updateDefaultKubeconfig: true
|
||||
switchCurrentContext: true
|
@ -1,3 +1,3 @@
|
||||
apiVersion: k3d.io/v1alpha2
|
||||
apiVersion: k3d.io/v1alpha3
|
||||
kind: Unknown
|
||||
foo: bar
|
@ -31,7 +31,7 @@ import (
|
||||
|
||||
"github.com/docker/go-connections/nat"
|
||||
cliutil "github.com/rancher/k3d/v4/cmd/util" // TODO: move parseapiport to pkg
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha2"
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha3"
|
||||
"github.com/rancher/k3d/v4/pkg/runtimes"
|
||||
k3d "github.com/rancher/k3d/v4/pkg/types"
|
||||
"github.com/rancher/k3d/v4/pkg/types/k3s"
|
||||
@ -117,7 +117,6 @@ func TransformSimpleToClusterConfig(ctx context.Context, runtime runtimes.Runtim
|
||||
serverNode := k3d.Node{
|
||||
Role: k3d.ServerRole,
|
||||
Image: simpleConfig.Image,
|
||||
Args: simpleConfig.Options.K3sOptions.ExtraServerArgs,
|
||||
ServerOpts: k3d.ServerOpts{},
|
||||
Memory: simpleConfig.Options.Runtime.ServersMemory,
|
||||
}
|
||||
@ -135,7 +134,6 @@ func TransformSimpleToClusterConfig(ctx context.Context, runtime runtimes.Runtim
|
||||
agentNode := k3d.Node{
|
||||
Role: k3d.AgentRole,
|
||||
Image: simpleConfig.Image,
|
||||
Args: simpleConfig.Options.K3sOptions.ExtraAgentArgs,
|
||||
Memory: simpleConfig.Options.Runtime.AgentsMemory,
|
||||
}
|
||||
newCluster.Nodes = append(newCluster.Nodes, &agentNode)
|
||||
@ -228,6 +226,22 @@ func TransformSimpleToClusterConfig(ctx context.Context, runtime runtimes.Runtim
|
||||
}
|
||||
}
|
||||
|
||||
// -> ARGS
|
||||
for _, argWithNodeFilters := range simpleConfig.Options.K3sOptions.ExtraArgs {
|
||||
if len(argWithNodeFilters.NodeFilters) == 0 && nodeCount > 1 {
|
||||
return nil, fmt.Errorf("K3sExtraArg '%s' lacks a node filter, but there's more than one node", argWithNodeFilters.Arg)
|
||||
}
|
||||
|
||||
nodes, err := util.FilterNodes(nodeList, argWithNodeFilters.NodeFilters)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, node := range nodes {
|
||||
node.Args = append(node.Args, argWithNodeFilters.Arg)
|
||||
}
|
||||
}
|
||||
|
||||
/**************************
|
||||
* Cluster Create Options *
|
||||
**************************/
|
||||
@ -238,8 +252,6 @@ func TransformSimpleToClusterConfig(ctx context.Context, runtime runtimes.Runtim
|
||||
WaitForServer: simpleConfig.Options.K3dOptions.Wait,
|
||||
Timeout: simpleConfig.Options.K3dOptions.Timeout,
|
||||
DisableLoadBalancer: simpleConfig.Options.K3dOptions.DisableLoadbalancer,
|
||||
K3sServerArgs: simpleConfig.Options.K3sOptions.ExtraServerArgs,
|
||||
K3sAgentArgs: simpleConfig.Options.K3sOptions.ExtraAgentArgs,
|
||||
GPURequest: simpleConfig.Options.Runtime.GPURequest,
|
||||
ServersMemory: simpleConfig.Options.Runtime.ServersMemory,
|
||||
AgentsMemory: simpleConfig.Options.Runtime.AgentsMemory,
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha3"
|
||||
"github.com/rancher/k3d/v4/pkg/runtimes"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
@ -37,14 +38,14 @@ func TestTransformSimpleConfigToClusterConfig(t *testing.T) {
|
||||
vip.SetConfigFile(cfgFile)
|
||||
_ = vip.ReadInConfig()
|
||||
|
||||
cfg, err := FromViperSimple(vip)
|
||||
cfg, err := FromViper(vip)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
t.Logf("\n========== Read Config ==========\n%+v\n=================================\n", cfg)
|
||||
|
||||
clusterCfg, err := TransformSimpleToClusterConfig(context.Background(), runtimes.Docker, cfg)
|
||||
clusterCfg, err := TransformSimpleToClusterConfig(context.Background(), runtimes.Docker, cfg.(conf.SimpleConfig))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
34
pkg/config/types/types.go
Normal file
34
pkg/config/types/types.go
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
Copyright © 2020 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 types
|
||||
|
||||
// TypeMeta is basically copied from https://github.com/kubernetes/apimachinery/blob/a3b564b22db316a41e94fdcffcf9995424fe924c/pkg/apis/meta/v1/types.go#L36-L56
|
||||
type TypeMeta struct {
|
||||
Kind string `mapstructure:"kind,omitempty" yaml:"kind,omitempty" json:"kind,omitempty"`
|
||||
APIVersion string `mapstructure:"apiVersion,omitempty" yaml:"apiVersion,omitempty" json:"apiVersion,omitempty"`
|
||||
}
|
||||
|
||||
// Config interface.
|
||||
type Config interface {
|
||||
GetKind() string
|
||||
GetAPIVersion() string
|
||||
}
|
@ -27,6 +27,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
configtypes "github.com/rancher/k3d/v4/pkg/config/types"
|
||||
k3d "github.com/rancher/k3d/v4/pkg/types"
|
||||
"github.com/rancher/k3d/v4/version"
|
||||
)
|
||||
@ -35,9 +36,11 @@ import (
|
||||
//go:embed schema.json
|
||||
var JSONSchema string
|
||||
|
||||
const ApiVersion = "k3d.io/v1alpha2"
|
||||
|
||||
// DefaultConfigTpl for printing
|
||||
const DefaultConfigTpl = `---
|
||||
apiVersion: k3d.io/v1alpha2
|
||||
apiVersion: %s
|
||||
kind: Simple
|
||||
name: %s
|
||||
servers: 1
|
||||
@ -48,21 +51,11 @@ image: %s
|
||||
// DefaultConfig templated DefaultConfigTpl
|
||||
var DefaultConfig = fmt.Sprintf(
|
||||
DefaultConfigTpl,
|
||||
ApiVersion,
|
||||
k3d.DefaultClusterName,
|
||||
fmt.Sprintf("%s:%s", k3d.DefaultK3sImageRepo, version.GetK3sVersion(false)),
|
||||
)
|
||||
|
||||
// TypeMeta is basically copied from https://github.com/kubernetes/apimachinery/blob/a3b564b22db316a41e94fdcffcf9995424fe924c/pkg/apis/meta/v1/types.go#L36-L56
|
||||
type TypeMeta struct {
|
||||
Kind string `mapstructure:"kind,omitempty" yaml:"kind,omitempty" json:"kind,omitempty"`
|
||||
APIVersion string `mapstructure:"apiVersion,omitempty" yaml:"apiVersion,omitempty" json:"apiVersion,omitempty"`
|
||||
}
|
||||
|
||||
// Config interface.
|
||||
type Config interface {
|
||||
GetKind() string
|
||||
}
|
||||
|
||||
type VolumeWithNodeFilters struct {
|
||||
Volume string `mapstructure:"volume" yaml:"volume" json:"volume,omitempty"`
|
||||
NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters" json:"nodeFilters,omitempty"`
|
||||
@ -119,21 +112,21 @@ type SimpleConfigOptionsK3s struct {
|
||||
|
||||
// SimpleConfig describes the toplevel k3d configuration file.
|
||||
type SimpleConfig struct {
|
||||
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"`
|
||||
Registries 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"`
|
||||
Registries struct {
|
||||
Use []string `mapstructure:"use" yaml:"use,omitempty" json:"use,omitempty"`
|
||||
Create bool `mapstructure:"create" yaml:"create,omitempty" json:"create,omitempty"`
|
||||
Config string `mapstructure:"config" yaml:"config,omitempty" json:"config,omitempty"` // registries.yaml (k3s config for containerd registry override)
|
||||
@ -147,30 +140,60 @@ type SimpleExposureOpts struct {
|
||||
HostPort string `mapstructure:"hostPort" yaml:"hostPort,omitempty" json:"hostPort,omitempty"`
|
||||
}
|
||||
|
||||
// GetKind implements Config.GetKind
|
||||
// Kind implements Config.Kind
|
||||
func (c SimpleConfig) GetKind() string {
|
||||
return "Cluster"
|
||||
return "Simple"
|
||||
}
|
||||
|
||||
func (c SimpleConfig) GetAPIVersion() string {
|
||||
return ApiVersion
|
||||
}
|
||||
|
||||
// ClusterConfig describes a single cluster config
|
||||
type ClusterConfig struct {
|
||||
TypeMeta `mapstructure:",squash" yaml:",inline"`
|
||||
Cluster k3d.Cluster `mapstructure:",squash" yaml:",inline"`
|
||||
ClusterCreateOpts k3d.ClusterCreateOpts `mapstructure:"options" yaml:"options"`
|
||||
KubeconfigOpts SimpleConfigOptionsKubeconfig `mapstructure:"kubeconfig" yaml:"kubeconfig"`
|
||||
configtypes.TypeMeta `mapstructure:",squash" yaml:",inline"`
|
||||
Cluster k3d.Cluster `mapstructure:",squash" yaml:",inline"`
|
||||
ClusterCreateOpts k3d.ClusterCreateOpts `mapstructure:"options" yaml:"options"`
|
||||
KubeconfigOpts SimpleConfigOptionsKubeconfig `mapstructure:"kubeconfig" yaml:"kubeconfig"`
|
||||
}
|
||||
|
||||
// GetKind implements Config.GetKind
|
||||
// Kind implements Config.Kind
|
||||
func (c ClusterConfig) GetKind() string {
|
||||
return "Cluster"
|
||||
return "Simple"
|
||||
}
|
||||
|
||||
func (c ClusterConfig) GetAPIVersion() string {
|
||||
return ApiVersion
|
||||
}
|
||||
|
||||
// ClusterListConfig describes a list of clusters
|
||||
type ClusterListConfig struct {
|
||||
TypeMeta `mapstructure:",squash" yaml:",inline"`
|
||||
Clusters []k3d.Cluster `mapstructure:"clusters" yaml:"clusters"`
|
||||
configtypes.TypeMeta `mapstructure:",squash" yaml:",inline"`
|
||||
Clusters []k3d.Cluster `mapstructure:"clusters" yaml:"clusters"`
|
||||
}
|
||||
|
||||
func (c ClusterListConfig) GetKind() string {
|
||||
return "ClusterList"
|
||||
return "Simple"
|
||||
}
|
||||
|
||||
func (c ClusterListConfig) GetAPIVersion() string {
|
||||
return ApiVersion
|
||||
}
|
||||
|
||||
func GetConfigByKind(kind string) (configtypes.Config, error) {
|
||||
|
||||
// determine config kind
|
||||
switch kind {
|
||||
case "simple":
|
||||
return SimpleConfig{}, nil
|
||||
case "cluster":
|
||||
return ClusterConfig{}, nil
|
||||
case "clusterlist":
|
||||
return ClusterListConfig{}, nil
|
||||
case "":
|
||||
return nil, fmt.Errorf("missing `kind` in config file")
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown `kind` '%s' in config file", kind)
|
||||
}
|
||||
|
||||
}
|
||||
|
84
pkg/config/v1alpha3/migrations.go
Normal file
84
pkg/config/v1alpha3/migrations.go
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
Copyright © 2020 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 v1alpha3
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
configtypes "github.com/rancher/k3d/v4/pkg/config/types"
|
||||
"github.com/rancher/k3d/v4/pkg/config/v1alpha2"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var Migrations = map[string]func(configtypes.Config) (configtypes.Config, error){
|
||||
v1alpha2.ApiVersion: MigrateV1Alpha2,
|
||||
}
|
||||
|
||||
func MigrateV1Alpha2(input configtypes.Config) (configtypes.Config, error) {
|
||||
log.Debugln("Migrating v1alpha2 to v1alpha3")
|
||||
|
||||
injson, err := json.Marshal(input)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if input.GetKind() == "Simple" {
|
||||
cfg := SimpleConfig{}
|
||||
|
||||
if err := json.Unmarshal(injson, &cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg.Options.K3sOptions.ExtraArgs = []K3sArgWithNodeFilters{}
|
||||
|
||||
for _, arg := range input.(v1alpha2.SimpleConfig).Options.K3sOptions.ExtraServerArgs {
|
||||
cfg.Options.K3sOptions.ExtraArgs = append(cfg.Options.K3sOptions.ExtraArgs, K3sArgWithNodeFilters{
|
||||
Arg: arg,
|
||||
NodeFilters: []string{
|
||||
"server[*]",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
for _, arg := range input.(v1alpha2.SimpleConfig).Options.K3sOptions.ExtraAgentArgs {
|
||||
cfg.Options.K3sOptions.ExtraArgs = append(cfg.Options.K3sOptions.ExtraArgs, K3sArgWithNodeFilters{
|
||||
Arg: arg,
|
||||
NodeFilters: []string{
|
||||
"agent[*]",
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
cfg.APIVersion = ApiVersion
|
||||
|
||||
log.Debugf("Migrated config: %+v", cfg)
|
||||
|
||||
return cfg, nil
|
||||
|
||||
}
|
||||
|
||||
log.Debugf("No migration needed for %s#%s -> %s#%s", input.GetAPIVersion(), input.GetKind(), ApiVersion, input.GetKind())
|
||||
|
||||
return input, nil
|
||||
|
||||
}
|
254
pkg/config/v1alpha3/schema.json
Normal file
254
pkg/config/v1alpha3/schema.json
Normal file
@ -0,0 +1,254 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "SimpleConfig",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"apiVersion",
|
||||
"kind"
|
||||
],
|
||||
"properties": {
|
||||
"apiVersion": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"k3d.io/v1alpha3"
|
||||
],
|
||||
"default": "k3d.io/v1alpha3"
|
||||
},
|
||||
"kind": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"Simple"
|
||||
],
|
||||
"default": "Simple"
|
||||
},
|
||||
"name": {
|
||||
"description": "Name of the cluster (must be a valid hostname and will be prefixed with 'k3d-'). Example: 'mycluster'.",
|
||||
"type": "string",
|
||||
"format": "hostname"
|
||||
},
|
||||
"servers": {
|
||||
"type": "number",
|
||||
"minimum": 1
|
||||
},
|
||||
"agents": {
|
||||
"type": "number",
|
||||
"minimum": 0
|
||||
},
|
||||
"kubeAPI": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"host": {
|
||||
"type": "string",
|
||||
"format": "hostname"
|
||||
},
|
||||
"hostIP": {
|
||||
"type": "string",
|
||||
"format": "ipv4",
|
||||
"examples": [
|
||||
"0.0.0.0",
|
||||
"192.168.178.55"
|
||||
]
|
||||
},
|
||||
"hostPort": {
|
||||
"type":"string",
|
||||
"examples": [
|
||||
"6443"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"image": {
|
||||
"type": "string",
|
||||
"examples": [
|
||||
"rancher/k3s:latest"
|
||||
]
|
||||
},
|
||||
"network": {
|
||||
"type": "string"
|
||||
},
|
||||
"subnet": {
|
||||
"type": "string",
|
||||
"default": "auto",
|
||||
"examples": [
|
||||
"172.28.0.0/16",
|
||||
"192.162.0.0/16"
|
||||
]
|
||||
},
|
||||
"token": {
|
||||
"type": "string"
|
||||
},
|
||||
"volumes": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"volume": {
|
||||
"type": "string"
|
||||
},
|
||||
"nodeFilters": {
|
||||
"$ref": "#/definitions/nodeFilters"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"ports": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"port": {
|
||||
"type": "string"
|
||||
},
|
||||
"nodeFilters": {
|
||||
"$ref": "#/definitions/nodeFilters"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"labels": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"nodeFilters": {
|
||||
"$ref": "#/definitions/nodeFilters"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"k3d": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"wait": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"timeout": {
|
||||
"type": "string",
|
||||
"examples": [
|
||||
"60s",
|
||||
"1m",
|
||||
"1m30s"
|
||||
]
|
||||
},
|
||||
"disableLoadbalancer": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"disableImageVolume": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"disableRollback": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"disableHostIPInjection": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"k3s": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"extraArgs": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"arg": {
|
||||
"type": "string",
|
||||
"examples": [
|
||||
"--tls-san=127.0.0.1",
|
||||
"--disable=traefik"
|
||||
]
|
||||
},
|
||||
"nodeFilters": {
|
||||
"$ref": "#/definitions/nodeFilters"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"kubeconfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"updateDefaultKubeconfig": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"switchCurrentContext": {
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"runtime": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"gpuRequest": {
|
||||
"type": "string"
|
||||
},
|
||||
"serversMemory": {
|
||||
"type": "string"
|
||||
},
|
||||
"agentsMemory": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"env": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"envVar": {
|
||||
"type": "string"
|
||||
},
|
||||
"nodeFilters": {
|
||||
"$ref": "#/definitions/nodeFilters"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"registries": {
|
||||
"type": "object"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"definitions": {
|
||||
"nodeFilters": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"examples": [
|
||||
"loadbalancer",
|
||||
"server[*]",
|
||||
"server[0]",
|
||||
"agent[1]",
|
||||
"all"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
203
pkg/config/v1alpha3/types.go
Normal file
203
pkg/config/v1alpha3/types.go
Normal file
@ -0,0 +1,203 @@
|
||||
/*
|
||||
Copyright © 2020 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 v1alpha3
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
config "github.com/rancher/k3d/v4/pkg/config/types"
|
||||
k3d "github.com/rancher/k3d/v4/pkg/types"
|
||||
"github.com/rancher/k3d/v4/version"
|
||||
)
|
||||
|
||||
const ApiVersion = "k3d.io/v1alpha3"
|
||||
|
||||
// JSONSchema describes the schema used to validate config files
|
||||
//go:embed schema.json
|
||||
var JSONSchema string
|
||||
|
||||
// DefaultConfigTpl for printing
|
||||
const DefaultConfigTpl = `---
|
||||
apiVersion: k3d.io/v1alpha3
|
||||
kind: Simple
|
||||
name: %s
|
||||
servers: 1
|
||||
agents: 0
|
||||
image: %s
|
||||
`
|
||||
|
||||
// DefaultConfig templated DefaultConfigTpl
|
||||
var DefaultConfig = fmt.Sprintf(
|
||||
DefaultConfigTpl,
|
||||
k3d.DefaultClusterName,
|
||||
fmt.Sprintf("%s:%s", k3d.DefaultK3sImageRepo, version.GetK3sVersion(false)),
|
||||
)
|
||||
|
||||
type VolumeWithNodeFilters struct {
|
||||
Volume string `mapstructure:"volume" yaml:"volume" json:"volume,omitempty"`
|
||||
NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters" json:"nodeFilters,omitempty"`
|
||||
}
|
||||
|
||||
type PortWithNodeFilters struct {
|
||||
Port string `mapstructure:"port" yaml:"port" json:"port,omitempty"`
|
||||
NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters" json:"nodeFilters,omitempty"`
|
||||
}
|
||||
|
||||
type LabelWithNodeFilters struct {
|
||||
Label string `mapstructure:"label" yaml:"label" json:"label,omitempty"`
|
||||
NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters" json:"nodeFilters,omitempty"`
|
||||
}
|
||||
|
||||
type EnvVarWithNodeFilters struct {
|
||||
EnvVar string `mapstructure:"envVar" yaml:"envVar" json:"envVar,omitempty"`
|
||||
NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters" json:"nodeFilters,omitempty"`
|
||||
}
|
||||
|
||||
type K3sArgWithNodeFilters struct {
|
||||
Arg string `mapstructure:"arg" yaml:"arg" json:"arg,omitempty"`
|
||||
NodeFilters []string `mapstructure:"nodeFilters" yaml:"nodeFilters" json:"nodeFilters,omitempty"`
|
||||
}
|
||||
|
||||
// SimpleConfigOptionsKubeconfig describes the set of options referring to the kubeconfig during cluster creation.
|
||||
type SimpleConfigOptionsKubeconfig struct {
|
||||
UpdateDefaultKubeconfig bool `mapstructure:"updateDefaultKubeconfig" yaml:"updateDefaultKubeconfig" json:"updateDefaultKubeconfig,omitempty"` // default: true
|
||||
SwitchCurrentContext bool `mapstructure:"switchCurrentContext" yaml:"switchCurrentContext" json:"switchCurrentContext,omitempty"` //nolint:lll // default: true
|
||||
}
|
||||
|
||||
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"`
|
||||
}
|
||||
|
||||
type SimpleConfigOptionsRuntime struct {
|
||||
GPURequest string `mapstructure:"gpuRequest" yaml:"gpuRequest"`
|
||||
ServersMemory string `mapstructure:"serversMemory" yaml:"serversMemory"`
|
||||
AgentsMemory string `mapstructure:"agentsMemory" yaml:"agentsMemory"`
|
||||
}
|
||||
|
||||
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"`
|
||||
}
|
||||
|
||||
type SimpleConfigOptionsK3s struct {
|
||||
ExtraArgs []K3sArgWithNodeFilters `mapstructure:"extraArgs" yaml:"extraArgs"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
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"`
|
||||
Registries struct {
|
||||
Use []string `mapstructure:"use" yaml:"use,omitempty" json:"use,omitempty"`
|
||||
Create bool `mapstructure:"create" yaml:"create,omitempty" json:"create,omitempty"`
|
||||
Config string `mapstructure:"config" yaml:"config,omitempty" json:"config,omitempty"` // registries.yaml (k3s config for containerd registry override)
|
||||
} `mapstructure:"registries" yaml:"registries,omitempty" json:"registries,omitempty"`
|
||||
}
|
||||
|
||||
// SimpleExposureOpts provides a simplified syntax compared to the original k3d.ExposureOpts
|
||||
type SimpleExposureOpts struct {
|
||||
Host string `mapstructure:"host" yaml:"host,omitempty" json:"host,omitempty"`
|
||||
HostIP string `mapstructure:"hostIP" yaml:"hostIP,omitempty" json:"hostIP,omitempty"`
|
||||
HostPort string `mapstructure:"hostPort" yaml:"hostPort,omitempty" json:"hostPort,omitempty"`
|
||||
}
|
||||
|
||||
// GetKind implements Config.GetKind
|
||||
func (c SimpleConfig) GetKind() string {
|
||||
return "Simple"
|
||||
}
|
||||
|
||||
func (c SimpleConfig) GetAPIVersion() string {
|
||||
return ApiVersion
|
||||
}
|
||||
|
||||
// ClusterConfig describes a single cluster config
|
||||
type ClusterConfig struct {
|
||||
config.TypeMeta `mapstructure:",squash" yaml:",inline"`
|
||||
Cluster k3d.Cluster `mapstructure:",squash" yaml:",inline"`
|
||||
ClusterCreateOpts k3d.ClusterCreateOpts `mapstructure:"options" yaml:"options"`
|
||||
KubeconfigOpts SimpleConfigOptionsKubeconfig `mapstructure:"kubeconfig" yaml:"kubeconfig"`
|
||||
}
|
||||
|
||||
// GetKind implements Config.GetKind
|
||||
func (c ClusterConfig) GetKind() string {
|
||||
return "Simple"
|
||||
}
|
||||
|
||||
func (c ClusterConfig) GetAPIVersion() string {
|
||||
return ApiVersion
|
||||
}
|
||||
|
||||
// ClusterListConfig describes a list of clusters
|
||||
type ClusterListConfig struct {
|
||||
config.TypeMeta `mapstructure:",squash" yaml:",inline"`
|
||||
Clusters []k3d.Cluster `mapstructure:"clusters" yaml:"clusters"`
|
||||
}
|
||||
|
||||
func (c ClusterListConfig) GetKind() string {
|
||||
return "Simple"
|
||||
}
|
||||
|
||||
func (c ClusterListConfig) GetAPIVersion() string {
|
||||
return ApiVersion
|
||||
}
|
||||
|
||||
func GetConfigByKind(kind string) (config.Config, error) {
|
||||
|
||||
// determine config kind
|
||||
switch strings.ToLower(kind) {
|
||||
case "simple":
|
||||
return SimpleConfig{}, nil
|
||||
case "cluster":
|
||||
return ClusterConfig{}, nil
|
||||
case "clusterlist":
|
||||
return ClusterListConfig{}, nil
|
||||
case "":
|
||||
return nil, fmt.Errorf("missing `kind` in config file")
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown `kind` '%s' in config file", kind)
|
||||
}
|
||||
|
||||
}
|
@ -27,7 +27,7 @@ import (
|
||||
"time"
|
||||
|
||||
k3dc "github.com/rancher/k3d/v4/pkg/client"
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha2"
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha3"
|
||||
"github.com/rancher/k3d/v4/pkg/runtimes"
|
||||
runtimeutil "github.com/rancher/k3d/v4/pkg/runtimes/util"
|
||||
k3d "github.com/rancher/k3d/v4/pkg/types"
|
||||
|
@ -26,7 +26,7 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha2"
|
||||
conf "github.com/rancher/k3d/v4/pkg/config/v1alpha3"
|
||||
"github.com/rancher/k3d/v4/pkg/runtimes"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
@ -184,8 +184,6 @@ type ClusterCreateOpts struct {
|
||||
WaitForServer bool `yaml:"waitForServer" json:"waitForServer,omitempty"`
|
||||
Timeout time.Duration `yaml:"timeout" json:"timeout,omitempty"`
|
||||
DisableLoadBalancer bool `yaml:"disableLoadbalancer" json:"disableLoadbalancer,omitempty"`
|
||||
K3sServerArgs []string `yaml:"k3sServerArgs" json:"k3sServerArgs,omitempty"`
|
||||
K3sAgentArgs []string `yaml:"k3sAgentArgs" json:"k3sAgentArgs,omitempty"`
|
||||
GPURequest string `yaml:"gpuRequest" json:"gpuRequest,omitempty"`
|
||||
ServersMemory string `yaml:"serversMemory" json:"serversMemory,omitempty"`
|
||||
AgentsMemory string `yaml:"agentsMemory" json:"agentsMemory,omitempty"`
|
||||
|
@ -1,4 +1,4 @@
|
||||
apiVersion: k3d.io/v1alpha2
|
||||
apiVersion: k3d.io/v1alpha3
|
||||
kind: Simple
|
||||
name: test
|
||||
servers: 3
|
||||
@ -43,9 +43,10 @@ options:
|
||||
disableLoadbalancer: false
|
||||
disableImageVolume: false
|
||||
k3s:
|
||||
extraServerArgs:
|
||||
- --tls-san=127.0.0.1
|
||||
extraAgentArgs: []
|
||||
extraArgs:
|
||||
- arg: --tls-san=127.0.0.1
|
||||
nodeFilters:
|
||||
- server[*]
|
||||
kubeconfig:
|
||||
updateDefaultKubeconfig: true
|
||||
switchCurrentContext: true
|
51
tests/assets/config_test_simple_migration_v1alpha2.yaml
Executable file
51
tests/assets/config_test_simple_migration_v1alpha2.yaml
Executable file
@ -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
|
52
tests/assets/config_test_simple_migration_v1alpha3.yaml
Executable file
52
tests/assets/config_test_simple_migration_v1alpha3.yaml
Executable file
@ -0,0 +1,52 @@
|
||||
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
|
||||
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:
|
||||
extraArgs:
|
||||
- arg: --tls-san=127.0.0.1
|
||||
nodeFilters:
|
||||
- server[*]
|
||||
kubeconfig:
|
||||
updateDefaultKubeconfig: true
|
||||
switchCurrentContext: true
|
27
tests/test_config_file_migration.sh
Executable file
27
tests/test_config_file_migration.sh
Executable file
@ -0,0 +1,27 @@
|
||||
#!/bin/bash
|
||||
|
||||
CURR_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
|
||||
[ -d "$CURR_DIR" ] || { echo "FATAL: no current dir (maybe running in zsh?)"; exit 1; }
|
||||
|
||||
# shellcheck source=./common.sh
|
||||
source "$CURR_DIR/common.sh"
|
||||
|
||||
|
||||
export CURRENT_STAGE="Test | config-file-migration"
|
||||
|
||||
|
||||
|
||||
highlight "[START] ConfigMigrateTest"
|
||||
|
||||
tempdir=$(mktemp -d)
|
||||
$EXE config migrate "$CURR_DIR/assets/config_test_simple_migration_v1alpha2.yaml" "$tempdir/expected.yaml" || failed "failed on $CURR_DIR/assets/config_test_simple.yaml"
|
||||
$EXE config migrate "$CURR_DIR/assets/config_test_simple_migration_v1alpha3.yaml" "$tempdir/actual.yaml" || failed "failed on $CURR_DIR/assets/config_test_simple_migrate.yaml"
|
||||
|
||||
diff "$tempdir/actual.yaml" "$tempdir/expected.yaml" || failed "config migration failed" && passed "config migration succeeded"
|
||||
|
||||
|
||||
highlight "[DONE] ConfigMigrateTest"
|
||||
|
||||
exit 0
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user