diff --git a/cmd/clusterctl/clusterdeployer/clusterdeployer.go b/cmd/clusterctl/clusterdeployer/clusterdeployer.go index 66509685f872..72faf9d33a93 100644 --- a/cmd/clusterctl/clusterdeployer/clusterdeployer.go +++ b/cmd/clusterctl/clusterdeployer/clusterdeployer.go @@ -102,18 +102,12 @@ func (d *ClusterDeployer) Create(cluster *clusterv1.Cluster, machines []*cluster return fmt.Errorf("unable to create cluster %q in bootstrap cluster: %v", cluster.Name, err) } - // Create initial controlplane instance if cluster.Namespace == "" { cluster.Namespace = bootstrapClient.GetContextNamespace() } - err = bootstrapClient.EnsureNamespace(cluster.Namespace) - if err != nil { - return fmt.Errorf("unable to ensure namespace %q in bootstrap cluster: %v", cluster.Namespace, err) - } - glog.Infof("Creating master %v in namespace %q", master.Name, cluster.Namespace) - if err := bootstrapClient.CreateMachineObjects([]*clusterv1.Machine{master}, cluster.Namespace); err != nil { + if err := phases.ApplyMachines(bootstrapClient, cluster.Namespace, []*clusterv1.Machine{master}); err != nil { return fmt.Errorf("unable to create master machine: %v", err) } @@ -160,7 +154,7 @@ func (d *ClusterDeployer) Create(cluster *clusterv1.Cluster, machines []*cluster } glog.Info("Creating node machines in target cluster.") - if err := targetClient.CreateMachineObjects(nodes, cluster.Namespace); err != nil { + if err := phases.ApplyMachines(bootstrapClient, cluster.Namespace, nodes); err != nil { return fmt.Errorf("unable to create node machines: %v", err) } diff --git a/cmd/clusterctl/cmd/alpha_phase_apply_machines.go b/cmd/clusterctl/cmd/alpha_phase_apply_machines.go new file mode 100644 index 000000000000..b7bb0e224cd6 --- /dev/null +++ b/cmd/clusterctl/cmd/alpha_phase_apply_machines.go @@ -0,0 +1,89 @@ +/* +Copyright 2018 The Kubernetes 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. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cmd + +import ( + "fmt" + "io/ioutil" + + "github.com/golang/glog" + "github.com/spf13/cobra" + "sigs.k8s.io/cluster-api/cmd/clusterctl/clusterdeployer/clusterclient" + "sigs.k8s.io/cluster-api/cmd/clusterctl/phases" + "sigs.k8s.io/cluster-api/pkg/util" +) + +type AlphaPhaseApplyMachinesOptions struct { + Kubeconfig string + Machines string + Namespace string +} + +var pamo = &AlphaPhaseApplyMachinesOptions{} + +var alphaPhaseApplyMachinesCmd = &cobra.Command{ + Use: "apply-machines", + Short: "Apply Machines", + Long: `Apply Machines`, + Run: func(cmd *cobra.Command, args []string) { + if pamo.Machines == "" { + exitWithHelp(cmd, "Please provide yaml file for machines definition.") + } + + if pamo.Kubeconfig == "" { + exitWithHelp(cmd, "Please provide a kubeconfig file.") + } + + if err := RunAlphaPhaseApplyMachines(pamo); err != nil { + glog.Exit(err) + } + }, +} + +func RunAlphaPhaseApplyMachines(pamo *AlphaPhaseApplyMachinesOptions) error { + kubeconfig, err := ioutil.ReadFile(pamo.Kubeconfig) + if err != nil { + return err + } + + machines, err := util.ParseMachinesYaml(pamo.Machines) + if err != nil { + return err + } + + clientFactory := clusterclient.NewFactory() + client, err := clientFactory.NewClientFromKubeconfig(string(kubeconfig)) + if err != nil { + return fmt.Errorf("unable to create cluster client: %v", err) + } + + if err := phases.ApplyMachines(client, pamo.Namespace, machines); err != nil { + return fmt.Errorf("unable to apply machines: %v", err) + } + + return nil +} + +func init() { + // Required flags + alphaPhaseApplyMachinesCmd.Flags().StringVarP(&pamo.Kubeconfig, "kubeconfig", "", "", "Path for the kubeconfig file to use") + alphaPhaseApplyMachinesCmd.Flags().StringVarP(&pamo.Machines, "machines", "m", "", "A yaml file containing machine object definitions") + + // Optional flags + alphaPhaseApplyMachinesCmd.Flags().StringVarP(&pamo.Namespace, "namespace", "n", "", "Namespace") + alphaPhasesCmd.AddCommand(alphaPhaseApplyMachinesCmd) +} diff --git a/cmd/clusterctl/phases/applymachines.go b/cmd/clusterctl/phases/applymachines.go new file mode 100644 index 000000000000..b14e362af3a0 --- /dev/null +++ b/cmd/clusterctl/phases/applymachines.go @@ -0,0 +1,43 @@ +/* +Copyright 2018 The Kubernetes 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. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package phases + +import ( + "fmt" + + "github.com/golang/glog" + "sigs.k8s.io/cluster-api/cmd/clusterctl/clusterdeployer/clusterclient" + clusterv1 "sigs.k8s.io/cluster-api/pkg/apis/cluster/v1alpha1" +) + +func ApplyMachines(client clusterclient.Client, namespace string, machines []*clusterv1.Machine) error { + if namespace == "" { + namespace = client.GetContextNamespace() + } + + err := client.EnsureNamespace(namespace) + if err != nil { + return fmt.Errorf("unable to ensure namespace %q: %v", namespace, err) + } + + glog.Infof("Creating machines in namespace %q", namespace) + if err := client.CreateMachineObjects(machines, namespace); err != nil { + return err + } + + return nil +}