|
| 1 | +// Module included in the following assemblies: |
| 2 | +// |
| 3 | +// * operators/operator_sdk/ansible/osdk-ansible-inside-operator.adoc |
| 4 | + |
| 5 | +[id="osdk-ansible-inside-operator-local_{context}"] |
| 6 | += Testing an Ansible-based Operator locally |
| 7 | + |
| 8 | +You can test the logic inside of an Ansible-based Operator running locally by using the `make run` command from the top-level directory of your Operator project. The `make run` Makefile target runs the `ansible-operator` binary locally, which reads from the `watches.yaml` file and uses your `~/.kube/config` file to communicate with a Kubernetes cluster just as the `k8s` modules do. |
| 9 | + |
| 10 | +[NOTE] |
| 11 | +==== |
| 12 | +You can customize the roles path by setting the environment variable `ANSIBLE_ROLES_PATH` or by using the `ansible-roles-path` flag. If the role is not found in the `ANSIBLE_ROLES_PATH` value, the Operator looks for it in `{{current directory}}/roles`. |
| 13 | +==== |
| 14 | + |
| 15 | +.Prerequisites |
| 16 | + |
| 17 | +- link:https://ansible-runner.readthedocs.io/en/latest/install.html[Ansible Runner] version v1.1.0+ |
| 18 | +- link:https://github.com/ansible/ansible-runner-http[Ansible Runner HTTP Event Emitter plug-in] version v1.0.0+ |
| 19 | +- Performed the previous steps for testing the Kubernetes Collection locally |
| 20 | + |
| 21 | +.Procedure |
| 22 | + |
| 23 | +. Install your custom resource definition (CRD) and proper role-based access control (RBAC) definitions for your custom resource (CR): |
| 24 | ++ |
| 25 | +[source,terminal] |
| 26 | +---- |
| 27 | +$ make install |
| 28 | +---- |
| 29 | ++ |
| 30 | +.Example output |
| 31 | +[source,terminal] |
| 32 | +---- |
| 33 | +/usr/bin/kustomize build config/crd | kubectl apply -f - |
| 34 | +customresourcedefinition.apiextensions.k8s.io/memcacheds.cache.example.com created |
| 35 | +---- |
| 36 | + |
| 37 | +. Run the `make run` command: |
| 38 | ++ |
| 39 | +[source,terminal] |
| 40 | +---- |
| 41 | +$ make run |
| 42 | +---- |
| 43 | ++ |
| 44 | +.Example output |
| 45 | +[source,terminal] |
| 46 | +---- |
| 47 | +/home/user/memcached-operator/bin/ansible-operator run |
| 48 | +{"level":"info","ts":1612739145.2871568,"logger":"cmd","msg":"Version","Go Version":"go1.15.5","GOOS":"linux","GOARCH":"amd64","ansible-operator":"v1.3.0","commit":"1abf57985b43bf6a59dcd18147b3c574fa57d3f6"} |
| 49 | +... |
| 50 | +{"level":"info","ts":1612739148.347306,"logger":"controller-runtime.metrics","msg":"metrics server is starting to listen","addr":":8080"} |
| 51 | +{"level":"info","ts":1612739148.3488882,"logger":"watches","msg":"Environment variable not set; using default value","envVar":"ANSIBLE_VERBOSITY_MEMCACHED_CACHE_EXAMPLE_COM","default":2} |
| 52 | +{"level":"info","ts":1612739148.3490262,"logger":"cmd","msg":"Environment variable not set; using default value","Namespace":"","envVar":"ANSIBLE_DEBUG_LOGS","ANSIBLE_DEBUG_LOGS":false} |
| 53 | +{"level":"info","ts":1612739148.3490646,"logger":"ansible-controller","msg":"Watching resource","Options.Group":"cache.example.com","Options.Version":"v1","Options.Kind":"Memcached"} |
| 54 | +{"level":"info","ts":1612739148.350217,"logger":"proxy","msg":"Starting to serve","Address":"127.0.0.1:8888"} |
| 55 | +{"level":"info","ts":1612739148.3506632,"logger":"controller-runtime.manager","msg":"starting metrics server","path":"/metrics"} |
| 56 | +{"level":"info","ts":1612739148.350784,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting EventSource","source":"kind source: cache.example.com/v1, Kind=Memcached"} |
| 57 | +{"level":"info","ts":1612739148.5511978,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting Controller"} |
| 58 | +{"level":"info","ts":1612739148.5512562,"logger":"controller-runtime.manager.controller.memcached-controller","msg":"Starting workers","worker count":8} |
| 59 | +---- |
| 60 | ++ |
| 61 | +With the Operator now watching your CR for events, the creation of a CR will trigger your Ansible role to run. |
| 62 | ++ |
| 63 | +[NOTE] |
| 64 | +==== |
| 65 | +Consider an example `config/samples/<gvk>.yaml` CR manifest: |
| 66 | +
|
| 67 | +[source,yaml] |
| 68 | +---- |
| 69 | +apiVersion: <group>.example.com/v1alpha1 |
| 70 | +kind: <kind> |
| 71 | +metadata: |
| 72 | + name: "<kind>-sample" |
| 73 | +---- |
| 74 | +
|
| 75 | +Because the `spec` field is not set, Ansible is invoked with no extra variables. Passing extra variables from a CR to Ansible is covered in another section. It is important to set reasonable defaults for the Operator. |
| 76 | +==== |
| 77 | + |
| 78 | +. Create an instance of your CR with the default variable `state` set to `present`: |
| 79 | ++ |
| 80 | +[source,terminal] |
| 81 | +---- |
| 82 | +$ oc apply -f config/samples/<gvk>.yaml |
| 83 | +---- |
| 84 | + |
| 85 | +. Check that the `example-config` config map was created: |
| 86 | ++ |
| 87 | +[source,terminal] |
| 88 | +---- |
| 89 | +$ oc get configmaps |
| 90 | +---- |
| 91 | ++ |
| 92 | +.Example output |
| 93 | +[source,terminal] |
| 94 | +---- |
| 95 | +NAME STATUS AGE |
| 96 | +example-config Active 3s |
| 97 | +---- |
| 98 | + |
| 99 | +. Modify your `config/samples/<gvk>.yaml` file to set the `state` field to `absent`. For example: |
| 100 | ++ |
| 101 | +[source,yaml] |
| 102 | +---- |
| 103 | +apiVersion: cache.example.com/v1 |
| 104 | +kind: Memcached |
| 105 | +metadata: |
| 106 | + name: memcached-sample |
| 107 | +spec: |
| 108 | + state: absent |
| 109 | +---- |
| 110 | + |
| 111 | +. Apply the changes: |
| 112 | ++ |
| 113 | +[source,terminal] |
| 114 | +---- |
| 115 | +$ oc apply -f config/samples/<gvk>.yaml |
| 116 | +---- |
| 117 | + |
| 118 | +. Confirm that the config map is deleted: |
| 119 | ++ |
| 120 | +[source,terminal] |
| 121 | +---- |
| 122 | +$ oc get configmap |
| 123 | +---- |
0 commit comments