mirror of https://github.com/k3s-io/k3s
[Engine-1.21] Parser improvements, allow config values to be used with etcd-snapshot (#4477)
* Match to last After keyword for parser (#4383) * Made parser able to skip over subcommands * Fix to allow etcd-snapshot to use config file with flags that are only used with k3s server. (#4464) Signed-off-by: Derek Nola <derek.nola@suse.com>pull/4494/head
parent
381d086cf0
commit
d5a4147762
|
@ -146,6 +146,365 @@ var (
|
|||
}
|
||||
)
|
||||
|
||||
var ServerFlags = []cli.Flag{
|
||||
ConfigFlag,
|
||||
DebugFlag,
|
||||
VLevel,
|
||||
VModule,
|
||||
LogFile,
|
||||
AlsoLogToStderr,
|
||||
cli.StringFlag{
|
||||
Name: "bind-address",
|
||||
Usage: "(listener) " + version.Program + " bind address (default: 0.0.0.0)",
|
||||
Destination: &ServerConfig.BindAddress,
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "https-listen-port",
|
||||
Usage: "(listener) HTTPS listen port",
|
||||
Value: 6443,
|
||||
Destination: &ServerConfig.HTTPSPort,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "advertise-address",
|
||||
Usage: "(listener) IPv4 address that apiserver uses to advertise to members of the cluster (default: node-external-ip/node-ip)",
|
||||
Destination: &ServerConfig.AdvertiseIP,
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "advertise-port",
|
||||
Usage: "(listener) Port that apiserver uses to advertise to members of the cluster (default: listen-port)",
|
||||
Destination: &ServerConfig.AdvertisePort,
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "tls-san",
|
||||
Usage: "(listener) Add additional hostnames or IPv4/IPv6 addresses as Subject Alternative Names on the server TLS cert",
|
||||
Value: &ServerConfig.TLSSan,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "data-dir,d",
|
||||
Usage: "(data) Folder to hold state default /var/lib/rancher/" + version.Program + " or ${HOME}/.rancher/" + version.Program + " if not root",
|
||||
Destination: &ServerConfig.DataDir,
|
||||
},
|
||||
ClusterCIDR,
|
||||
ServiceCIDR,
|
||||
ServiceNodePortRange,
|
||||
ClusterDNS,
|
||||
ClusterDomain,
|
||||
cli.StringFlag{
|
||||
Name: "flannel-backend",
|
||||
Usage: "(networking) One of 'none', 'vxlan', 'ipsec', 'host-gw', or 'wireguard'",
|
||||
Destination: &ServerConfig.FlannelBackend,
|
||||
Value: "vxlan",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "token,t",
|
||||
Usage: "(cluster) Shared secret used to join a server or agent to a cluster",
|
||||
Destination: &ServerConfig.Token,
|
||||
EnvVar: version.ProgramUpper + "_TOKEN",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "token-file",
|
||||
Usage: "(cluster) File containing the cluster-secret/token",
|
||||
Destination: &ServerConfig.TokenFile,
|
||||
EnvVar: version.ProgramUpper + "_TOKEN_FILE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "write-kubeconfig,o",
|
||||
Usage: "(client) Write kubeconfig for admin client to this file",
|
||||
Destination: &ServerConfig.KubeConfigOutput,
|
||||
EnvVar: version.ProgramUpper + "_KUBECONFIG_OUTPUT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "write-kubeconfig-mode",
|
||||
Usage: "(client) Write kubeconfig with this mode",
|
||||
Destination: &ServerConfig.KubeConfigMode,
|
||||
EnvVar: version.ProgramUpper + "_KUBECONFIG_MODE",
|
||||
},
|
||||
ExtraAPIArgs,
|
||||
ExtraEtcdArgs,
|
||||
ExtraControllerArgs,
|
||||
ExtraSchedulerArgs,
|
||||
cli.StringSliceFlag{
|
||||
Name: "kube-cloud-controller-manager-arg",
|
||||
Usage: "(flags) Customized flag for kube-cloud-controller-manager process",
|
||||
Value: &ServerConfig.ExtraCloudControllerArgs,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "datastore-endpoint",
|
||||
Usage: "(db) Specify etcd, Mysql, Postgres, or Sqlite (default) data source name",
|
||||
Destination: &ServerConfig.DatastoreEndpoint,
|
||||
EnvVar: version.ProgramUpper + "_DATASTORE_ENDPOINT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "datastore-cafile",
|
||||
Usage: "(db) TLS Certificate Authority file used to secure datastore backend communication",
|
||||
Destination: &ServerConfig.DatastoreCAFile,
|
||||
EnvVar: version.ProgramUpper + "_DATASTORE_CAFILE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "datastore-certfile",
|
||||
Usage: "(db) TLS certification file used to secure datastore backend communication",
|
||||
Destination: &ServerConfig.DatastoreCertFile,
|
||||
EnvVar: version.ProgramUpper + "_DATASTORE_CERTFILE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "datastore-keyfile",
|
||||
Usage: "(db) TLS key file used to secure datastore backend communication",
|
||||
Destination: &ServerConfig.DatastoreKeyFile,
|
||||
EnvVar: version.ProgramUpper + "_DATASTORE_KEYFILE",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "etcd-expose-metrics",
|
||||
Usage: "(db) Expose etcd metrics to client interface. (Default false)",
|
||||
Destination: &ServerConfig.EtcdExposeMetrics,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "etcd-disable-snapshots",
|
||||
Usage: "(db) Disable automatic etcd snapshots",
|
||||
Destination: &ServerConfig.EtcdDisableSnapshots,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-snapshot-name",
|
||||
Usage: "(db) Set the base name of etcd snapshots. Default: etcd-snapshot-<unix-timestamp>",
|
||||
Destination: &ServerConfig.EtcdSnapshotName,
|
||||
Value: "etcd-snapshot",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-snapshot-schedule-cron",
|
||||
Usage: "(db) Snapshot interval time in cron spec. eg. every 5 hours '* */5 * * *'",
|
||||
Destination: &ServerConfig.EtcdSnapshotCron,
|
||||
Value: "0 */12 * * *",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "etcd-snapshot-retention",
|
||||
Usage: "(db) Number of snapshots to retain",
|
||||
Destination: &ServerConfig.EtcdSnapshotRetention,
|
||||
Value: defaultSnapshotRentention,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-snapshot-dir",
|
||||
Usage: "(db) Directory to save db snapshots. (Default location: ${data-dir}/db/snapshots)",
|
||||
Destination: &ServerConfig.EtcdSnapshotDir,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "etcd-s3",
|
||||
Usage: "(db) Enable backup to S3",
|
||||
Destination: &ServerConfig.EtcdS3,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-s3-endpoint",
|
||||
Usage: "(db) S3 endpoint url",
|
||||
Destination: &ServerConfig.EtcdS3Endpoint,
|
||||
Value: "s3.amazonaws.com",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-s3-endpoint-ca",
|
||||
Usage: "(db) S3 custom CA cert to connect to S3 endpoint",
|
||||
Destination: &ServerConfig.EtcdS3EndpointCA,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "etcd-s3-skip-ssl-verify",
|
||||
Usage: "(db) Disables S3 SSL certificate validation",
|
||||
Destination: &ServerConfig.EtcdS3SkipSSLVerify,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-s3-access-key",
|
||||
Usage: "(db) S3 access key",
|
||||
EnvVar: "AWS_ACCESS_KEY_ID",
|
||||
Destination: &ServerConfig.EtcdS3AccessKey,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-s3-secret-key",
|
||||
Usage: "(db) S3 secret key",
|
||||
EnvVar: "AWS_SECRET_ACCESS_KEY",
|
||||
Destination: &ServerConfig.EtcdS3SecretKey,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-s3-bucket",
|
||||
Usage: "(db) S3 bucket name",
|
||||
Destination: &ServerConfig.EtcdS3BucketName,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-s3-region",
|
||||
Usage: "(db) S3 region / bucket location (optional)",
|
||||
Destination: &ServerConfig.EtcdS3Region,
|
||||
Value: "us-east-1",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-s3-folder",
|
||||
Usage: "(db) S3 folder",
|
||||
Destination: &ServerConfig.EtcdS3Folder,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "etcd-s3-insecure",
|
||||
Usage: "(db) Disables S3 over HTTPS",
|
||||
Destination: &ServerConfig.EtcdS3Insecure,
|
||||
},
|
||||
&cli.DurationFlag{
|
||||
Name: "etcd-s3-timeout",
|
||||
Usage: "(db) S3 timeout",
|
||||
Destination: &ServerConfig.EtcdS3Timeout,
|
||||
Value: 30 * time.Second,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "default-local-storage-path",
|
||||
Usage: "(storage) Default local storage path for local provisioner storage class",
|
||||
Destination: &ServerConfig.DefaultLocalStoragePath,
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "disable",
|
||||
Usage: "(components) Do not deploy packaged components and delete any deployed components (valid items: " + DisableItems + ")",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-scheduler",
|
||||
Usage: "(components) Disable Kubernetes default scheduler",
|
||||
Destination: &ServerConfig.DisableScheduler,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-cloud-controller",
|
||||
Usage: "(components) Disable " + version.Program + " default cloud controller manager",
|
||||
Destination: &ServerConfig.DisableCCM,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-kube-proxy",
|
||||
Usage: "(components) Disable running kube-proxy",
|
||||
Destination: &ServerConfig.DisableKubeProxy,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-network-policy",
|
||||
Usage: "(components) Disable " + version.Program + " default network policy controller",
|
||||
Destination: &ServerConfig.DisableNPC,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-helm-controller",
|
||||
Usage: "(components) Disable Helm controller",
|
||||
Destination: &ServerConfig.DisableHelmController,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-apiserver",
|
||||
Hidden: true,
|
||||
Usage: "(experimental/components) Disable running api server",
|
||||
Destination: &ServerConfig.DisableAPIServer,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-controller-manager",
|
||||
Hidden: true,
|
||||
Usage: "(experimental/components) Disable running kube-controller-manager",
|
||||
Destination: &ServerConfig.DisableControllerManager,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-etcd",
|
||||
Hidden: true,
|
||||
Usage: "(experimental/components) Disable running etcd",
|
||||
Destination: &ServerConfig.DisableETCD,
|
||||
},
|
||||
NodeNameFlag,
|
||||
WithNodeIDFlag,
|
||||
NodeLabels,
|
||||
NodeTaints,
|
||||
ImageCredProvBinDirFlag,
|
||||
ImageCredProvConfigFlag,
|
||||
DockerFlag,
|
||||
CRIEndpointFlag,
|
||||
PauseImageFlag,
|
||||
SnapshotterFlag,
|
||||
PrivateRegistryFlag,
|
||||
AirgapExtraRegistryFlag,
|
||||
NodeIPFlag,
|
||||
NodeExternalIPFlag,
|
||||
ResolvConfFlag,
|
||||
FlannelIfaceFlag,
|
||||
FlannelConfFlag,
|
||||
ExtraKubeletArgs,
|
||||
ExtraKubeProxyArgs,
|
||||
ProtectKernelDefaultsFlag,
|
||||
cli.BoolFlag{
|
||||
Name: "rootless",
|
||||
Usage: "(experimental) Run rootless",
|
||||
Destination: &ServerConfig.Rootless,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "agent-token",
|
||||
Usage: "(cluster) Shared secret used to join agents to the cluster, but not servers",
|
||||
Destination: &ServerConfig.AgentToken,
|
||||
EnvVar: version.ProgramUpper + "_AGENT_TOKEN",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "agent-token-file",
|
||||
Usage: "(cluster) File containing the agent secret",
|
||||
Destination: &ServerConfig.AgentTokenFile,
|
||||
EnvVar: version.ProgramUpper + "_AGENT_TOKEN_FILE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "server,s",
|
||||
Usage: "(cluster) Server to connect to, used to join a cluster",
|
||||
EnvVar: version.ProgramUpper + "_URL",
|
||||
Destination: &ServerConfig.ServerURL,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "cluster-init",
|
||||
Usage: "(cluster) Initialize a new cluster using embedded Etcd",
|
||||
EnvVar: version.ProgramUpper + "_CLUSTER_INIT",
|
||||
Destination: &ServerConfig.ClusterInit,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "cluster-reset",
|
||||
Usage: "(cluster) Forget all peers and become sole member of a new cluster",
|
||||
EnvVar: version.ProgramUpper + "_CLUSTER_RESET",
|
||||
Destination: &ServerConfig.ClusterReset,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "cluster-reset-restore-path",
|
||||
Usage: "(db) Path to snapshot file to be restored",
|
||||
Destination: &ServerConfig.ClusterResetRestorePath,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "secrets-encryption",
|
||||
Usage: "(experimental) Enable Secret encryption at rest",
|
||||
Destination: &ServerConfig.EncryptSecrets,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "system-default-registry",
|
||||
Usage: "(image) Private registry to be used for all system images",
|
||||
EnvVar: version.ProgramUpper + "_SYSTEM_DEFAULT_REGISTRY",
|
||||
Destination: &ServerConfig.SystemDefaultRegistry,
|
||||
},
|
||||
&SELinuxFlag,
|
||||
LBServerPortFlag,
|
||||
|
||||
// Hidden/Deprecated flags below
|
||||
|
||||
&DisableSELinuxFlag,
|
||||
FlannelFlag,
|
||||
cli.StringSliceFlag{
|
||||
Name: "no-deploy",
|
||||
Usage: "(deprecated) Do not deploy packaged components (valid items: " + DisableItems + ")",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "cluster-secret",
|
||||
Usage: "(deprecated) use --token",
|
||||
Destination: &ServerConfig.ClusterSecret,
|
||||
EnvVar: version.ProgramUpper + "_CLUSTER_SECRET",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-agent",
|
||||
Usage: "Do not run a local agent and register a local kubelet",
|
||||
Hidden: true,
|
||||
Destination: &ServerConfig.DisableAgent,
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Hidden: true,
|
||||
Name: "kube-controller-arg",
|
||||
Usage: "(flags) Customized flag for kube-controller-manager process",
|
||||
Value: &ServerConfig.ExtraControllerArgs,
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Hidden: true,
|
||||
Name: "kube-cloud-controller-arg",
|
||||
Usage: "(flags) Customized flag for kube-cloud-controller-manager process",
|
||||
Value: &ServerConfig.ExtraCloudControllerArgs,
|
||||
},
|
||||
}
|
||||
|
||||
func NewServerCommand(action func(*cli.Context) error) cli.Command {
|
||||
return cli.Command{
|
||||
Name: "server",
|
||||
|
@ -153,363 +512,6 @@ func NewServerCommand(action func(*cli.Context) error) cli.Command {
|
|||
UsageText: appName + " server [OPTIONS]",
|
||||
Before: SetupDebug(CheckSELinuxFlags),
|
||||
Action: action,
|
||||
Flags: []cli.Flag{
|
||||
ConfigFlag,
|
||||
DebugFlag,
|
||||
VLevel,
|
||||
VModule,
|
||||
LogFile,
|
||||
AlsoLogToStderr,
|
||||
cli.StringFlag{
|
||||
Name: "bind-address",
|
||||
Usage: "(listener) " + version.Program + " bind address (default: 0.0.0.0)",
|
||||
Destination: &ServerConfig.BindAddress,
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "https-listen-port",
|
||||
Usage: "(listener) HTTPS listen port",
|
||||
Value: 6443,
|
||||
Destination: &ServerConfig.HTTPSPort,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "advertise-address",
|
||||
Usage: "(listener) IPv4 address that apiserver uses to advertise to members of the cluster (default: node-external-ip/node-ip)",
|
||||
Destination: &ServerConfig.AdvertiseIP,
|
||||
},
|
||||
cli.IntFlag{
|
||||
Name: "advertise-port",
|
||||
Usage: "(listener) Port that apiserver uses to advertise to members of the cluster (default: listen-port)",
|
||||
Destination: &ServerConfig.AdvertisePort,
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "tls-san",
|
||||
Usage: "(listener) Add additional hostnames or IPv4/IPv6 addresses as Subject Alternative Names on the server TLS cert",
|
||||
Value: &ServerConfig.TLSSan,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "data-dir,d",
|
||||
Usage: "(data) Folder to hold state default /var/lib/rancher/" + version.Program + " or ${HOME}/.rancher/" + version.Program + " if not root",
|
||||
Destination: &ServerConfig.DataDir,
|
||||
},
|
||||
ClusterCIDR,
|
||||
ServiceCIDR,
|
||||
ServiceNodePortRange,
|
||||
ClusterDNS,
|
||||
ClusterDomain,
|
||||
cli.StringFlag{
|
||||
Name: "flannel-backend",
|
||||
Usage: "(networking) One of 'none', 'vxlan', 'ipsec', 'host-gw', or 'wireguard'",
|
||||
Destination: &ServerConfig.FlannelBackend,
|
||||
Value: "vxlan",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "token,t",
|
||||
Usage: "(cluster) Shared secret used to join a server or agent to a cluster",
|
||||
Destination: &ServerConfig.Token,
|
||||
EnvVar: version.ProgramUpper + "_TOKEN",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "token-file",
|
||||
Usage: "(cluster) File containing the cluster-secret/token",
|
||||
Destination: &ServerConfig.TokenFile,
|
||||
EnvVar: version.ProgramUpper + "_TOKEN_FILE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "write-kubeconfig,o",
|
||||
Usage: "(client) Write kubeconfig for admin client to this file",
|
||||
Destination: &ServerConfig.KubeConfigOutput,
|
||||
EnvVar: version.ProgramUpper + "_KUBECONFIG_OUTPUT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "write-kubeconfig-mode",
|
||||
Usage: "(client) Write kubeconfig with this mode",
|
||||
Destination: &ServerConfig.KubeConfigMode,
|
||||
EnvVar: version.ProgramUpper + "_KUBECONFIG_MODE",
|
||||
},
|
||||
ExtraAPIArgs,
|
||||
ExtraEtcdArgs,
|
||||
ExtraControllerArgs,
|
||||
ExtraSchedulerArgs,
|
||||
cli.StringSliceFlag{
|
||||
Name: "kube-cloud-controller-manager-arg",
|
||||
Usage: "(flags) Customized flag for kube-cloud-controller-manager process",
|
||||
Value: &ServerConfig.ExtraCloudControllerArgs,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "datastore-endpoint",
|
||||
Usage: "(db) Specify etcd, Mysql, Postgres, or Sqlite (default) data source name",
|
||||
Destination: &ServerConfig.DatastoreEndpoint,
|
||||
EnvVar: version.ProgramUpper + "_DATASTORE_ENDPOINT",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "datastore-cafile",
|
||||
Usage: "(db) TLS Certificate Authority file used to secure datastore backend communication",
|
||||
Destination: &ServerConfig.DatastoreCAFile,
|
||||
EnvVar: version.ProgramUpper + "_DATASTORE_CAFILE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "datastore-certfile",
|
||||
Usage: "(db) TLS certification file used to secure datastore backend communication",
|
||||
Destination: &ServerConfig.DatastoreCertFile,
|
||||
EnvVar: version.ProgramUpper + "_DATASTORE_CERTFILE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "datastore-keyfile",
|
||||
Usage: "(db) TLS key file used to secure datastore backend communication",
|
||||
Destination: &ServerConfig.DatastoreKeyFile,
|
||||
EnvVar: version.ProgramUpper + "_DATASTORE_KEYFILE",
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "etcd-expose-metrics",
|
||||
Usage: "(db) Expose etcd metrics to client interface. (Default false)",
|
||||
Destination: &ServerConfig.EtcdExposeMetrics,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "etcd-disable-snapshots",
|
||||
Usage: "(db) Disable automatic etcd snapshots",
|
||||
Destination: &ServerConfig.EtcdDisableSnapshots,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-snapshot-name",
|
||||
Usage: "(db) Set the base name of etcd snapshots. Default: etcd-snapshot-<unix-timestamp>",
|
||||
Destination: &ServerConfig.EtcdSnapshotName,
|
||||
Value: "etcd-snapshot",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-snapshot-schedule-cron",
|
||||
Usage: "(db) Snapshot interval time in cron spec. eg. every 5 hours '* */5 * * *'",
|
||||
Destination: &ServerConfig.EtcdSnapshotCron,
|
||||
Value: "0 */12 * * *",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "etcd-snapshot-retention",
|
||||
Usage: "(db) Number of snapshots to retain",
|
||||
Destination: &ServerConfig.EtcdSnapshotRetention,
|
||||
Value: defaultSnapshotRentention,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-snapshot-dir",
|
||||
Usage: "(db) Directory to save db snapshots. (Default location: ${data-dir}/db/snapshots)",
|
||||
Destination: &ServerConfig.EtcdSnapshotDir,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "etcd-s3",
|
||||
Usage: "(db) Enable backup to S3",
|
||||
Destination: &ServerConfig.EtcdS3,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-s3-endpoint",
|
||||
Usage: "(db) S3 endpoint url",
|
||||
Destination: &ServerConfig.EtcdS3Endpoint,
|
||||
Value: "s3.amazonaws.com",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-s3-endpoint-ca",
|
||||
Usage: "(db) S3 custom CA cert to connect to S3 endpoint",
|
||||
Destination: &ServerConfig.EtcdS3EndpointCA,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "etcd-s3-skip-ssl-verify",
|
||||
Usage: "(db) Disables S3 SSL certificate validation",
|
||||
Destination: &ServerConfig.EtcdS3SkipSSLVerify,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-s3-access-key",
|
||||
Usage: "(db) S3 access key",
|
||||
EnvVar: "AWS_ACCESS_KEY_ID",
|
||||
Destination: &ServerConfig.EtcdS3AccessKey,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-s3-secret-key",
|
||||
Usage: "(db) S3 secret key",
|
||||
EnvVar: "AWS_SECRET_ACCESS_KEY",
|
||||
Destination: &ServerConfig.EtcdS3SecretKey,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-s3-bucket",
|
||||
Usage: "(db) S3 bucket name",
|
||||
Destination: &ServerConfig.EtcdS3BucketName,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-s3-region",
|
||||
Usage: "(db) S3 region / bucket location (optional)",
|
||||
Destination: &ServerConfig.EtcdS3Region,
|
||||
Value: "us-east-1",
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "etcd-s3-folder",
|
||||
Usage: "(db) S3 folder",
|
||||
Destination: &ServerConfig.EtcdS3Folder,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "etcd-s3-insecure",
|
||||
Usage: "(db) Disables S3 over HTTPS",
|
||||
Destination: &ServerConfig.EtcdS3Insecure,
|
||||
},
|
||||
&cli.DurationFlag{
|
||||
Name: "etcd-s3-timeout",
|
||||
Usage: "(db) S3 timeout",
|
||||
Destination: &ServerConfig.EtcdS3Timeout,
|
||||
Value: 30 * time.Second,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "default-local-storage-path",
|
||||
Usage: "(storage) Default local storage path for local provisioner storage class",
|
||||
Destination: &ServerConfig.DefaultLocalStoragePath,
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Name: "disable",
|
||||
Usage: "(components) Do not deploy packaged components and delete any deployed components (valid items: " + DisableItems + ")",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-scheduler",
|
||||
Usage: "(components) Disable Kubernetes default scheduler",
|
||||
Destination: &ServerConfig.DisableScheduler,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-cloud-controller",
|
||||
Usage: "(components) Disable " + version.Program + " default cloud controller manager",
|
||||
Destination: &ServerConfig.DisableCCM,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-kube-proxy",
|
||||
Usage: "(components) Disable running kube-proxy",
|
||||
Destination: &ServerConfig.DisableKubeProxy,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-network-policy",
|
||||
Usage: "(components) Disable " + version.Program + " default network policy controller",
|
||||
Destination: &ServerConfig.DisableNPC,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-helm-controller",
|
||||
Usage: "(components) Disable Helm controller",
|
||||
Destination: &ServerConfig.DisableHelmController,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-apiserver",
|
||||
Hidden: true,
|
||||
Usage: "(experimental/components) Disable running api server",
|
||||
Destination: &ServerConfig.DisableAPIServer,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-controller-manager",
|
||||
Hidden: true,
|
||||
Usage: "(experimental/components) Disable running kube-controller-manager",
|
||||
Destination: &ServerConfig.DisableControllerManager,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-etcd",
|
||||
Hidden: true,
|
||||
Usage: "(experimental/components) Disable running etcd",
|
||||
Destination: &ServerConfig.DisableETCD,
|
||||
},
|
||||
NodeNameFlag,
|
||||
WithNodeIDFlag,
|
||||
NodeLabels,
|
||||
NodeTaints,
|
||||
ImageCredProvBinDirFlag,
|
||||
ImageCredProvConfigFlag,
|
||||
DockerFlag,
|
||||
CRIEndpointFlag,
|
||||
PauseImageFlag,
|
||||
SnapshotterFlag,
|
||||
PrivateRegistryFlag,
|
||||
AirgapExtraRegistryFlag,
|
||||
NodeIPFlag,
|
||||
NodeExternalIPFlag,
|
||||
ResolvConfFlag,
|
||||
FlannelIfaceFlag,
|
||||
FlannelConfFlag,
|
||||
ExtraKubeletArgs,
|
||||
ExtraKubeProxyArgs,
|
||||
ProtectKernelDefaultsFlag,
|
||||
cli.BoolFlag{
|
||||
Name: "rootless",
|
||||
Usage: "(experimental) Run rootless",
|
||||
Destination: &ServerConfig.Rootless,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "agent-token",
|
||||
Usage: "(cluster) Shared secret used to join agents to the cluster, but not servers",
|
||||
Destination: &ServerConfig.AgentToken,
|
||||
EnvVar: version.ProgramUpper + "_AGENT_TOKEN",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "agent-token-file",
|
||||
Usage: "(cluster) File containing the agent secret",
|
||||
Destination: &ServerConfig.AgentTokenFile,
|
||||
EnvVar: version.ProgramUpper + "_AGENT_TOKEN_FILE",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "server,s",
|
||||
Usage: "(cluster) Server to connect to, used to join a cluster",
|
||||
EnvVar: version.ProgramUpper + "_URL",
|
||||
Destination: &ServerConfig.ServerURL,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "cluster-init",
|
||||
Usage: "(cluster) Initialize a new cluster using embedded Etcd",
|
||||
EnvVar: version.ProgramUpper + "_CLUSTER_INIT",
|
||||
Destination: &ServerConfig.ClusterInit,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "cluster-reset",
|
||||
Usage: "(cluster) Forget all peers and become sole member of a new cluster",
|
||||
EnvVar: version.ProgramUpper + "_CLUSTER_RESET",
|
||||
Destination: &ServerConfig.ClusterReset,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "cluster-reset-restore-path",
|
||||
Usage: "(db) Path to snapshot file to be restored",
|
||||
Destination: &ServerConfig.ClusterResetRestorePath,
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "secrets-encryption",
|
||||
Usage: "(experimental) Enable Secret encryption at rest",
|
||||
Destination: &ServerConfig.EncryptSecrets,
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "system-default-registry",
|
||||
Usage: "(image) Private registry to be used for all system images",
|
||||
EnvVar: version.ProgramUpper + "_SYSTEM_DEFAULT_REGISTRY",
|
||||
Destination: &ServerConfig.SystemDefaultRegistry,
|
||||
},
|
||||
&SELinuxFlag,
|
||||
LBServerPortFlag,
|
||||
|
||||
// Hidden/Deprecated flags below
|
||||
|
||||
&DisableSELinuxFlag,
|
||||
FlannelFlag,
|
||||
cli.StringSliceFlag{
|
||||
Name: "no-deploy",
|
||||
Usage: "(deprecated) Do not deploy packaged components (valid items: " + DisableItems + ")",
|
||||
},
|
||||
cli.StringFlag{
|
||||
Name: "cluster-secret",
|
||||
Usage: "(deprecated) use --token",
|
||||
Destination: &ServerConfig.ClusterSecret,
|
||||
EnvVar: version.ProgramUpper + "_CLUSTER_SECRET",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
Name: "disable-agent",
|
||||
Usage: "Do not run a local agent and register a local kubelet",
|
||||
Hidden: true,
|
||||
Destination: &ServerConfig.DisableAgent,
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Hidden: true,
|
||||
Name: "kube-controller-arg",
|
||||
Usage: "(flags) Customized flag for kube-controller-manager process",
|
||||
Value: &ServerConfig.ExtraControllerArgs,
|
||||
},
|
||||
cli.StringSliceFlag{
|
||||
Hidden: true,
|
||||
Name: "kube-cloud-controller-arg",
|
||||
Usage: "(flags) Customized flag for kube-cloud-controller-manager process",
|
||||
Value: &ServerConfig.ExtraCloudControllerArgs,
|
||||
},
|
||||
},
|
||||
Flags: ServerFlags,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
package configfilearg
|
||||
|
||||
import (
|
||||
"github.com/rancher/k3s/pkg/cli/cmds"
|
||||
"github.com/rancher/k3s/pkg/version"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
var defaultParser = &Parser{
|
||||
After: []string{"server", "agent", "etcd-snapshot:1"},
|
||||
FlagNames: []string{"--config", "-c"},
|
||||
EnvName: version.ProgramUpper + "_CONFIG_FILE",
|
||||
DefaultConfig: "/etc/rancher/" + version.Program + "/config.yaml",
|
||||
ValidFlags: map[string][]cli.Flag{"server": cmds.ServerFlags, "etcd-snapshot": cmds.EtcdSnapshotFlags},
|
||||
}
|
||||
|
||||
func MustParse(args []string) []string {
|
||||
parser := &Parser{
|
||||
After: []string{"server", "agent", "etcd-snapshot"},
|
||||
FlagNames: []string{"--config", "-c"},
|
||||
EnvName: version.ProgramUpper + "_CONFIG_FILE",
|
||||
DefaultConfig: "/etc/rancher/" + version.Program + "/config.yaml",
|
||||
}
|
||||
result, err := parser.Parse(args)
|
||||
result, err := defaultParser.Parse(args)
|
||||
if err != nil {
|
||||
logrus.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package configfilearg
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_UnitMustParse(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
args []string
|
||||
config string
|
||||
want []string
|
||||
}{
|
||||
{
|
||||
name: "Basic server",
|
||||
args: []string{"k3s", "server"},
|
||||
|
||||
want: []string{"k3s", "server"},
|
||||
},
|
||||
{
|
||||
name: "Server with known flags",
|
||||
args: []string{"k3s", "server", "-t 12345", "--write-kubeconfig-mode 644"},
|
||||
|
||||
want: []string{"k3s", "server", "-t 12345", "--write-kubeconfig-mode 644"},
|
||||
},
|
||||
{
|
||||
name: "Server with known flags and config with known and unknown flags",
|
||||
args: []string{"k3s", "server", "--write-kubeconfig-mode 644"},
|
||||
config: "./testdata/defaultdata.yaml",
|
||||
want: []string{"k3s", "server", "--token=12345", "--node-label=DEAFBEEF",
|
||||
"--etcd-s3=true", "--etcd-s3-bucket=my-backup", "--write-kubeconfig-mode 644"},
|
||||
},
|
||||
{
|
||||
name: "Basic etcd-snapshot",
|
||||
args: []string{"k3s", "etcd-snapshot", "save"},
|
||||
|
||||
want: []string{"k3s", "etcd-snapshot", "save"},
|
||||
},
|
||||
{
|
||||
name: "Etcd-snapshot with known flags",
|
||||
args: []string{"k3s", "etcd-snapshot", "save", "--s3=true"},
|
||||
|
||||
want: []string{"k3s", "etcd-snapshot", "save", "--s3=true"},
|
||||
},
|
||||
{
|
||||
name: "Etcd-snapshot with config with known and unknown flags",
|
||||
args: []string{"k3s", "etcd-snapshot", "save"},
|
||||
config: "./testdata/defaultdata.yaml",
|
||||
want: []string{"k3s", "etcd-snapshot", "save", "--etcd-s3=true", "--etcd-s3-bucket=my-backup"},
|
||||
},
|
||||
{
|
||||
name: "Agent with known flags",
|
||||
args: []string{"k3s", "agent", "--token=12345"},
|
||||
|
||||
want: []string{"k3s", "agent", "--token=12345"},
|
||||
},
|
||||
{
|
||||
name: "Agent with config with known and unknown flags, flags are not skipped",
|
||||
args: []string{"k3s", "agent"},
|
||||
config: "./testdata/defaultdata.yaml",
|
||||
want: []string{"k3s", "agent", "--token=12345", "--node-label=DEAFBEEF",
|
||||
"--etcd-s3=true", "--etcd-s3-bucket=my-backup", "--notaflag=true"},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
defaultParser.DefaultConfig = tt.config
|
||||
if got := MustParse(tt.args); !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("MustParse() = %+v\nWant = %+v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -7,10 +7,14 @@ import (
|
|||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/rancher/k3s/pkg/agent/util"
|
||||
"github.com/rancher/wrangler/pkg/data/convert"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/urfave/cli"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
|
@ -19,6 +23,7 @@ type Parser struct {
|
|||
FlagNames []string
|
||||
EnvName string
|
||||
DefaultConfig string
|
||||
ValidFlags map[string][]cli.Flag
|
||||
}
|
||||
|
||||
// Parse will parse an os.Args style slice looking for Parser.FlagNames after Parse.After.
|
||||
|
@ -42,12 +47,55 @@ func (p *Parser) Parse(args []string) ([]string, error) {
|
|||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(args) > 1 {
|
||||
values, err = p.stripInvalidFlags(args[1], values)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return append(prefix, append(values, suffix...)...), nil
|
||||
}
|
||||
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (p *Parser) stripInvalidFlags(command string, args []string) ([]string, error) {
|
||||
var result []string
|
||||
var cmdFlags []cli.Flag
|
||||
for k, v := range p.ValidFlags {
|
||||
if k == command {
|
||||
cmdFlags = v
|
||||
}
|
||||
}
|
||||
if len(cmdFlags) == 0 {
|
||||
return args, nil
|
||||
}
|
||||
validFlags := make(map[string]bool, len(cmdFlags))
|
||||
for _, f := range cmdFlags {
|
||||
//split flags with aliases into 2 entries
|
||||
for _, s := range strings.Split(f.GetName(), ",") {
|
||||
validFlags[s] = true
|
||||
}
|
||||
}
|
||||
|
||||
re, err := regexp.Compile("^-+(.+)=")
|
||||
if err != nil {
|
||||
return args, err
|
||||
}
|
||||
for _, arg := range args {
|
||||
mArg := arg
|
||||
if match := re.FindAllStringSubmatch(arg, -1); match != nil {
|
||||
mArg = match[0][1]
|
||||
}
|
||||
if validFlags[mArg] {
|
||||
result = append(result, arg)
|
||||
} else {
|
||||
logrus.Warnf("Unknown flag %s found in config.yaml, skipping\n", arg)
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (p *Parser) FindString(args []string, target string) (string, error) {
|
||||
configFile, isSet := p.findConfigFileFlag(args)
|
||||
if configFile != "" {
|
||||
|
@ -100,15 +148,37 @@ func (p *Parser) findStart(args []string) ([]string, []string, bool) {
|
|||
if len(p.After) == 0 {
|
||||
return []string{}, args, true
|
||||
}
|
||||
|
||||
for i, val := range args {
|
||||
for _, test := range p.After {
|
||||
if val == test {
|
||||
return args[0 : i+1], args[i+1:], true
|
||||
afterTemp := append([]string{}, p.After...)
|
||||
afterIndex := make(map[string]int)
|
||||
re, err := regexp.Compile(`(.+):(\d+)`)
|
||||
if err != nil {
|
||||
return args, nil, false
|
||||
}
|
||||
// After keywords ending with ":<NUM>" can set + NUM of arguments as the split point.
|
||||
// used for matching on subcommmands
|
||||
for i, arg := range afterTemp {
|
||||
if match := re.FindAllStringSubmatch(arg, -1); match != nil {
|
||||
afterTemp[i] = match[0][1]
|
||||
afterIndex[match[0][1]], err = strconv.Atoi(match[0][2])
|
||||
if err != nil {
|
||||
return args, nil, false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i, val := range args {
|
||||
for _, test := range afterTemp {
|
||||
if val == test {
|
||||
if skip := afterIndex[test]; skip != 0 {
|
||||
if len(args) <= i+skip || strings.HasPrefix(args[i+skip], "-") {
|
||||
return args[0 : i+1], args[i+1:], true
|
||||
}
|
||||
return args[0 : i+skip+1], args[i+skip+1:], true
|
||||
}
|
||||
return args[0 : i+1], args[i+1:], true
|
||||
}
|
||||
}
|
||||
}
|
||||
return args, nil, false
|
||||
}
|
||||
|
||||
|
|
|
@ -48,11 +48,53 @@ func Test_UnitParser_findStart(t *testing.T) {
|
|||
prefix: []string{"not-server", "foo", "bar"},
|
||||
found: false,
|
||||
},
|
||||
{
|
||||
name: "command (with optional subcommands) but no flags",
|
||||
args: []string{"etcd-snapshot"},
|
||||
prefix: []string{"etcd-snapshot"},
|
||||
suffix: []string{},
|
||||
found: true,
|
||||
},
|
||||
{
|
||||
name: "command (with optional subcommands) and flags",
|
||||
args: []string{"etcd-snapshot", "-f"},
|
||||
prefix: []string{"etcd-snapshot"},
|
||||
suffix: []string{"-f"},
|
||||
found: true,
|
||||
},
|
||||
{
|
||||
name: "command and subcommand with no flags",
|
||||
args: []string{"etcd-snapshot", "list"},
|
||||
prefix: []string{"etcd-snapshot", "list"},
|
||||
suffix: []string{},
|
||||
found: true,
|
||||
},
|
||||
{
|
||||
name: "command and subcommand with flags",
|
||||
args: []string{"etcd-snapshot", "list", "-f"},
|
||||
prefix: []string{"etcd-snapshot", "list"},
|
||||
suffix: []string{"-f"},
|
||||
found: true,
|
||||
},
|
||||
{
|
||||
name: "another command and subcommand with flags",
|
||||
args: []string{"etcd-snapshot", "save", "--s3"},
|
||||
prefix: []string{"etcd-snapshot", "save"},
|
||||
suffix: []string{"--s3"},
|
||||
found: true,
|
||||
},
|
||||
{
|
||||
name: "command and too many subcommands",
|
||||
args: []string{"etcd-snapshot", "list", "delete", "foo", "bar"},
|
||||
prefix: []string{"etcd-snapshot", "list"},
|
||||
suffix: []string{"delete", "foo", "bar"},
|
||||
found: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
p := Parser{
|
||||
After: []string{"server", "agent"},
|
||||
After: []string{"server", "agent", "etcd-snapshot:1"},
|
||||
}
|
||||
prefix, suffix, found := p.findStart(tt.args)
|
||||
if !reflect.DeepEqual(prefix, tt.prefix) {
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
token: 12345
|
||||
node-label: DEAFBEEF
|
||||
etcd-s3: true
|
||||
etcd-s3-bucket: my-backup
|
||||
notaflag : true
|
Loading…
Reference in New Issue