Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plumb addon support into clusterctl. #376

Merged
merged 1 commit into from
Jun 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions clusterctl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ $ go build
TBD

### Creating a cluster
1. Create a `cluster.yaml`, `machines.yaml` and `provider-components.yaml` files configured for your cluster. See the provider specific templates and generation tools at `$GOPATH/src/sigs.k8s.io/cluster-api/clusterctl/examples/<provider>`.
1. Create the `cluster.yaml`, `machines.yaml`, `provider-components.yaml`, and `addons.yaml` files configured for your cluster. See the provider specific templates and generation tools at `$GOPATH/src/sigs.k8s.io/cluster-api/clusterctl/examples/<provider>`.
2. Create a cluster

```shell
clusterctl create cluster --provider [google/vsphere] -c cluster.yaml -m machines.yaml -p provider-components.yaml
clusterctl create cluster --provider [google/vsphere] -c cluster.yaml -m machines.yaml -p provider-components.yaml -a addons.yaml
```

To choose a specific minikube driver, please use the `--vm-driver` command line parameter. For example to use the kvm2 driver with clusterctl you woud add `--vm-driver kvm2`
Expand Down
29 changes: 15 additions & 14 deletions clusterctl/clusterdeployer/clusterdeployer.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ type ClusterDeployer struct {
clientFactory ClientFactory
provider ProviderDeployer
providerComponents string
addonComponents string
kubeconfigOutput string
cleanupExternalCluster bool
}
Expand All @@ -84,13 +85,15 @@ func New(
clientFactory ClientFactory,
provider ProviderDeployer,
providerComponents string,
addonComponents string,
kubeconfigOutput string,
cleanupExternalCluster bool) *ClusterDeployer {
return &ClusterDeployer{
externalProvisioner: externalProvisioner,
clientFactory: clientFactory,
provider: provider,
providerComponents: providerComponents,
addonComponents: addonComponents,
kubeconfigOutput: kubeconfigOutput,
cleanupExternalCluster: cleanupExternalCluster,
}
Expand All @@ -117,28 +120,24 @@ func (d *ClusterDeployer) Create(cluster *clusterv1.Cluster, machines []*cluster
}()

glog.Info("Applying Cluster API stack to external cluster")
err = d.applyClusterAPIStack(externalClient)
if err != nil {
if err := d.applyClusterAPIStack(externalClient); err != nil {
return fmt.Errorf("unable to apply cluster api stack to external cluster: %v", err)
}

glog.Info("Provisioning internal cluster via external cluster")

glog.Infof("Creating cluster object %v on external cluster", cluster.Name)
err = externalClient.CreateClusterObject(cluster)
if err != nil {
if err := externalClient.CreateClusterObject(cluster); err != nil {
return fmt.Errorf("unable to create cluster object: %v", err)
}

glog.Infof("Creating master %v", master.Name)
err = externalClient.CreateMachineObjects([]*clusterv1.Machine{master})
if err != nil {
if err := externalClient.CreateMachineObjects([]*clusterv1.Machine{master}); err != nil {
return fmt.Errorf("unable to create master machine: %v", err)
}

glog.Infof("Updating external cluster object with master (%s) endpoint", master.Name)
err = d.updateClusterEndpoint(externalClient)
if err != nil {
if err := d.updateClusterEndpoint(externalClient); err != nil {
return fmt.Errorf("unable to update external cluster endpoint: %v", err)
}

Expand All @@ -155,8 +154,7 @@ func (d *ClusterDeployer) Create(cluster *clusterv1.Cluster, machines []*cluster
}()

glog.Info("Applying Cluster API stack to internal cluster")
err = d.applyClusterAPIStackWithPivoting(internalClient, externalClient)
if err != nil {
if err := d.applyClusterAPIStackWithPivoting(internalClient, externalClient); err != nil {
return fmt.Errorf("unable to apply cluster api stack to internal cluster: %v", err)
}

Expand All @@ -169,17 +167,20 @@ func (d *ClusterDeployer) Create(cluster *clusterv1.Cluster, machines []*cluster
// For some reason, endpoint doesn't get updated in external cluster sometimes. So we
// update the internal cluster endpoint as well to be sure.
glog.Infof("Updating internal cluster object with master (%s) endpoint", master.Name)
err = d.updateClusterEndpoint(internalClient)
if err != nil {
if err := d.updateClusterEndpoint(internalClient); err != nil {
return fmt.Errorf("unable to update internal cluster endpoint: %v", err)
}

glog.Info("Creating node machines in internal cluster.")
err = internalClient.CreateMachineObjects(nodes)
if err != nil {
if err := internalClient.CreateMachineObjects(nodes); err != nil {
return fmt.Errorf("unable to create node machines: %v", err)
}

glog.Info("Creating addons in internal cluster.")
if err := internalClient.Apply(d.addonComponents); err != nil {
return fmt.Errorf("unable to apply addons: %v", err)
}

glog.Infof("Done provisioning cluster. You can now access your cluster with kubectl --kubeconfig %v", d.kubeconfigOutput)

return nil
Expand Down
5 changes: 3 additions & 2 deletions clusterctl/clusterdeployer/clusterdeployer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ func TestCreate(t *testing.T) {
inputMachines := generateMachines()
pcStore := mockProviderComponentsStore{}
pcFactory := mockProviderComponentsStoreFactory{NewFromCoreclientsetPCStore: &pcStore}
d := clusterdeployer.New(p, f, pd, "", kubeconfigOut, testcase.cleanupExternal)
d := clusterdeployer.New(p, f, pd, "", "", kubeconfigOut, testcase.cleanupExternal)
err := d.Create(inputCluster, inputMachines, &pcFactory)

// Validate
Expand Down Expand Up @@ -410,7 +410,8 @@ func TestCreateProviderComponentsScenarios(t *testing.T) {
inputMachines := generateMachines()
pcFactory := mockProviderComponentsStoreFactory{NewFromCoreclientsetPCStore: &tc.pcStore}
providerComponentsYaml := "-yaml\ndefinition"
d := clusterdeployer.New(p, f, pd, providerComponentsYaml, kubeconfigOut, false)
addonsYaml := "-yaml\ndefinition"
d := clusterdeployer.New(p, f, pd, providerComponentsYaml, addonsYaml, kubeconfigOut, false)
err := d.Create(inputCluster, inputMachines, &pcFactory)
if err == nil && tc.expectedError != "" {
t.Fatalf("error mismatch: got '%v', want '%v'", err, tc.expectedError)
Expand Down
20 changes: 16 additions & 4 deletions clusterctl/cmd/create_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type CreateOptions struct {
Cluster string
Machine string
ProviderComponents string
AddonComponents string
CleanupExternalCluster bool
VmDriver string
Provider string
Expand All @@ -53,6 +54,12 @@ var createClusterCmd = &cobra.Command{
if co.Machine == "" {
exitWithHelp(cmd, "Please provide yaml file for machine definition.")
}
if co.ProviderComponents == "" {
exitWithHelp(cmd, "Please provide yaml file for provider component definition.")
}
if co.AddonComponents == "" {
exitWithHelp(cmd, "Please provide yaml file for addon component definition.")
}
if err := RunCreate(co); err != nil {
glog.Exit(err)
}
Expand All @@ -76,32 +83,37 @@ func RunCreate(co *CreateOptions) error {
}
pc, err := ioutil.ReadFile(co.ProviderComponents)
if err != nil {
return err
return fmt.Errorf("error loading provider components file '%v': %v", co.ProviderComponents, err)
}
ac, err := ioutil.ReadFile(co.AddonComponents)
if err != nil {
return fmt.Errorf("error loading addons file '%v': %v", co.AddonComponents, err)
}
pcsFactory := clusterdeployer.NewProviderComponentsStoreFactory()
d := clusterdeployer.New(
mini,
clusterdeployer.NewClientFactory(),
pd,
string(pc),
string(ac),
co.KubeconfigOutput,
co.CleanupExternalCluster)
err = d.Create(c, m, pcsFactory)
return err
return d.Create(c, m, pcsFactory)
}

func init() {
// Required flags
createClusterCmd.Flags().StringVarP(&co.Cluster, "cluster", "c", "", "A yaml file containing cluster object definition")
createClusterCmd.Flags().StringVarP(&co.Machine, "machines", "m", "", "A yaml file containing machine object definition(s)")
createClusterCmd.Flags().StringVarP(&co.ProviderComponents, "provider-components", "p", "", "A yaml file containing cluster api provider controllers and supporting objects")
createClusterCmd.Flags().StringVarP(&co.AddonComponents, "addon-components", "a", "", "A yaml file containing cluster addons to apply to the internal cluster")
// TODO: Remove as soon as code allows https://github.com/kubernetes-sigs/cluster-api/issues/157
createClusterCmd.Flags().StringVarP(&co.Provider, "provider", "", "", "Which provider deployment logic to use (google/vsphere)")

// Optional flags
createClusterCmd.Flags().BoolVarP(&co.CleanupExternalCluster, "cleanup-external-cluster", "", true, "Whether to cleanup the external cluster after bootstrap")
createClusterCmd.Flags().StringVarP(&co.VmDriver, "vm-driver", "", "", "Which vm driver to use for minikube")
createClusterCmd.Flags().StringVarP(&co.KubeconfigOutput, "kubeconfig-out", "", "kubeconfig", "where to output the kubeconfig for the provisioned cluster.")
createClusterCmd.Flags().StringVarP(&co.KubeconfigOutput, "kubeconfig-out", "", "kubeconfig", "Where to output the kubeconfig for the provisioned cluster")

createCmd.AddCommand(createClusterCmd)
}
Expand Down
9 changes: 9 additions & 0 deletions clusterctl/examples/vsphere/addons.yaml.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: standard
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: kubernetes.io/vsphere-volume
parameters:
datastore: ""
2 changes: 1 addition & 1 deletion clusterctl/examples/vsphere/generate-yaml.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,4 @@ cat $PROVIDERCOMPONENT_TEMPLATE_FILE \
> $PROVIDERCOMPONENT_GENERATED_FILE

echo "Done generating $PROVIDERCOMPONENT_GENERATED_FILE"
echo "You will still need to generate the cluster.yaml and machines.yaml"
echo "You will still need to generate the cluster.yaml, machines.yaml, and addons.yaml configuration files"
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ Usage:
clusterctl create cluster [flags]

Flags:
-a, --addon-components string A yaml file containing cluster addons to apply to the internal cluster
--cleanup-external-cluster Whether to cleanup the external cluster after bootstrap (default true)
-c, --cluster string A yaml file containing cluster object definition
-h, --help help for cluster
--kubeconfig-out string where to output the kubeconfig for the provisioned cluster. (default "kubeconfig")
--kubeconfig-out string Where to output the kubeconfig for the provisioned cluster (default "kubeconfig")
-m, --machines string A yaml file containing machine object definition(s)
--provider string Which provider deployment logic to use (google/vsphere)
-p, --provider-components string A yaml file containing cluster api provider controllers and supporting objects
Expand Down
3 changes: 2 additions & 1 deletion clusterctl/testdata/create-cluster-no-args.golden
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ Usage:
clusterctl create cluster [flags]

Flags:
-a, --addon-components string A yaml file containing cluster addons to apply to the internal cluster
--cleanup-external-cluster Whether to cleanup the external cluster after bootstrap (default true)
-c, --cluster string A yaml file containing cluster object definition
-h, --help help for cluster
--kubeconfig-out string where to output the kubeconfig for the provisioned cluster. (default "kubeconfig")
--kubeconfig-out string Where to output the kubeconfig for the provisioned cluster (default "kubeconfig")
-m, --machines string A yaml file containing machine object definition(s)
--provider string Which provider deployment logic to use (google/vsphere)
-p, --provider-components string A yaml file containing cluster api provider controllers and supporting objects
Expand Down