Skip to content

Commit

Permalink
Merge pull request #1389 from trawler/config_refactoring
Browse files Browse the repository at this point in the history
Remove config flag as a global Flag + setting config default location to /etc/k0s/k0s.yaml
  • Loading branch information
trawler authored Dec 28, 2021
2 parents f9b2836 + 5e2aa11 commit 6a651c0
Show file tree
Hide file tree
Showing 23 changed files with 146 additions and 117 deletions.
1 change: 1 addition & 0 deletions cmd/airgap/airgap.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ func NewAirgapCmd() *cobra.Command {

cmd.SilenceUsage = true
cmd.AddCommand(NewAirgapListImagesCmd())
cmd.PersistentFlags().AddFlagSet(config.FileInputFlag())
cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet())
return cmd
}
1 change: 1 addition & 0 deletions cmd/airgap/listimages.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ func NewAirgapListImagesCmd() *cobra.Command {
return nil
},
}
cmd.Flags().AddFlagSet(config.FileInputFlag())
cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet())
return cmd
}
1 change: 1 addition & 0 deletions cmd/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ func NewAPICmd() *cobra.Command {
},
}
cmd.SilenceUsage = true
cmd.Flags().AddFlagSet(config.FileInputFlag())
cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet())
return cmd
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/backup/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func NewBackupCmd() *cobra.Command {
}
cmd.Flags().StringVar(&savePath, "save-path", "", "destination directory path for backup assets")
cmd.SilenceUsage = true
cmd.Flags().AddFlagSet(config.FileInputFlag())
cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet())
return cmd
}
Expand Down Expand Up @@ -89,7 +90,7 @@ func (c *CmdOpts) backup() error {

func preRunValidateConfig(cmd *cobra.Command, args []string) error {
c := CmdOpts(config.GetCmdOpts())
_, err := config.ValidateYaml(c.CfgFile, c.K0sVars)
_, err := config.GetConfigFromYAML(c.CfgFile, c.K0sVars)
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions cmd/config/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,6 @@ func NewValidateCmd() *cobra.Command {
}

cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet())
cmd.Flags().AddFlagSet(config.FileInputFlag())
return cmd
}
1 change: 1 addition & 0 deletions cmd/etcd/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func NewEtcdCmd() *cobra.Command {
cmd.SilenceUsage = true
cmd.AddCommand(etcdLeaveCmd())
cmd.AddCommand(etcdListCmd())
cmd.Flags().AddFlagSet(config.FileInputFlag())
cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet())
return cmd
}
1 change: 1 addition & 0 deletions cmd/etcd/leave.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,5 +75,6 @@ func etcdLeaveCmd() *cobra.Command {

cmd.Flags().StringVar(&etcdPeerAddress, "peer-address", "", "etcd peer address")
cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet())
cmd.Flags().AddFlagSet(config.FileInputFlag())
return cmd
}
1 change: 1 addition & 0 deletions cmd/etcd/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func etcdListCmd() *cobra.Command {
return json.NewEncoder(os.Stdout).Encode(map[string]interface{}{"members": members})
},
}
cmd.Flags().AddFlagSet(config.FileInputFlag())
cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet())
return cmd
}
7 changes: 1 addition & 6 deletions cmd/install/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import (

"github.com/spf13/cobra"

"github.com/k0sproject/k0s/internal/pkg/dir"
"github.com/k0sproject/k0s/internal/pkg/file"
"github.com/k0sproject/k0s/pkg/config"
"github.com/k0sproject/k0s/pkg/install"
Expand Down Expand Up @@ -50,10 +49,6 @@ func (c *CmdOpts) setup(role string, args []string) error {
return fmt.Errorf("this command must be run as root")
}

// if cfgFile is not provided k0s will handle this so no need to check if the file exists.
if c.CfgFile != "" && !dir.IsDirectory(c.CfgFile) && !file.Exists(c.CfgFile) {
return fmt.Errorf("file %s does not exist", c.CfgFile)
}
if role == "controller" {
cfg, err := config.GetNodeConfig(c.CfgFile, c.K0sVars)
if err != nil {
Expand Down Expand Up @@ -102,7 +97,7 @@ func (c *CmdOpts) convertFileParamsToAbsolute() (err error) {

func preRunValidateConfig(_ *cobra.Command, _ []string) error {
c := CmdOpts(config.GetCmdOpts())
_, err := config.ValidateYaml(c.CfgFile, c.K0sVars)
_, err := config.GetConfigFromYAML(c.CfgFile, c.K0sVars)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/kubeconfig/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,14 @@ Note: A certificate once signed cannot be revoked for a particular user`,
},
}
cmd.Flags().StringVar(&groups, "groups", "", "Specify groups")
cmd.Flags().AddFlagSet(config.FileInputFlag())
cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet())
return cmd
}

func (c *CmdOpts) getAPIURL() (string, error) {
// Disable logrus
logrus.SetLevel(logrus.WarnLevel)

cfg, err := config.GetNodeConfig(c.CfgFile, c.K0sVars)
if err != nil {
return "", err
Expand Down
3 changes: 2 additions & 1 deletion cmd/reset/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ func NewResetCmd() *cobra.Command {
cmd.SilenceUsage = true
cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet())
cmd.Flags().AddFlagSet(config.GetCriSocketFlag())
cmd.Flags().AddFlagSet(config.FileInputFlag())
return cmd
}

Expand Down Expand Up @@ -74,7 +75,7 @@ func (c *CmdOpts) reset() error {

func preRunValidateConfig(_ *cobra.Command, _ []string) error {
c := CmdOpts(config.GetCmdOpts())
_, err := config.ValidateYaml(c.CfgFile, c.K0sVars)
_, err := config.GetConfigFromYAML(c.CfgFile, c.K0sVars)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/restore/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func NewRestoreCmd() *cobra.Command {

cmd.SilenceUsage = true
cmd.Flags().StringVar(&restoredConfigPath, "config-out", "", "Specify desired name and full path for the restored k0s.yaml file (default: ${cwd}/k0s_<archive timestamp>.yaml)")
cmd.Flags().AddFlagSet(config.FileInputFlag())
cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet())
return cmd
}
Expand Down Expand Up @@ -95,7 +96,7 @@ func (c *CmdOpts) restore(path string) error {
// TODO Need to move to some common place, now it's defined in restore and backup commands
func preRunValidateConfig(_ *cobra.Command, _ []string) error {
c := CmdOpts(config.GetCmdOpts())
_, err := config.ValidateYaml(c.CfgFile, c.K0sVars)
_, err := config.GetConfigFromYAML(c.CfgFile, c.K0sVars)
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/token/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ k0s token create --role worker --expiry 10m //sets expiration time to 10 minute
}
// append flags
cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet())

cmd.Flags().AddFlagSet(config.FileInputFlag())
cmd.Flags().StringVar(&tokenExpiry, "expiry", "0s", "Expiration time of the token. Format 1.5h, 2h45m or 300ms.")
cmd.Flags().StringVar(&createTokenRole, "role", "worker", "Either worker or controller")
cmd.Flags().BoolVar(&waitCreate, "wait", false, "wait forever (default false)")
Expand Down
1 change: 0 additions & 1 deletion cmd/token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,5 @@ func NewTokenCmd() *cobra.Command {
cmd.AddCommand(tokenCreateCmd())
cmd.AddCommand(tokenListCmd())
cmd.AddCommand(tokenInvalidateCmd())
cmd.PersistentFlags().AddFlagSet(config.GetPersistentFlagSet())
return cmd
}
3 changes: 0 additions & 3 deletions cmd/validate/validate.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
/*
Copyright 2021 k0s authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Expand Down
1 change: 1 addition & 0 deletions inttest/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ check-ctr: TIMEOUT=10m
check-byocri: TIMEOUT=5m
# readiness check for metric tests takes between around 5 and 6 minutes.
check-metrics: TIMEOUT=6m
check-calico: TIMEOUT=6m

# Establishing konnectivity tunnels with the LB in place takes a while, thus a bit longer timeout for the smoke
check-customports: TIMEOUT=6m
Expand Down
2 changes: 1 addition & 1 deletion inttest/customports/customports_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ func (ds *Suite) TestControllerJoinsWithCustomPort() {

workerToken, err := ds.GetJoinToken("worker", "", "--config=/tmp/k0s.yaml")
ds.Require().NoError(err)
ds.Require().NoError(ds.RunWorkersWithToken("/var/lib/k0s", workerToken, `--config="/tmp/k0s.yaml"`))
ds.Require().NoError(ds.RunWorkersWithToken("/var/lib/k0s", workerToken))

kc, err := ds.KubeClient("controller0", "")
ds.Require().NoError(err)
Expand Down
79 changes: 59 additions & 20 deletions pkg/apis/k0s.k0sproject.io/v1beta1/clusterconfig_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ package v1beta1
import (
"bytes"
"encoding/json"
"fmt"
"io"
"os"
"reflect"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -162,24 +160,6 @@ func (s *SchedulerSpec) IsZero() bool {
return len(s.ExtraArgs) == 0
}

// ConfigFromFile takes a file path as Input, and parses it into a ClusterConfig
func ConfigFromFile(filename string, defaultStorage ...*StorageSpec) (*ClusterConfig, error) {
buf, err := os.ReadFile(filename)
if err != nil {
return nil, fmt.Errorf("failed to read config file at %s: %w", filename, err)
}
return ConfigFromString(string(buf), defaultStorage...)
}

// ConfigFromStdin tries to read k0s.yaml config from stdin
func ConfigFromStdin(defaultStorage ...*StorageSpec) (*ClusterConfig, error) {
input, err := io.ReadAll(os.Stdin)
if err != nil {
return nil, fmt.Errorf("can't read configration from stdin: %v", err)
}
return ConfigFromString(string(input), defaultStorage...)
}

func ConfigFromString(yml string, defaultStorage ...*StorageSpec) (*ClusterConfig, error) {
config := DefaultClusterConfig(defaultStorage...)
err := strictyaml.YamlUnmarshalStrictIgnoringFields([]byte(yml), config, "interval")
Expand All @@ -192,6 +172,15 @@ func ConfigFromString(yml string, defaultStorage ...*StorageSpec) (*ClusterConfi
return config, nil
}

// ConfigFromReader reads the configuration from any reader (can be stdin, file reader, etc)
func ConfigFromReader(r io.Reader, defaultStorage ...*StorageSpec) (*ClusterConfig, error) {
input, err := io.ReadAll(r)
if err != nil {
return nil, err
}
return ConfigFromString(string(input), defaultStorage...)
}

// DefaultClusterConfig sets the default ClusterConfig values, when none are given
func DefaultClusterConfig(defaultStorage ...*StorageSpec) *ClusterConfig {
return &ClusterConfig{
Expand Down Expand Up @@ -289,6 +278,56 @@ func (c *ClusterConfig) Validate() []error {
return errors
}

// GetBootstrappingConfig returns a ClusterConfig object stripped of Cluster-Wide Settings
func (c *ClusterConfig) GetBootstrappingConfig(storageSpec *StorageSpec) *ClusterConfig {
return &ClusterConfig{
ObjectMeta: c.ObjectMeta,
TypeMeta: c.TypeMeta,
Spec: &ClusterSpec{
API: c.Spec.API,
Storage: storageSpec,
Network: &Network{
ServiceCIDR: c.Spec.Network.ServiceCIDR,
DualStack: c.Spec.Network.DualStack,
},
Install: c.Spec.Install,
},
Status: c.Status,
}
}

// HACK: the current ClusterConfig struct holds both bootstrapping config & cluster-wide config
// this hack strips away the node-specific bootstrapping config so that we write a "clean" config to the CR
// This function accepts a standard ClusterConfig and returns the same config minus the node specific info:
// - APISpec
// - StorageSpec
// - Network.ServiceCIDR
// - Install
func (c *ClusterConfig) GetClusterWideConfig() *ClusterConfig {
return &ClusterConfig{
ObjectMeta: c.ObjectMeta,
TypeMeta: c.TypeMeta,
Spec: &ClusterSpec{
ControllerManager: c.Spec.ControllerManager,
Scheduler: c.Spec.Scheduler,
Network: &Network{
Calico: c.Spec.Network.Calico,
KubeProxy: c.Spec.Network.KubeProxy,
KubeRouter: c.Spec.Network.KubeRouter,
PodCIDR: c.Spec.Network.PodCIDR,
Provider: c.Spec.Network.Provider,
},
PodSecurityPolicy: c.Spec.PodSecurityPolicy,
WorkerProfiles: c.Spec.WorkerProfiles,
Telemetry: c.Spec.Telemetry,
Images: c.Spec.Images,
Extensions: c.Spec.Extensions,
Konnectivity: c.Spec.Konnectivity,
},
Status: c.Status,
}
}

// CRValidator is used to make sure a config CR is created with correct values
func (c *ClusterConfig) CRValidator() *ClusterConfig {
copy := c.DeepCopy()
Expand Down
2 changes: 1 addition & 1 deletion pkg/component/controller/clusterConfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ func (r *ClusterConfigReconciler) reportStatus(config *v1beta1.ClusterConfig, re
func (r *ClusterConfigReconciler) copyRunningConfigToCR(baseCtx context.Context) (*v1beta1.ClusterConfig, error) {
ctx, cancel := context.WithTimeout(baseCtx, 5*time.Second)
defer cancel()
clusterWideConfig := config.ClusterConfigMinusNodeConfig(r.YamlConfig).StripDefaults().CRValidator()
clusterWideConfig := r.YamlConfig.GetClusterWideConfig().StripDefaults().CRValidator()
clusterConfig, err := r.configClient.Create(ctx, clusterWideConfig, cOpts)
if err != nil {
return nil, err
Expand Down
11 changes: 10 additions & 1 deletion pkg/config/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ func DefaultLogLevels() map[string]string {

func GetPersistentFlagSet() *pflag.FlagSet {
flagset := &pflag.FlagSet{}
flagset.StringVarP(&CfgFile, "config", "c", "", "config file, use '-' to read the config from stdin")
flagset.BoolVarP(&Debug, "debug", "d", false, "Debug logging (default: false)")
flagset.BoolVarP(&Verbose, "verbose", "v", false, "Verbose logging (default: false)")
flagset.StringVar(&DataDir, "data-dir", "", "Data Directory for k0s (default: /var/lib/k0s). DO NOT CHANGE for an existing setup, things will break!")
Expand Down Expand Up @@ -179,6 +178,16 @@ func GetControllerFlags() *pflag.FlagSet {
flagset.IntVar(&controllerOpts.K0sCloudProviderPort, "k0s-cloud-provider-port", cloudprovider.CloudControllerManagerPort, "the port that k0s-cloud-provider binds on")
flagset.AddFlagSet(GetCriSocketFlag())
flagset.BoolVar(&controllerOpts.EnableDynamicConfig, "enable-dynamic-config", false, "enable cluster-wide dynamic config based on custom resource")
flagset.AddFlagSet(FileInputFlag())
return flagset
}

// The config flag used to be a persistent, joint flag to all commands
// now only a few commands use it. This function helps to share the flag with multiple commands without needing to define
// it in multiple places
func FileInputFlag() *pflag.FlagSet {
flagset := &pflag.FlagSet{}
flagset.StringVarP(&CfgFile, "config", "c", constant.K0sConfigPathDefault, "config file, use '-' to read the config from stdin")

return flagset
}
Expand Down
Loading

0 comments on commit 6a651c0

Please sign in to comment.