github.com/verrazzano/verrazzano-monitoring-operator@v0.0.30/docs/development.md (about) 1 # Development guide 2 3 This page provides information for developers who want to understand or contribute to the VMO. 4 5 ## Building the operator 6 7 ### Requirements 8 9 The following is required to build the operator: 10 * Golang 1.13 or higher 11 * Docker 12 13 Run the following command from $GOPATH/src/github.com/verrazzano/verrazzano-monitoring-operator: 14 15 ``` 16 make go-install 17 ``` 18 19 #### Controller Generators 20 21 The Controller makes use of the generators in k8s.io/code-generator to generate a typed client, informers, listers and deep-copy functions. 22 23 The `./hack/update-codegen.sh` script is included in the `go-install` target. It will re-generate the following files and directories: 24 - pkg/apis/vmcontroller/v1/zz_generated.deepcopy.go 25 - pkg/client 26 27 ## Running the VMO 28 29 ### Requirements 30 31 The following is required to run the VMO: 32 * Kubernetes v1.13.x and up 33 34 ### Install the CRDs 35 36 Regardless of which of the following options you use to run the VMO, you'll need to first manually apply 37 the VMO CRDs. This is a one-time step: 38 39 ``` 40 # Install VMO CRDs 41 kubectl apply -f k8s/crds/verrazzano-monitoring-operator-crds.yaml --validate=false 42 ``` 43 44 ### Running the VMO as an out-of-cluster process 45 46 While developing the VMO itself, it's usually most efficient to run it as an out-of-cluster 47 process, pointing to your Kubernetes cluster. To do this: 48 49 ``` 50 export KUBECONFIG=<your_kubeconfig> 51 52 # Run the operator as a local Go process: 53 make go-run 54 ``` 55 56 From here you can manually deploy VMIs to your cluster (as in the [Usage doc](usage.md)), or run integration tests. 57 58 ### Running the operator as an in-cluster pod 59 60 The official way to run a Kubernetes operator is to run it as a pod within Kubernetes itself. To build this 61 Docker image, assigning it a temporary tag based on the current timestamp: 62 63 ``` 64 make build 65 ``` 66 67 If your `$KUBECONFIG` points to a remote cluster, you'll have to push this image to a real Docker registry: 68 69 ``` 70 docker login --username agent <docker repo> 71 # Password is a secret! 72 make push 73 ``` 74 75 Now, replace the VMO Docker image in `k8s/manifests/verrazzano-monitoring-operator.yaml` with the temporary image built 76 above, then run: 77 78 ``` 79 kubectl apply -f k8s/manifests/verrazzano-monitoring-operator.yaml 80 ``` 81 82 ## Running unit and integration tests 83 84 To perform static analysis: 85 86 ``` 87 make golangci-lint 88 ``` 89 To run unit tests: 90 91 ``` 92 make unit-test 93 ``` 94 95 To perform both static analysis and run unit test in one go: 96 97 ``` 98 make check 99 ``` 100 101 To run integration tests against a real Kubernetes cluster, first start the VMO using either the 102 out-of-cluster or in-cluster techniques mentioned above, then: 103 104 Testing against a cluster on your laptop 105 106 ``` 107 make integ-test 108 ``` 109 110 Testing against a remote cluster (with worker nodes with public IPs): 111 ``` 112 make integ-test K8S_EXTERNAL_IP=<ip_of_a_worker_node> 113 ``` 114 115 ## Other Development Notes 116 117 ### Making changes to the operator-generated Kubernetes objects 118 119 As explained elsewhere, for each VMI, the VMO creates/updates a set of Deployments/Services/ConfigMaps/etc. 120 As we evolve the operator code, the contents of these Kubernetes objects change. When the operator processes a VMI, 121 it evaluates each Kubernetes object associated with the instance, diffing its desired state against its expected 122 state. If the states are different, it calls the Kubernetes API to apply the desired state. Some special diffing logic 123 has been added to the VMO to account for the fact that an object's live state, retrieved from the k8s API, 124 is always populated with many runtime-generated default values: we simply disregard the diff comparison for any element 125 that is 'empty' in the desired object state. For our purposes, an 'empty' element is defined as either: 126 - Missing completely from the desired state 127 - Set to nil or the equivalent of a Golang nil value ("", 0, etc) in the desired state 128 - A map/list that is set to an empty map/list in the desired state 129 130 In almost all situations, the above diffing logic will be transparent to VMO developers, and changes to the 131 operator that modify Deployments/Services/ConfigMaps/etc will simply take effect when the operator is deployed 132 to a live system. The only limitation to the above logic is that if we ever _truly wanted to_ (for some reason, although no 133 good example comes to mind) set an element to an empty value, our code doesn't allow it. In this unlikely/rare case, it would 134 be necessary to do that with a one-off script.