Skip to content

Commit

Permalink
Plumb addon support into clusterctl.
Browse files Browse the repository at this point in the history
  • Loading branch information
roberthbailey committed Jun 21, 2018
1 parent 76577fd commit 4d23453
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 22 deletions.
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
12 changes: 9 additions & 3 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 Down Expand Up @@ -78,30 +79,35 @@ func RunCreate(co *CreateOptions) error {
if err != nil {
return err
}
ac, err := ioutil.ReadFile(co.AddonComponents)
if err != nil {
return 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"

0 comments on commit 4d23453

Please sign in to comment.