Skip to content

Commit

Permalink
add more documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
liztio committed Nov 14, 2019
1 parent c35c95e commit f7c5d60
Show file tree
Hide file tree
Showing 4 changed files with 218 additions and 62 deletions.
85 changes: 25 additions & 60 deletions docs/book/provider_implementations/building_running_and_testing.md
Original file line number Diff line number Diff line change
@@ -1,60 +1,25 @@
# Building

## Fixup Makefile to include common Cluster API CRDs

Apply the following patch:

```bash
diff --git a/Makefile b/Makefile
index ac12c7e..cf44312 100644
--- a/Makefile
+++ b/Makefile
@@ -22,12 +22,15 @@ install: manifests

# Deploy controller in the configured Kubernetes cluster in ~/.kube/config
deploy: manifests
- kubectl apply -f config/crds
- kustomize build config/default | kubectl apply -f -
+ cat provider-components.yaml | kubectl apply -f -

# Generate manifests e.g. CRD, RBAC etc.
manifests:
go run vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go all
+ sed -i'' -e 's@^- manager_auth_proxy_patch.yaml.*@#&@' config/default/kustomization.yaml
+ kustomize build config/default/ > provider-components.yaml
+ echo "---" >> provider-components.yaml
+ kustomize build vendor/sigs.k8s.io/cluster-api/config/default/ >> provider-components.yaml

# Run go fmt against code
fmt:
```

## Build and push images

Determine a location to upload your container and then build and push it:

```bash
export IMG=<your-docker-registry>/cluster-api-provider-solas
dep ensure
make
make docker-build IMG=${IMG}
make docker-push IMG=${IMG}
```

## Start minikube and deploy the provider

```bash
minikube start
make deploy
```

## Verify deployment

**TODO**: Should deploy a sample `Cluster` and `Machine` resource to verify
controllers are reconciling properly. This is troublesome however since before
the actuator stubs are filled in, all we will see are messages to the effect of
"TODO: Not yet implemented"..."

```bash
kubectl logs cluster-api-provider-solas-controller-manager-0 -n cluster-api-provider-solas-system
```
# Building, Running, Testing

## Docker Image Name

The patch in `config/default/manager_image_patch.yaml` will be applied to the manager pod.
Right now there is a placeholder `IMAGE_URL`, which you will need to change to your actual image.

{% hint style="info" %}
Development Images: It's likely that you will want one location and tag for release development, and another during development.

The approach most Cluster API projects is using [a `Makefile` that uses `sed` to replace the image URL][sed] on demand during development.
[sed]: https://github.com/kubernetes-sigs/cluster-api/blob/e0fb83a839b2755b14fbefbe6f93db9a58c76952/Makefile#L201-L204
{% endhint %}

## Deployment

Before you can deploy the infrastructure controller, you'll need to deploy Cluster API itself.

You can clone `cluster-api` for the latest version, or just [use a precompiled manifest][install].

[install]: https://cluster-api.sigs.k8s.io/tasks/installation.html#install-cluster-api




122 changes: 122 additions & 0 deletions docs/book/provider_implementations/configure_and_deploy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Configure and Deploy

## YAML

`kubebuilder` generates most of the YAML you'll need to deploy a container.
We just need to modify it to add our new secrets.

First, let's add our secret as a [patch] to the manager yaml.

`config/default/manager_config.yaml`:

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
spec:
template:
spec:
containers:
- name: manager
env:
- name: MAILGUN_API_KEY
valueFrom:
secretKeyRef:
name: mailgun-secret
key: api_key
- name: MAILGUN_DOMAIN
valueFrom:
configMapKeyRef:
name: mailgun-config
key: mailgun_domain
- name: MAIL_RECIPIENT
valueFrom:
configMapKeyRef:
name: mailgun-config
key: mail_recipient
```
And then, we have to add that patch to [`config/default/kustomization.yaml`][kustomizeyaml]:

```yaml
patchesStrategicMerge
- manager_image_patch.yaml
# Protect the /metrics endpoint by putting it behind auth.
# Only one of manager_auth_proxy_patch.yaml and
# manager_prometheus_metrics_patch.yaml should be enabled.
- manager_auth_proxy_patch.yaml
# If you want your controller-manager to expose the /metrics
# endpoint w/o any authn/z, uncomment the following line and
# comment manager_auth_proxy_patch.yaml.
# Only one of manager_auth_proxy_patch.yaml and
# manager_prometheus_metrics_patch.yaml should be enabled.
- manager_config.yaml
```

[kustomizeyaml]: https://github.com/kubernetes-sigs/kustomize/blob/master/docs/glossary.md#kustomization
[patch]: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md

## Our configuration

There's many ways to manage configuration in production.
The convention many Cluster-API projects use is enviroment variables.

`config/manager/configuration.yaml`

```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: mailgun-config
namespace: system
type: Opaque
stringData:
api_key: ${MAILGUN_API_KEY}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: mailgun-config
namespace: system
data:
mailgun_domain: ${MAILGUN_DOMAIN}
mail_recipient: ${MAILGUN_RECIPIENT}
```

And add this to `config/manager/kustomization.yaml`

```yaml
resources:
- manager.yaml
- credentials.yaml
```

You can now (hopefully) generate your yaml!

```
kustomize build config/default
```
## EnvSubst
{% hint style="info" %}
A tool like [direnv](https://direnv.net/) can be used to help manage enviroment variables.
{% endhint %}
`kustomize` does not handle replacing those `${VARIABLES}` with actual values.
For that, we use [`envsubst`][envsubst].
You'll need to have those environment variables (`MAILGUN_API_KEY`, `MAILGUN_DOMAIN`, `MAILGUN_RECIPIENT`) in your environment when you generate the final yaml file.
Then we call envsubst in line, like so:
```
kustomize build config/default | envsubst
```
[envsubst]: https://linux.die.net/man/1/envsubst
2 changes: 1 addition & 1 deletion docs/book/provider_implementations/create_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ type MailgunClusterStatus struct {
}
```

As the deleted comments request, rune `make` to regenerate some of the generated data files afterwards.
As the deleted comments request, run `make manager manifests` to regenerate some of the generated data files afterwards.

```bash
git add .
Expand Down
71 changes: 70 additions & 1 deletion docs/book/provider_implementations/populate_controllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,21 @@ if err != nil {
}
```

{% hint style="warning" %}
*client-go versions*
At the time this document was written, `kubebuilder` pulls `client-go` version `1.14.1` into `go.mod` (it looks like `k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible`).

If you encounter an error when compiling like:

```
../pkg/mod/k8s.io/[email protected]+incompatible/rest/request.go:598:31: not enough arguments in call to watch.NewStreamWatcher
have (*versioned.Decoder)
want (watch.Decoder, watch.Reporter)`
```

You may need to bump `client-go`. At time of writing, that means `1.15`, which looks like: `k8s.io/client-go v11.0.1-0.20190409021438-1a26190bd76a+incompatible`.
{% endhint %}

## The fun part

{% hint style="info" %}
Expand Down Expand Up @@ -141,7 +156,7 @@ if mgCluster.Status.MessageID != nil {
}
subject := fmt.Sprintf("[%s] New Cluster %s requested", mgCluster.Spec.Priority, cluster.Name)
body := fmt.Sprint("Hello! One cluster please.\n\n%s\n", mgCluster.Spec.Request)
body := fmt.Sprintf("Hello! One cluster please.\n\n%s\n", mgCluster.Spec.Request)
msg := mailgun.NewMessage(mgCluster.Spec.Requester, subject, body, r.Recipient)
_, msgID, err := r.Mailgun.Send(msg)
Expand All @@ -157,3 +172,57 @@ r.Update(ctx, &mgCluster)
[cluster]: https://godoc.org/sigs.k8s.io/cluster-api/api/v1alpha3#Cluster
[getowner]: https://godoc.org/sigs.k8s.io/cluster-api/util#GetOwnerMachine
[idempotent]: https://stackoverflow.com/questions/1077412/what-is-an-idempotent-operation

## Update `main.go` with your new fields

If you added fields to your reconciler, you'll need to update `main.go`.

Right now, it probably looks like this:

```go
if err = (&controllers.MailgunClusterReconciler{
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controllers").WithName("MailgunCluster"),
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "MailgunCluster")
os.Exit(1)
}
```

Let's add our configuration.
We're going to use environment variables for this:

```go
domain := os.Getenv("MAILGUN_DOMAIN")
if domain == "" {
setupLog.Info("missing required env MAILGUN_DOMAIN")
os.Exit(1)
}

apiKey := os.Getenv("MAILGUN_API_KEY")
if apiKey == "" {
setupLog.Info("missing required env MAILGUN_API_KEY")
os.Exit(1)
}

recipient := os.Getenv("MAIL_RECIPIENT")
if recipient == "" {
setupLog.Info("missing required env MAIL_RECIPIENT")
os.Exit(1)
}

mg := mailgun.NewMailgun(domain, apiKey)

if err = (&controllers.MailgunClusterReconciler{
Client: mgr.GetClient(),
Log: ctrl.Log.WithName("controllers").WithName("MailgunCluster"),
Mailgun: mg,
Recipient: recipient,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "MailgunCluster")
os.Exit(1)
}
```

If you have some other state, you'll want to initialize it here!

0 comments on commit f7c5d60

Please sign in to comment.