Skip to content

Commit eef7f3c

Browse files
committed
Add 'cluster', 'namespace', and 'user' options to delete command. Enhance delete to load provider components from cluster.
1 parent 7dd04a1 commit eef7f3c

File tree

7 files changed

+101
-49
lines changed

7 files changed

+101
-49
lines changed

clusterctl/clusterdeployer/clientfactory.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,5 @@ func (f *clientFactory) NewClusterClientFromKubeconfig(kubeconfig string) (Clust
3333
}
3434

3535
func (f *clientFactory) NewCoreClientsetFromKubeconfigFile(kubeconfigPath string) (*kubernetes.Clientset, error) {
36-
return clientcmd.NewCoreClientSetForDefaultSearchPath(kubeconfigPath)
36+
return clientcmd.NewCoreClientSetForDefaultSearchPath(kubeconfigPath, clientcmd.NewConfigOverrides())
3737
}

clusterctl/clusterdeployer/clusterclient.go

+41-14
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"github.com/golang/glog"
2626
apiv1 "k8s.io/api/core/v1"
2727
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
28+
tcmd "k8s.io/client-go/tools/clientcmd"
2829
clusterv1 "sigs.k8s.io/cluster-api/pkg/apis/cluster/v1alpha1"
2930
"sigs.k8s.io/cluster-api/pkg/client/clientset_generated/clientset"
3031
"sigs.k8s.io/cluster-api/pkg/clientcmd"
@@ -43,17 +44,18 @@ const (
4344
)
4445

4546
type clusterClient struct {
46-
clientSet clientset.Interface
47-
kubeconfigFile string
48-
closeFn func() error
47+
clientSet clientset.Interface
48+
kubeconfigFile string
49+
configOverrides tcmd.ConfigOverrides
50+
closeFn func() error
4951
}
5052

5153
func NewClusterClient(kubeconfig string) (*clusterClient, error) {
5254
f, err := createTempFile(kubeconfig)
5355
if err != nil {
5456
return nil, err
5557
}
56-
c, err := NewClusterClientFromFile(f)
58+
c, err := NewClusterClientFromFile(f, clientcmd.NewConfigOverrides())
5759
if err != nil {
5860
return nil, err
5961
}
@@ -65,15 +67,16 @@ func (c *clusterClient) removeKubeconfigFile() error {
6567
return os.Remove(c.kubeconfigFile)
6668
}
6769

68-
func NewClusterClientFromFile(kubeconfigFile string) (*clusterClient, error) {
69-
c, err := clientcmd.NewClusterApiClientForDefaultSearchPath(kubeconfigFile)
70+
func NewClusterClientFromFile(kubeconfigFile string, overrides tcmd.ConfigOverrides) (*clusterClient, error) {
71+
c, err := clientcmd.NewClusterApiClientForDefaultSearchPath(kubeconfigFile, overrides)
7072
if err != nil {
7173
return nil, err
7274
}
7375

7476
return &clusterClient{
75-
kubeconfigFile: kubeconfigFile,
76-
clientSet: c,
77+
kubeconfigFile: kubeconfigFile,
78+
clientSet: c,
79+
configOverrides: overrides,
7780
}, nil
7881
}
7982

@@ -162,17 +165,41 @@ func (c *clusterClient) WaitForClusterV1alpha1Ready() error {
162165
return waitForClusterResourceReady(c.clientSet)
163166
}
164167

168+
func (c *clusterClient) kubectlDelete(manifest string) error {
169+
return c.kubectlManifestCmd("delete", manifest)
170+
}
171+
165172
func (c *clusterClient) kubectlApply(manifest string) error {
173+
return c.kubectlManifestCmd("apply", manifest)
174+
}
175+
176+
func (c *clusterClient) kubectlManifestCmd(commandName string, manifest string) error {
166177
r := strings.NewReader(manifest)
167-
cmd := exec.Command("kubectl", "apply", "--kubeconfig", c.kubeconfigFile, "-f", "-")
178+
args := c.buildKubectlArgs(commandName)
179+
cmd := exec.Command("kubectl", args...)
168180
cmd.Stdin = r
169-
170181
out, err := cmd.CombinedOutput()
171-
if err == nil {
172-
return nil
173-
} else {
174-
return fmt.Errorf("couldn't kubectl apply: %v, output: %s", err, string(out))
182+
if err != nil {
183+
return fmt.Errorf("couldn't kubectl %v: %v, output: %s", commandName, err, string(out))
184+
}
185+
return nil
186+
}
187+
188+
func (c *clusterClient) buildKubectlArgs(commandName string) []string {
189+
args := []string{commandName}
190+
if c.kubeconfigFile != "" {
191+
args = append(args, "--kubeconfig", c.kubeconfigFile)
192+
}
193+
if c.configOverrides.Context.Cluster != "" {
194+
args = append(args, "--cluster", c.configOverrides.Context.Cluster)
195+
}
196+
if c.configOverrides.Context.Namespace != "" {
197+
args = append(args, "--namespace", c.configOverrides.Context.Namespace)
198+
}
199+
if c.configOverrides.Context.AuthInfo != "" {
200+
args = append(args, "--user", c.configOverrides.Context.AuthInfo)
175201
}
202+
return append(args, "-f", "-")
176203
}
177204

178205
func (c *clusterClient) waitForKubectlApply(manifest string) error {

clusterctl/cmd/delete_cluster.go

+34-6
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,22 @@ limitations under the License.
1717
package cmd
1818

1919
import (
20+
"fmt"
21+
22+
"k8s.io/api/core/v1"
23+
tcmd "k8s.io/client-go/tools/clientcmd"
24+
"sigs.k8s.io/cluster-api/clusterctl/providercomponents"
25+
"sigs.k8s.io/cluster-api/pkg/clientcmd"
26+
"sigs.k8s.io/cluster-api/pkg/errors"
27+
2028
"github.com/golang/glog"
2129
"github.com/spf13/cobra"
22-
"sigs.k8s.io/cluster-api/pkg/errors"
2330
)
2431

2532
type DeleteOptions struct {
26-
ClusterName string
27-
ProviderComponents string
33+
KubeconfigPath string
34+
ProviderComponents string
35+
KubeconfigOverrides tcmd.ConfigOverrides
2836
}
2937

3038
var do = &DeleteOptions{}
@@ -34,20 +42,40 @@ var deleteClusterCmd = &cobra.Command{
3442
Short: "Delete kubernetes cluster",
3543
Long: `Delete a kubernetes cluster with one command`,
3644
Run: func(cmd *cobra.Command, args []string) {
37-
if do.ClusterName == "" {
38-
exitWithHelp(cmd, "Please provide cluster name.")
39-
}
4045
if err := RunDelete(); err != nil {
4146
glog.Exit(err)
4247
}
4348
},
4449
}
4550

4651
func init() {
52+
deleteClusterCmd.Flags().StringVarP(&do.KubeconfigPath, "kubeconfig", "", "", "Path to the kubeconfig file to use for connecting to the cluster to be deleted, if empty, the default KUBECONFIG load path is used.")
4753
deleteClusterCmd.Flags().StringVarP(&do.ProviderComponents, "provider-components", "p", "", "A yaml file containing cluster api provider controllers and supporting objects, if empty the value is loaded from the cluster's configuration store.")
54+
// BindContextFlags will bind the flags cluster, namespace, and user
55+
tcmd.BindContextFlags(&do.KubeconfigOverrides.Context, deleteClusterCmd.Flags(), tcmd.RecommendedContextOverrideFlags(""))
4856
deleteCmd.AddCommand(deleteClusterCmd)
4957
}
5058

5159
func RunDelete() error {
60+
_, err := loadProviderComponents()
61+
if err != nil {
62+
return err
63+
}
5264
return errors.NotImplementedError
5365
}
66+
67+
func loadProviderComponents() (string, error) {
68+
coreClients, err := clientcmd.NewCoreClientSetForDefaultSearchPath(do.KubeconfigPath, do.KubeconfigOverrides)
69+
if err != nil {
70+
return "", fmt.Errorf("error creating core clients: %v", err)
71+
}
72+
pcStore := providercomponents.Store{
73+
ExplicitPath: do.ProviderComponents,
74+
ConfigMap: coreClients.CoreV1().ConfigMaps(v1.NamespaceDefault),
75+
}
76+
providerComponents, err := pcStore.Load()
77+
if err != nil {
78+
return "", fmt.Errorf("error when loading provider components: %v", err)
79+
}
80+
return providerComponents, nil
81+
}

gcp-deployer/deploy/deploy_helper.go

+1-5
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,7 @@ func (d *deployer) copyKubeConfig(cluster *clusterv1.Cluster, master *clusterv1.
258258
}
259259

260260
func (d *deployer) initApiClient() error {
261-
c, err := clientcmd.NewClusterApiClientForDefaultSearchPath(d.configPath)
262-
if err != nil {
263-
return err
264-
}
265-
kubernetesClientSet, err := clientcmd.NewCoreClientSetForDefaultSearchPath(d.configPath)
261+
kubernetesClientSet, c, err := clientcmd.NewClientsForDefaultSearchpath(d.configPath, clientcmd.NewConfigOverrides())
266262
if err != nil {
267263
return err
268264
}

pkg/clientcmd/configutil.go

+22-21
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,16 @@ import (
2727
"sigs.k8s.io/cluster-api/pkg/client/clientset_generated/clientset"
2828
)
2929

30+
// This is a convienience method to prevent the need of importing both this version of clientcmd and the client-go version
31+
func NewConfigOverrides() clientcmd.ConfigOverrides {
32+
return clientcmd.ConfigOverrides{}
33+
}
34+
3035
// NewCoreClientSetForDefaultSearchPath creates a core kubernetes clientset. If the kubeconfigPath is specified then the configuration is loaded from that path.
3136
// Otherwise the default kubeconfig search path is used.
32-
func NewCoreClientSetForDefaultSearchPath(kubeconfigPath string) (*kubernetes.Clientset, error) {
33-
config, err := newRestConfigForDefaultSearchPath(kubeconfigPath)
37+
// The overrides parameter is used to select a specific context of the config, for example, select the context with a given cluster name or namespace.
38+
func NewCoreClientSetForDefaultSearchPath(kubeconfigPath string, overrides clientcmd.ConfigOverrides) (*kubernetes.Clientset, error) {
39+
config, err := newRestConfigForDefaultSearchPath(kubeconfigPath, overrides)
3440
if err != nil {
3541
return nil, err
3642
}
@@ -48,8 +54,9 @@ func NewCoreClientSetForKubeconfig(kubeconfig string) (*kubernetes.Clientset, er
4854

4955
// NewClusterApiClientForDefaultSearchPath creates a Cluster API clientset. If the kubeconfigPath is specified then the configuration is loaded from that path.
5056
// Otherwise the default kubeconfig search path is used.
51-
func NewClusterApiClientForDefaultSearchPath(kubeconfigPath string) (*clientset.Clientset, error) {
52-
config, err := newRestConfigForDefaultSearchPath(kubeconfigPath)
57+
// The overrides parameter is used to select a specific context of the config, for example, select the context with a given cluster name or namespace.
58+
func NewClusterApiClientForDefaultSearchPath(kubeconfigPath string, overrides clientcmd.ConfigOverrides) (*clientset.Clientset, error) {
59+
config, err := newRestConfigForDefaultSearchPath(kubeconfigPath, overrides)
5360
if err != nil {
5461
return nil, err
5562
}
@@ -67,17 +74,9 @@ func NewClusterApiClientForKubeconfig(kubeconfig string) (*clientset.Clientset,
6774

6875
// NewClientsForDefaultSearchpath creates both a core kubernetes clientset and a cluster-api clientset. If the kubeconfigPath
6976
// is specified then the configuration is loaded from that path. Otherwise the default kubeconfig search path is used.
70-
func NewClientsForDefaultSearchpath(kubeconfigPath string) (*kubernetes.Clientset, *clientset.Clientset, error) {
71-
config, err := newRestConfigForDefaultSearchPath(kubeconfigPath)
72-
if err != nil {
73-
return nil, nil, err
74-
}
75-
return newClientsFromRestConfig(config)
76-
}
77-
78-
// NewClientsForKubeconfig creates both a core kubernetes clientset and a cluster-api clientset.
79-
func NewClientsForKubeconfig(kubeconfig string) (*kubernetes.Clientset, *clientset.Clientset, error) {
80-
config, err := newRestConfigForKubeconfig(kubeconfig)
77+
// The overrides parameter is used to select a specific context of the config, for example, select the context with a given cluster name or namespace.
78+
func NewClientsForDefaultSearchpath(kubeconfigPath string, overrides clientcmd.ConfigOverrides) (*kubernetes.Clientset, *clientset.Clientset, error) {
79+
config, err := newRestConfigForDefaultSearchPath(kubeconfigPath, overrides)
8180
if err != nil {
8281
return nil, nil, err
8382
}
@@ -98,14 +97,16 @@ func newClientsFromRestConfig(config *rest.Config) (*kubernetes.Clientset, *clie
9897
}
9998

10099
// newRestConfig creates a rest.Config for the given apiConfig
101-
func newRestConfig(apiConfig *api.Config) (*rest.Config, error) {
102-
return clientcmd.NewDefaultClientConfig(*apiConfig, &clientcmd.ConfigOverrides{}).ClientConfig()
100+
func newRestConfig(apiConfig *api.Config, overrides clientcmd.ConfigOverrides) (*rest.Config, error) {
101+
return clientcmd.NewDefaultClientConfig(*apiConfig, &overrides).ClientConfig()
103102
}
104103

105104
// newRestConfigForDefaultSearchPath creates a rest.Config by searching for the kubeconfig on the default search path. If an override 'kubeconfigPath' is
106105
// given then that path is used instead of the default path. If no override is given, an attempt is made to load the
107106
// 'in cluster' config. If this fails, then the default search path is used.
108-
func newRestConfigForDefaultSearchPath(kubeconfigPath string) (*rest.Config, error) {
107+
//
108+
// All the additional parameters are optional selectors, if present the rest.config
109+
func newRestConfigForDefaultSearchPath(kubeconfigPath string, overrides clientcmd.ConfigOverrides) (*rest.Config, error) {
109110
if kubeconfigPath == "" {
110111
config, err := rest.InClusterConfig()
111112
// if there is no err, continue because InClusterConfig is only expected to succeed if running inside of a pod.
@@ -117,16 +118,16 @@ func newRestConfigForDefaultSearchPath(kubeconfigPath string) (*rest.Config, err
117118
if err != nil {
118119
return nil, err
119120
}
120-
return newRestConfig(apiConfig)
121+
return newRestConfig(apiConfig, overrides)
121122
}
122123

123124
// newRestConfigForKubeconfig creates a rest.Config for a given kubeconfig string.
124125
func newRestConfigForKubeconfig(kubeconfig string) (*rest.Config, error) {
125-
apiConfig, err := newApiConfigForDefaultSearchPath(kubeconfig)
126+
apiConfig, err := newApiConfigForKubeconfig(kubeconfig)
126127
if err != nil {
127128
return nil, err
128129
}
129-
return newRestConfig(apiConfig)
130+
return newRestConfig(apiConfig, clientcmd.ConfigOverrides{})
130131
}
131132

132133
// newApiConfigForDefaultSearchPath creates an api.Config by searching for the kubeconfig on the default search path. If an override 'kubeconfigPath' is

tools/repair/util/repair.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ func NewRepairer(dryRun bool, configPath string) (*repairer, error) {
3737
configPath = util.GetDefaultKubeConfigPath()
3838
}
3939

40-
c, err := clientcmd.NewClusterApiClientForDefaultSearchPath(configPath)
40+
c, err := clientcmd.NewClusterApiClientForDefaultSearchPath(configPath, clientcmd.NewConfigOverrides())
4141
if err != nil {
4242
return nil, err
4343
}

tools/upgrader/util/upgrade.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ func initClient(kubeconfig string) error {
4141
if kubeconfig == "" {
4242
kubeconfig = util.GetDefaultKubeConfigPath()
4343
}
44-
coreClientset, clusterapiClientset, err := clientcmd.NewClientsForDefaultSearchpath(kubeconfig)
44+
coreClientset, clusterapiClientset, err := clientcmd.NewClientsForDefaultSearchpath(kubeconfig, clientcmd.NewConfigOverrides())
4545
if err != nil {
4646
glog.Fatalf("Error creating rest config: %v", err)
4747
return err

0 commit comments

Comments
 (0)