|
| 1 | +# Adding support for a new provider |
| 2 | + |
| 3 | +Steps to be followed while implementing a new (hyperscale) provider are mentioned below. This is the easiest way to add a new provider support using a blueprint code. |
| 4 | + |
| 5 | +However, you may also develop your machine controller from scratch which would provide you more flexibility. However make sure that your custom machine controller adhere's to the `Machine.Status` struct defined in the [MachineAPIs](/pkg/apis/machine/types.go) to make sure the MCM is able to act with higher level controllers like MachineSet and MachineDeployment controller. The key is the `Machine.Status.CurrentStatus.Phase` key that indicates the status of the machine object. |
| 6 | + |
| 7 | +Our strong recommendation would be to follow the steps below as this provides most flexibility required to support machine management for adding new providers. And if you feel to extend the functionality feel free to update our [machine controller libraries](/pkg/util/provider). |
| 8 | + |
| 9 | +## Setting up your repository |
| 10 | + |
| 11 | +1. Create a new empty repository named `machine-controller-manager-provider-{provider-name}` on github username/project. Do not initialize this repository with a README. |
| 12 | +1. Copy the remote repository `URL` (HTTPS/SSH) to this repository which is displayed once you create this repository. |
| 13 | +1. Now on your local system, create directories as required. {your-github-username} given below could also be {github-project} depending on where you have created the new repository. |
| 14 | + ```bash |
| 15 | + mkdir -p $GOPATH/src/github.com/{your-github-username} |
| 16 | + ``` |
| 17 | +1. Navigate to this created directory. |
| 18 | + ```bash |
| 19 | + cd $GOPATH/src/github.com/{your-github-username} |
| 20 | + ``` |
| 21 | +1. Clone [this repository](https://github.com/gardener/machine-controller-manager-provider-sampleprovider) on your local machine. |
| 22 | + ```bash |
| 23 | + git clone git@github.com:gardener/machine-controller-manager-provider-sampleprovider.git |
| 24 | + ``` |
| 25 | +1. Rename the directory from `machine-controller-manager-provider-sampleprovider` to `machine-controller-manager-provider-{provider-name}`. |
| 26 | + ```bash |
| 27 | + mv machine-controller-manager-provider-sampleprovider machine-controller-manager-provider-{provider-name} |
| 28 | + ``` |
| 29 | +1. Navigate into the newly created directory. |
| 30 | + ```bash |
| 31 | + cd machine-controller-manager-provider-{provider-name} |
| 32 | + ``` |
| 33 | +1. Update the remote `origin` URL to the newly created repository's URL you had copied above. |
| 34 | + ```bash |
| 35 | + git remote set-url origin git@github.com:{your-github-username}/machine-controller-manager-provider-{provider-name}.git |
| 36 | + ``` |
| 37 | +1. Rename github project from `gardener` to `{github-org/your-github-username}` where ever you have cloned the repository above. Use the hack script given below to do the same. |
| 38 | + ```bash |
| 39 | + make rename-project PROJECT_NAME={github-org/your-github-username} |
| 40 | + eg: |
| 41 | + make rename-project PROJECT_NAME=gardener (or) |
| 42 | + make rename-project PROJECT_NAME=githubusername |
| 43 | + ``` |
| 44 | +1. Rename all files and code from `SampleProvider` to your desired `{provider-name}`. Use the hack script given below to do the same. {provider-name} is case sensitive. |
| 45 | + ```bash |
| 46 | + make rename-provider PROVIDER_NAME={provider-name} |
| 47 | + eg: |
| 48 | + make rename-provider PROVIDER_NAME=AmazonWebServices (or) |
| 49 | + make rename-provider PROVIDER_NAME=AWS |
| 50 | + ``` |
| 51 | +1. Now commit your changes and push it upstream. |
| 52 | + ```bash |
| 53 | + git add -A |
| 54 | + git commit -m "Renamed SampleProvide to {provider-name}" |
| 55 | + git push origin master |
| 56 | + ``` |
| 57 | +
|
| 58 | +## Code changes required |
| 59 | +
|
| 60 | +The contract between he Machine Controller Manager (MCM) and the Machine Controller (MC) AKA driver has been [documented here](machine_error_codes.md) and the [machine error codes can be found here](/pkg/util/provider/machinecodes/codes/codes.go). You may refer to them for any queries. |
| 61 | +
|
| 62 | +:warning: |
| 63 | +- Keep in mind that, **there should to be a unique way to map between machine objects and VMs**. This can be done by mapping machine object names with VM-Name/ tags/ other metadata. |
| 64 | +- Optionally there should also be a unique way to map a VM to it's machine class object. This can be done by tagging VM objects with tags/resource-groups associated with the machine class. |
| 65 | + |
| 66 | +#### Steps to integrate |
| 67 | + |
| 68 | +1. Update the `pkg/provider/apis/provider_spec.go` specification file to reflect the structure of the `ProviderSpec` blob. It typically contains the machine template details in the `MachineClass` object. Follow the sample spec provided already in the file. A sample provider specification can be found [here](https://github.com/gardener/machine-controller-manager-provider-aws/blob/master/pkg/aws/apis/aws_provider_spec.go). |
| 69 | +1. Fill in the methods described at `pkg/provider/core.go` to manage VMs on your cloud provider. Comments are provided above each method to help you fill them up with desired `REQUEST` and `RESPONSE` parameters. |
| 70 | + - A sample provider implementation for these methods can be found [here](https://github.com/gardener/machine-controller-manager-provider-aws/blob/master/pkg/aws/core.go). |
| 71 | + - Fill in the required methods `CreateMachine()`, and `DeleteMachine()` methods. |
| 72 | + - Optionally fill in methods like `GetMachineStatus()`, `ListMachines()`, and `GetVolumeIDs()`. You may choose to fill these, once the working of the required methods seem to be working. |
| 73 | + - `GetVolumeIDs()` expects VolumeIDs to be decoded from the volumeSpec based on the cloud provider. |
| 74 | +1. Perform validation of APIs that you have described and make it a part of your methods as required at each requests. |
| 75 | +1. Write unit tests to make it work with your implementation by running `make test`. |
| 76 | + ```bash |
| 77 | + make test |
| 78 | + ``` |
| 79 | +1. Re-generate the vendors, to update any new vendors imported. |
| 80 | + ```bash |
| 81 | + make revendor |
| 82 | + ``` |
| 83 | +1. Update the sample YAML files on `kubernetes/` directory to provide sample files through which the working of the machine controller can be tested. |
| 84 | +1. Update `README.md` to reflect any additional changes |
| 85 | + |
| 86 | +## Testing your code changes |
| 87 | + |
| 88 | +Make sure `$TARGET_KUBECONFIG` points to the cluster where you wish to manage machines. `$CONTROL_NAMESPACE` represents the namespaces where MCM is looking for machine CR objects, and `$CONTROL_KUBECONFIG` points to the cluster which holds these machine CRs. |
| 89 | + |
| 90 | +1. On the first terminal running at `$GOPATH/src/github.com/{github-org/your-github-username}/machine-controller-manager-provider-{provider-name}`, |
| 91 | + - Run the machine controller (driver) using the command below. |
| 92 | + ```bash |
| 93 | + make start |
| 94 | + ``` |
| 95 | +1. On the second terminal pointing to `$GOPATH/src/github.com/gardener`, |
| 96 | + - Clone the [latest MCM code](https://github.com/gardener/machine-controller-manager) |
| 97 | + ```bash |
| 98 | + git clone git@github.com:gardener/machine-controller-manager.git |
| 99 | + ``` |
| 100 | + - Navigate to the newly created directory. |
| 101 | + ```bash |
| 102 | + cd machine-controller-manager |
| 103 | + ``` |
| 104 | + - Deploy the required CRDs from the machine-controller-manager repo, |
| 105 | + ```bash |
| 106 | + kubectl apply -f kubernetes/crds.yaml |
| 107 | + ``` |
| 108 | + - Run the machine-controller-manager in the `cmi-client` branch |
| 109 | + ```bash |
| 110 | + make start |
| 111 | + ``` |
| 112 | +1. On the third terminal pointing to `$GOPATH/src/github.com/{github-org/your-github-username}/machine-controller-manager-provider-{provider-name}` |
| 113 | + - Fill in the object files given below and deploy them as described below. |
| 114 | + - Deploy the `machine-class` |
| 115 | + ```bash |
| 116 | + kubectl apply -f kubernetes/machine-class.yaml |
| 117 | + ``` |
| 118 | + - Deploy the `kubernetes secret` if required. |
| 119 | + ```bash |
| 120 | + kubectl apply -f kubernetes/secret.yaml |
| 121 | + ``` |
| 122 | + - Deploy the `machine` object and make sure it joins the cluster successfully. |
| 123 | + ```bash |
| 124 | + kubectl apply -f kubernetes/machine.yaml |
| 125 | + ``` |
| 126 | + - Once machine joins, you can test by deploying a machine-deployment. |
| 127 | + - Deploy the `machine-deployment` object and make sure it joins the cluster successfully. |
| 128 | + ```bash |
| 129 | + kubectl apply -f kubernetes/machine-deployment.yaml |
| 130 | + ``` |
| 131 | + - Make sure to delete both the `machine` and `machine-deployment` object after use. |
| 132 | + ```bash |
| 133 | + kubectl delete -f kubernetes/machine.yaml |
| 134 | + kubectl delete -f kubernetes/machine-deployment.yaml |
| 135 | + ``` |
| 136 | + |
| 137 | +## Releasing your docker image |
| 138 | + |
| 139 | +1. Make sure you have logged into gcloud/docker using the CLI. |
| 140 | +2. To release your docker image, run the following. |
| 141 | +```bash |
| 142 | + make release IMAGE_REPOSITORY=<link-to-image-repo> |
| 143 | +``` |
| 144 | +3. A sample kubernetes deploy file can be found at `kubernetes/deployment.yaml`. Update the same (with your desired MCM and MC images) to deploy your MCM pod. |
0 commit comments