From 138e14b1ada5b56ae4946f70d52a746791e54110 Mon Sep 17 00:00:00 2001 From: justinsb Date: Sun, 22 Jun 2025 14:08:58 -0400 Subject: [PATCH 1/2] Create flag override-api-endpoint which allows for custom DNS setups Issue #17262 --- cmd/kops/delete_instance.go | 9 +++-- cmd/kops/export_kubeconfig.go | 3 ++ cmd/kops/get_instances.go | 19 +++++++--- cmd/kops/rolling-update_cluster.go | 9 ++--- cmd/kops/toolbox_enroll.go | 2 ++ cmd/kops/update_cluster.go | 3 ++ cmd/kops/util/factory.go | 50 +++++++++++---------------- cmd/kops/validate_cluster.go | 8 +++-- pkg/commands/commandutils/factory.go | 5 ++- pkg/commands/toolbox_enroll.go | 5 ++- pkg/kubeconfig/create_kubecfg.go | 15 +++++++- pkg/kubeconfig/create_kubecfg_test.go | 20 +++++++++++ 12 files changed, 103 insertions(+), 45 deletions(-) diff --git a/cmd/kops/delete_instance.go b/cmd/kops/delete_instance.go index f83d4fd9b8..7009e7aaed 100644 --- a/cmd/kops/delete_instance.go +++ b/cmd/kops/delete_instance.go @@ -36,6 +36,7 @@ import ( "k8s.io/kops/pkg/cloudinstances" "k8s.io/kops/pkg/commands/commandutils" "k8s.io/kops/pkg/instancegroups" + "k8s.io/kops/pkg/kubeconfig" "k8s.io/kops/pkg/validation" "k8s.io/kops/upup/pkg/fi/cloudup" "k8s.io/kubectl/pkg/util/i18n" @@ -71,6 +72,8 @@ type DeleteInstanceOptions struct { InstanceID string Surge bool + + kubeconfig.CreateKubecfgOptions } func (o *DeleteInstanceOptions) initDefaults() { @@ -150,6 +153,8 @@ func NewCmdDeleteInstance(f *util.Factory, out io.Writer) *cobra.Command { cmd.Flags().BoolVarP(&options.Yes, "yes", "y", options.Yes, "Specify --yes to immediately delete the instance") + options.CreateKubecfgOptions.AddCommonFlags(cmd.Flags()) + return cmd } @@ -167,12 +172,12 @@ func RunDeleteInstance(ctx context.Context, f *util.Factory, out io.Writer, opti var k8sClient kubernetes.Interface var restConfig *rest.Config if !options.CloudOnly { - restConfig, err = f.RESTConfig(cluster) + restConfig, err = f.RESTConfig(ctx, cluster, options.CreateKubecfgOptions) if err != nil { return fmt.Errorf("getting rest config: %w", err) } - httpClient, err := f.HTTPClient(cluster) + httpClient, err := f.HTTPClient(restConfig) if err != nil { return fmt.Errorf("getting http client: %w", err) } diff --git a/cmd/kops/export_kubeconfig.go b/cmd/kops/export_kubeconfig.go index b04ac12862..c8707dc547 100644 --- a/cmd/kops/export_kubeconfig.go +++ b/cmd/kops/export_kubeconfig.go @@ -94,9 +94,12 @@ func NewCmdExportKubeconfig(f *util.Factory, out io.Writer) *cobra.Command { cmd.Flags().Lookup("admin").NoOptDefVal = kubeconfig.DefaultKubecfgAdminLifetime.String() cmd.Flags().StringVar(&options.User, "user", options.User, "Existing user in kubeconfig file to use") cmd.RegisterFlagCompletionFunc("user", completeKubecfgUser) + cmd.Flags().BoolVar(&options.Internal, "internal", options.Internal, "Use the cluster's internal DNS name") cmd.Flags().BoolVar(&options.UseKopsAuthenticationPlugin, "auth-plugin", options.UseKopsAuthenticationPlugin, "Use the kOps authentication plugin") + options.CreateKubecfgOptions.AddCommonFlags(cmd.Flags()) + return cmd } diff --git a/cmd/kops/get_instances.go b/cmd/kops/get_instances.go index 8d039a4470..7abe002f2a 100644 --- a/cmd/kops/get_instances.go +++ b/cmd/kops/get_instances.go @@ -26,6 +26,7 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/kops/pkg/cloudinstances" "k8s.io/kops/pkg/commands/commandutils" + "k8s.io/kops/pkg/kubeconfig" "k8s.io/kubectl/pkg/util/i18n" "k8s.io/kubectl/pkg/util/templates" "sigs.k8s.io/yaml" @@ -64,7 +65,15 @@ type renderableCloudInstance struct { State string `json:"state"` } +type GetInstancesOptions struct { + *GetOptions + kubeconfig.CreateKubecfgOptions +} + func NewCmdGetInstances(f *util.Factory, out io.Writer, options *GetOptions) *cobra.Command { + opt := GetInstancesOptions{ + GetOptions: options, + } cmd := &cobra.Command{ Use: "instances [CLUSTER]", Short: getInstancesShort, @@ -72,14 +81,16 @@ func NewCmdGetInstances(f *util.Factory, out io.Writer, options *GetOptions) *co Args: rootCommand.clusterNameArgs(&options.ClusterName), ValidArgsFunction: commandutils.CompleteClusterName(f, true, false), RunE: func(cmd *cobra.Command, args []string) error { - return RunGetInstances(cmd.Context(), f, out, options) + return RunGetInstances(cmd.Context(), f, out, &opt) }, } + opt.CreateKubecfgOptions.AddCommonFlags(cmd.Flags()) + return cmd } -func RunGetInstances(ctx context.Context, f *util.Factory, out io.Writer, options *GetOptions) error { +func RunGetInstances(ctx context.Context, f *util.Factory, out io.Writer, options *GetInstancesOptions) error { clientset, err := f.KopsClient() if err != nil { return err @@ -99,12 +110,12 @@ func RunGetInstances(ctx context.Context, f *util.Factory, out io.Writer, option return err } - restConfig, err := f.RESTConfig(cluster) + restConfig, err := f.RESTConfig(ctx, cluster, options.CreateKubecfgOptions) if err != nil { return err } - httpClient, err := f.HTTPClient(cluster) + httpClient, err := f.HTTPClient(restConfig) if err != nil { return err } diff --git a/cmd/kops/rolling-update_cluster.go b/cmd/kops/rolling-update_cluster.go index 467f81ea1c..5473662876 100644 --- a/cmd/kops/rolling-update_cluster.go +++ b/cmd/kops/rolling-update_cluster.go @@ -219,6 +219,8 @@ func NewCmdRollingUpdateCluster(f *util.Factory, out io.Writer) *cobra.Command { cmd.Flags().BoolVar(&options.FailOnDrainError, "fail-on-drain-error", true, "Fail if draining a node fails") cmd.Flags().BoolVar(&options.FailOnValidate, "fail-on-validate-error", true, "Fail if the cluster fails to validate") + options.CreateKubecfgOptions.AddCommonFlags(cmd.Flags()) + cmd.Flags().SetNormalizeFunc(func(f *pflag.FlagSet, name string) pflag.NormalizedName { switch name { case "ig", "instance-groups": @@ -233,7 +235,6 @@ func NewCmdRollingUpdateCluster(f *util.Factory, out io.Writer) *cobra.Command { } func RunRollingUpdateCluster(ctx context.Context, f *util.Factory, out io.Writer, options *RollingUpdateOptions) error { - f.CreateKubecfgOptions = options.CreateKubecfgOptions clientset, err := f.KopsClient() if err != nil { return err @@ -247,12 +248,12 @@ func RunRollingUpdateCluster(ctx context.Context, f *util.Factory, out io.Writer var nodes []v1.Node var k8sClient kubernetes.Interface if !options.CloudOnly { - restConfig, err := f.RESTConfig(cluster) + restConfig, err := f.RESTConfig(ctx, cluster, options.CreateKubecfgOptions) if err != nil { return fmt.Errorf("getting rest config: %w", err) } - httpClient, err := f.HTTPClient(cluster) + httpClient, err := f.HTTPClient(restConfig) if err != nil { return fmt.Errorf("getting http client: %w", err) } @@ -454,7 +455,7 @@ func RunRollingUpdateCluster(ctx context.Context, f *util.Factory, out io.Writer var clusterValidator validation.ClusterValidator if !options.CloudOnly { - restConfig, err := f.RESTConfig(cluster) + restConfig, err := f.RESTConfig(ctx, cluster, options.CreateKubecfgOptions) if err != nil { return fmt.Errorf("getting rest config: %w", err) } diff --git a/cmd/kops/toolbox_enroll.go b/cmd/kops/toolbox_enroll.go index 55d3600655..7fd321fed1 100644 --- a/cmd/kops/toolbox_enroll.go +++ b/cmd/kops/toolbox_enroll.go @@ -50,5 +50,7 @@ func NewCmdToolboxEnroll(f commandutils.Factory, out io.Writer) *cobra.Command { cmd.Flags().StringVar(&options.SSHUser, "ssh-user", options.SSHUser, "user for ssh") cmd.Flags().IntVar(&options.SSHPort, "ssh-port", options.SSHPort, "port for ssh") + options.CreateKubecfgOptions.AddCommonFlags(cmd.Flags()) + return cmd } diff --git a/cmd/kops/update_cluster.go b/cmd/kops/update_cluster.go index 8a3d9cfa20..d1e2f08bdd 100644 --- a/cmd/kops/update_cluster.go +++ b/cmd/kops/update_cluster.go @@ -170,7 +170,10 @@ func NewCmdUpdateCluster(f *util.Factory, out io.Writer) *cobra.Command { cmd.Flags().Lookup("admin").NoOptDefVal = kubeconfig.DefaultKubecfgAdminLifetime.String() cmd.Flags().StringVar(&options.User, "user", options.User, "Existing user in kubeconfig file to use. Implies --create-kube-config") cmd.RegisterFlagCompletionFunc("user", completeKubecfgUser) + cmd.Flags().BoolVar(&options.Internal, "internal", options.Internal, "Use the cluster's internal DNS name. Implies --create-kube-config") + options.CreateKubecfgOptions.AddCommonFlags(cmd.Flags()) + cmd.Flags().BoolVar(&options.AllowKopsDowngrade, "allow-kops-downgrade", options.AllowKopsDowngrade, "Allow an older version of kOps to update the cluster than last used") cmd.Flags().StringSliceVar(&options.InstanceGroups, "instance-group", options.InstanceGroups, "Instance groups to update (defaults to all if not specified)") cmd.RegisterFlagCompletionFunc("instance-group", completeInstanceGroup(f, &options.InstanceGroups, &options.InstanceGroupRoles)) diff --git a/cmd/kops/util/factory.go b/cmd/kops/util/factory.go index 272de84cef..966ca62b97 100644 --- a/cmd/kops/util/factory.go +++ b/cmd/kops/util/factory.go @@ -55,8 +55,6 @@ type Factory struct { mutex sync.Mutex // clusters holds REST connection configuration for connecting to clusters clusters map[string]*clusterInfo - - kubeconfig.CreateKubecfgOptions } // clusterInfo holds REST connection configuration for connecting to a cluster @@ -161,7 +159,7 @@ func (f *Factory) KopsStateStore() string { return f.options.RegistryPath } -func (f *Factory) getClusterInfo(cluster *kops.Cluster) *clusterInfo { +func (f *Factory) getClusterInfo(cluster *kops.Cluster, options kubeconfig.CreateKubecfgOptions) *clusterInfo { f.mutex.Lock() defer f.mutex.Unlock() @@ -170,22 +168,20 @@ func (f *Factory) getClusterInfo(cluster *kops.Cluster) *clusterInfo { return clusterInfo } clusterInfo := &clusterInfo{ - factory: f, - cluster: cluster, + factory: f, + cluster: cluster, + CreateKubecfgOptions: options, } f.clusters[key] = clusterInfo return clusterInfo } -func (f *Factory) RESTConfig(cluster *kops.Cluster) (*rest.Config, error) { - clusterInfo := f.getClusterInfo(cluster) - clusterInfo.CreateKubecfgOptions = f.CreateKubecfgOptions - return clusterInfo.RESTConfig() +func (f *Factory) RESTConfig(ctx context.Context, cluster *kops.Cluster, options kubeconfig.CreateKubecfgOptions) (*rest.Config, error) { + clusterInfo := f.getClusterInfo(cluster, options) + return clusterInfo.RESTConfig(ctx) } -func (f *clusterInfo) RESTConfig() (*rest.Config, error) { - ctx := context.Background() - +func (f *clusterInfo) RESTConfig(ctx context.Context) (*rest.Config, error) { if f.cachedRESTConfig == nil { restConfig, err := f.factory.buildRESTConfig(ctx, f.cluster, f.CreateKubecfgOptions) if err != nil { @@ -201,17 +197,12 @@ func (f *clusterInfo) RESTConfig() (*rest.Config, error) { return f.cachedRESTConfig, nil } -func (f *Factory) HTTPClient(cluster *kops.Cluster) (*http.Client, error) { - clusterInfo := f.getClusterInfo(cluster) - return clusterInfo.HTTPClient() +func (f *Factory) HTTPClient(restConfig *rest.Config) (*http.Client, error) { + return rest.HTTPClientFor(restConfig) } -func (f *clusterInfo) HTTPClient() (*http.Client, error) { +func (f *clusterInfo) HTTPClient(restConfig *rest.Config) (*http.Client, error) { if f.cachedHTTPClient == nil { - restConfig, err := f.RESTConfig() - if err != nil { - return nil, err - } httpClient, err := rest.HTTPClientFor(restConfig) if err != nil { return nil, fmt.Errorf("building http client: %w", err) @@ -222,19 +213,18 @@ func (f *clusterInfo) HTTPClient() (*http.Client, error) { } // DynamicClient returns a dynamic client -func (f *Factory) DynamicClient(cluster *kops.Cluster) (dynamic.Interface, error) { - clusterInfo := f.getClusterInfo(cluster) - return clusterInfo.DynamicClient() +func (f *Factory) DynamicClient(ctx context.Context, cluster *kops.Cluster, options kubeconfig.CreateKubecfgOptions) (dynamic.Interface, error) { + clusterInfo := f.getClusterInfo(cluster, options) + restConfig, err := clusterInfo.RESTConfig(ctx) + if err != nil { + return nil, err + } + return clusterInfo.DynamicClient(restConfig) } -func (f *clusterInfo) DynamicClient() (dynamic.Interface, error) { +func (f *clusterInfo) DynamicClient(restConfig *rest.Config) (dynamic.Interface, error) { if f.cachedDynamicClient == nil { - restConfig, err := f.RESTConfig() - if err != nil { - return nil, err - } - - httpClient, err := f.HTTPClient() + httpClient, err := f.HTTPClient(restConfig) if err != nil { return nil, err } diff --git a/cmd/kops/validate_cluster.go b/cmd/kops/validate_cluster.go index 9fcc45e401..cc3e601e99 100644 --- a/cmd/kops/validate_cluster.go +++ b/cmd/kops/validate_cluster.go @@ -75,6 +75,8 @@ type ValidateClusterOptions struct { // filterPodsForValidation is a function that returns true if the pod should be validated filterPodsForValidation func(pod *v1.Pod) bool + + ExportKubeconfigOptions } func (o *ValidateClusterOptions) InitDefaults() { @@ -117,6 +119,8 @@ func NewCmdValidateCluster(f *util.Factory, out io.Writer) *cobra.Command { cmd.Flags().DurationVar(&options.interval, "interval", options.interval, "Time in duration to wait between validation attempts") cmd.Flags().StringVar(&options.kubeconfig, "kubeconfig", "", "Path to the kubeconfig file") + options.CreateKubecfgOptions.AddCommonFlags(cmd.Flags()) + return cmd } @@ -155,12 +159,12 @@ func RunValidateCluster(ctx context.Context, f *util.Factory, out io.Writer, opt return nil, fmt.Errorf("no InstanceGroup objects found") } - restConfig, err := f.RESTConfig(cluster) + restConfig, err := f.RESTConfig(ctx, cluster, options.CreateKubecfgOptions) if err != nil { return nil, fmt.Errorf("getting rest config: %w", err) } - httpClient, err := f.HTTPClient(cluster) + httpClient, err := f.HTTPClient(restConfig) if err != nil { return nil, fmt.Errorf("getting http client: %w", err) } diff --git a/pkg/commands/commandutils/factory.go b/pkg/commands/commandutils/factory.go index 4436e07ccf..04268d1ad5 100644 --- a/pkg/commands/commandutils/factory.go +++ b/pkg/commands/commandutils/factory.go @@ -17,15 +17,18 @@ limitations under the License. package commandutils import ( + "context" + "k8s.io/client-go/rest" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/client/simple" + "k8s.io/kops/pkg/kubeconfig" "k8s.io/kops/util/pkg/vfs" ) type Factory interface { KopsClient() (simple.Clientset, error) VFSContext() *vfs.VFSContext - RESTConfig(cluster *kops.Cluster) (*rest.Config, error) + RESTConfig(ctx context.Context, cluster *kops.Cluster, options kubeconfig.CreateKubecfgOptions) (*rest.Config, error) } diff --git a/pkg/commands/toolbox_enroll.go b/pkg/commands/toolbox_enroll.go index 736e977689..aba1de01e4 100644 --- a/pkg/commands/toolbox_enroll.go +++ b/pkg/commands/toolbox_enroll.go @@ -48,6 +48,7 @@ import ( "k8s.io/kops/pkg/client/simple" "k8s.io/kops/pkg/commands/commandutils" "k8s.io/kops/pkg/featureflag" + "k8s.io/kops/pkg/kubeconfig" "k8s.io/kops/pkg/model" "k8s.io/kops/pkg/model/resources" "k8s.io/kops/pkg/nodemodel" @@ -65,6 +66,8 @@ type ToolboxEnrollOptions struct { SSHUser string SSHPort int + + kubeconfig.CreateKubecfgOptions } func (o *ToolboxEnrollOptions) InitDefaults() { @@ -108,7 +111,7 @@ func RunToolboxEnroll(ctx context.Context, f commandutils.Factory, out io.Writer // Enroll the node over SSH. if options.Host != "" { - restConfig, err := f.RESTConfig(fullCluster) + restConfig, err := f.RESTConfig(ctx, fullCluster, options.CreateKubecfgOptions) if err != nil { return err } diff --git a/pkg/kubeconfig/create_kubecfg.go b/pkg/kubeconfig/create_kubecfg.go index 51bf933249..fc34597d9a 100644 --- a/pkg/kubeconfig/create_kubecfg.go +++ b/pkg/kubeconfig/create_kubecfg.go @@ -24,6 +24,7 @@ import ( "sort" "time" + "github.com/spf13/pflag" "k8s.io/klog/v2" "k8s.io/kops/pkg/apis/kops" "k8s.io/kops/pkg/pki" @@ -42,6 +43,10 @@ type CreateKubecfgOptions struct { // User is the user to use in the kubeconfig User string + // OverrideAPIServer overrides the API endpoint to use in the kubeconfig + // This takes precedence over the Internal option (if set) + OverrideAPIServer string + // Internal is whether to use the internal API endpoint Internal bool @@ -49,11 +54,19 @@ type CreateKubecfgOptions struct { UseKopsAuthenticationPlugin bool } +// AddCommonFlags adds the common flags to the flagset +// These are the flags that are used when building an internal connection to the cluster. +func (o *CreateKubecfgOptions) AddCommonFlags(flagset *pflag.FlagSet) { + flagset.StringVar(&o.OverrideAPIServer, "api-server", o.OverrideAPIServer, "Override the API server used when communicating with the cluster kube-apiserver") +} + func BuildKubecfg(ctx context.Context, cluster *kops.Cluster, keyStore fi.KeystoreReader, secretStore fi.SecretStore, cloud fi.Cloud, options CreateKubecfgOptions, kopsStateStore string) (*KubeconfigBuilder, error) { clusterName := cluster.ObjectMeta.Name var server string - if options.Internal { + if options.OverrideAPIServer != "" { + server = options.OverrideAPIServer + } else if options.Internal { server = "https://" + cluster.APIInternalName() } else { if cluster.Spec.API.PublicName != "" { diff --git a/pkg/kubeconfig/create_kubecfg_test.go b/pkg/kubeconfig/create_kubecfg_test.go index a9ab80490a..e68efb6811 100644 --- a/pkg/kubeconfig/create_kubecfg_test.go +++ b/pkg/kubeconfig/create_kubecfg_test.go @@ -405,6 +405,26 @@ func TestBuildKubecfg(t *testing.T) { }, wantClientCert: false, }, + { + name: "Test Kube Config Data with APIEndpoint set", + args: args{ + cluster: publicCluster, + status: fakeStatus, + CreateKubecfgOptions: CreateKubecfgOptions{ + Admin: DefaultKubecfgAdminLifetime, + Internal: true, + OverrideAPIServer: "https://api.testcluster.example.com", + }, + }, + want: &KubeconfigBuilder{ + Context: "testcluster", + Server: "https://api.testcluster.example.com", + TLSServerName: "api.internal.testcluster", + CACerts: []byte(nextCertificate + certData), + User: "testcluster", + }, + wantClientCert: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 90066a5d6e49c3550ea7e36156dfaff57f355702 Mon Sep 17 00:00:00 2001 From: justinsb Date: Sun, 22 Jun 2025 14:15:39 -0400 Subject: [PATCH 2/2] autogen: make gen-cli-docs --- docs/cli/kops_delete_instance.md | 1 + docs/cli/kops_export_kubeconfig.md | 1 + docs/cli/kops_get_instances.md | 3 ++- docs/cli/kops_rolling-update_cluster.md | 1 + docs/cli/kops_toolbox_enroll.md | 1 + docs/cli/kops_update_cluster.md | 1 + docs/cli/kops_validate_cluster.md | 1 + 7 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/cli/kops_delete_instance.md b/docs/cli/kops_delete_instance.md index dec0cd2ebd..1cfc8eaee8 100644 --- a/docs/cli/kops_delete_instance.md +++ b/docs/cli/kops_delete_instance.md @@ -30,6 +30,7 @@ kops delete instance INSTANCE|NODE [flags] ### Options ``` + --api-server string Override the API server used when communicating with the cluster kube-apiserver --cloudonly Perform deletion update without confirming progress with Kubernetes --fail-on-drain-error Fail if draining a node fails (default true) --fail-on-validate-error Fail if the cluster fails to validate (default true) diff --git a/docs/cli/kops_export_kubeconfig.md b/docs/cli/kops_export_kubeconfig.md index 18d189de48..80462167d6 100644 --- a/docs/cli/kops_export_kubeconfig.md +++ b/docs/cli/kops_export_kubeconfig.md @@ -31,6 +31,7 @@ kops export kubeconfig [CLUSTER | --all] [flags] ``` --admin duration[=18h0m0s] Also export a cluster admin user credential with the specified lifetime and add it to the cluster context --all Export all clusters from the kOps state store + --api-server string Override the API server used when communicating with the cluster kube-apiserver --auth-plugin Use the kOps authentication plugin -h, --help help for kubeconfig --internal Use the cluster's internal DNS name diff --git a/docs/cli/kops_get_instances.md b/docs/cli/kops_get_instances.md index c529c02697..76c63882b3 100644 --- a/docs/cli/kops_get_instances.md +++ b/docs/cli/kops_get_instances.md @@ -19,7 +19,8 @@ kops get instances [CLUSTER] [flags] ### Options ``` - -h, --help help for instances + --api-server string Override the API server used when communicating with the cluster kube-apiserver + -h, --help help for instances ``` ### Options inherited from parent commands diff --git a/docs/cli/kops_rolling-update_cluster.md b/docs/cli/kops_rolling-update_cluster.md index 761c958b1e..b0ba99e84d 100644 --- a/docs/cli/kops_rolling-update_cluster.md +++ b/docs/cli/kops_rolling-update_cluster.md @@ -60,6 +60,7 @@ kops rolling-update cluster [CLUSTER] [flags] ``` --admin duration a cluster admin user credential with the specified lifetime (default 18h0m0s) + --api-server string Override the API server used when communicating with the cluster kube-apiserver --bastion-interval duration Time to wait between restarting bastions (default 15s) --cloudonly Perform rolling update without validating cluster status (will cause downtime) --control-plane-interval duration Time to wait between restarting control plane nodes (default 15s) diff --git a/docs/cli/kops_toolbox_enroll.md b/docs/cli/kops_toolbox_enroll.md index 2f68d815dd..e159565f7d 100644 --- a/docs/cli/kops_toolbox_enroll.md +++ b/docs/cli/kops_toolbox_enroll.md @@ -22,6 +22,7 @@ kops toolbox enroll [CLUSTER] [flags] ### Options ``` + --api-server string Override the API server used when communicating with the cluster kube-apiserver --cluster string Name of cluster to join -h, --help help for enroll --host string IP/hostname for machine to add diff --git a/docs/cli/kops_update_cluster.md b/docs/cli/kops_update_cluster.md index b178b2924c..e96b752c37 100644 --- a/docs/cli/kops_update_cluster.md +++ b/docs/cli/kops_update_cluster.md @@ -27,6 +27,7 @@ kops update cluster [CLUSTER] [flags] ``` --admin duration[=18h0m0s] Also export a cluster admin user credential with the specified lifetime and add it to the cluster context --allow-kops-downgrade Allow an older version of kOps to update the cluster than last used + --api-server string Override the API server used when communicating with the cluster kube-apiserver --create-kube-config Will control automatically creating the kube config file on your local filesystem (default true) -h, --help help for cluster --ignore-kubelet-version-skew Setting this to true will force updating the kubernetes version on all instance groups, regardles of which control plane version is running diff --git a/docs/cli/kops_validate_cluster.md b/docs/cli/kops_validate_cluster.md index 0a62e5263f..6a2a4209bf 100644 --- a/docs/cli/kops_validate_cluster.md +++ b/docs/cli/kops_validate_cluster.md @@ -29,6 +29,7 @@ kops validate cluster [CLUSTER] [flags] ### Options ``` + --api-server string Override the API server used when communicating with the cluster kube-apiserver --count int Number of consecutive successful validations required -h, --help help for cluster --interval duration Time in duration to wait between validation attempts (default 10s)