blob: e2df6445f3dd96af183ee4d4612730d04c1e0bea [file] [log] [blame]
Scott Bakerfab7c9e2021-07-29 17:12:16 -07001.. vim: syntax=rst
2
3Aether ROC Developer Guide
4==========================
5
6Background / Development Environment
7------------------------------------
8
9This document assumes familiarity with Kubernetes and Helm, and that a Kubernetes/Helm development
10environment has already been deployed in the developer’s work environment.
Zack Williams1ae109e2021-07-27 11:17:04 -070011
12This development environment can use any of a number of potential mechanisms -- including KinD, kubeadm, etc.
13
Scott Bakerfab7c9e2021-07-29 17:12:16 -070014The Aether-in-a-Box script is one potential way to setup a development environment, but not the only way.
15As an alternative to the developer’s local machine, a remote environment can be set up, for example on
Zack Williams1ae109e2021-07-27 11:17:04 -070016cloud infrastructure such as Cloudlab.
Scott Bakerfab7c9e2021-07-29 17:12:16 -070017
Sean Condoneb95cd62021-08-04 19:44:18 +010018.. note:: When ROC is deployed it is unsecured by default, with no Authentication or Authorization.
19 To secure ROC so that the Authentication and Authorization can be tested, follow the Securing ROC
20 guide below :ref:`securing_roc`
21
Scott Bakerfab7c9e2021-07-29 17:12:16 -070022Installing Prerequisites
23------------------------
24
25Atomix and onos-operator must be installed::
26
27 # create necessary namespaces
28 kubectl create namespace micro-onos
29
30 # install atomix
Sean Condon70dcf702021-08-24 10:57:29 +010031 export ATOMIX_CONTROLLER_VERSION=0.6.8
Sean Condon257687f2021-08-23 11:13:20 +010032 helm -n kube-system install atomix-controller atomix/atomix-controller --version $ATOMIX_CONTROLLER_VERSION
Sean Condon70dcf702021-08-24 10:57:29 +010033 export ATOMIX_RAFT_VERSION=0.1.9
34 helm -n kube-system install atomix-raft-storage atomix/atomix-raft-storage --version $ATOMIX_RAFT_VERSION
Scott Bakerfab7c9e2021-07-29 17:12:16 -070035
36 # install the onos operator
Sean Condon257687f2021-08-23 11:13:20 +010037 ONOS_OPERATOR_VERSION=0.4.8
38 helm install -n kube-system onos-operator onosproject/onos-operator --version $ONOS_OPERATOR_VERSION
Scott Bakerfab7c9e2021-07-29 17:12:16 -070039
Sean Condon257687f2021-08-23 11:13:20 +010040.. note:: The ROC is sensitive to the versions of Atomix and onos-operator installed. The values
41 shown above are correct for the 1.2.x versions of the *aether-roc-umbrella*.
42
43.. list-table:: ROC support component version matrix
Sean Condon70dcf702021-08-24 10:57:29 +010044 :widths: 40 20 20 20
Sean Condon257687f2021-08-23 11:13:20 +010045 :header-rows: 1
46
47 * - ROC Version
48 - Atomix Controller
49 - Atomix Raft
50 - Onos Operator
Sean Condon70dcf702021-08-24 10:57:29 +010051 * - 1.2.25-1.2.45
Sean Condon257687f2021-08-23 11:13:20 +010052 - 0.6.7
53 - 0.1.8
54 - 0.4.8
Sean Condon70dcf702021-08-24 10:57:29 +010055 * - 1.3.0-
56 - 0.6.8
57 - 0.1.9
58 - 0.4.8
Scott Bakerfab7c9e2021-07-29 17:12:16 -070059
60Verify that these services were installed properly.
61You should see pods for *atomix-controller*, *atomix-raft-storage-controller*,
62*onos-operator-config*, and *onos-operator-topo*.
63Execute these commands::
64
Sean Condon257687f2021-08-23 11:13:20 +010065 helm -n kube-system list
Scott Bakerfab7c9e2021-07-29 17:12:16 -070066 kubectl -n kube-system get pods | grep -i atomix
67 kubectl -n kube-system get pods | grep -i onos
68
Scott Bakerfab7c9e2021-07-29 17:12:16 -070069Create a values-override.yaml
70-----------------------------
71
72You’ll want to override several of the defaults in the ROC helm charts::
73
74 cat > values-override.yaml <<EOF
75 import:
Scott Bakerb46a6ed2021-08-02 14:03:10 -070076 onos-gui:
77 enabled: true
Scott Bakerfab7c9e2021-07-29 17:12:16 -070078
79 onos-gui:
Scott Bakerb46a6ed2021-08-02 14:03:10 -070080 ingress:
81 enabled: false
Scott Bakerfab7c9e2021-07-29 17:12:16 -070082
83 aether-roc-gui-v3:
Scott Bakerb46a6ed2021-08-02 14:03:10 -070084 ingress:
85 enabled: false
Scott Bakerfab7c9e2021-07-29 17:12:16 -070086 EOF
87
Zack Williams1ae109e2021-07-27 11:17:04 -070088Installing the ``aether-roc-umbrella`` Helm chart
89-------------------------------------------------
Scott Bakerfab7c9e2021-07-29 17:12:16 -070090
91Add the necessary helm repositories::
92
93 # obtain username and password from Michelle and/or ONF infra team
94 export repo_user=<username>
95 export repo_password=<password>
96 helm repo add sdran --username "$repo_user" --password "$repo_password" https://sdrancharts.onosproject.org
97
Zack Williams1ae109e2021-07-27 11:17:04 -070098``aether-roc-umbrella`` will bring up the ROC and its services::
Scott Bakerfab7c9e2021-07-29 17:12:16 -070099
100 helm -n micro-onos install aether-roc-umbrella sdran/aether-roc-umbrella -f values-override.yaml
101
102 kubectl wait pod -n micro-onos --for=condition=Ready -l type=config --timeout=300s
103
104
Sean Condonf918f642021-08-04 14:32:53 +0100105.. _posting-the-mega-patch:
106
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700107Posting the mega-patch
108----------------------
109
110The ROC usually comes up in a blank state -- there are no Enterprises, UEs, or other artifacts present in it.
111The mega-patch is an example patch that populates the ROC with some sample enterprises, UEs, slices, etc.
112Execute the following::
113
114 # launch a port-forward for the API
115 # this will continue to run in the background
116 kubectl -n micro-onos port-forward service/aether-roc-api --address 0.0.0.0 8181:8181 &
117
118 git clone https://github.com/onosproject/aether-roc-api.git
119
120 # execute the mega-patch (it will post via CURL to localhost:8181)
121 bash ~/path/to/aether-roc-api/examples/MEGA_Patch.curl
122
123
124You may wish to customize the mega patch.
Zack Williams1ae109e2021-07-27 11:17:04 -0700125
126For example, by default the patch configures the ``sdcore-adapter`` to push to
127``sdcore-test-dummy``.
128
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700129You could configure it to push to a live aether-in-a-box core by doing something like this::
130
131 sed -i 's^http://aether-roc-umbrella-sdcore-test-dummy/v1/config/5g^http://webui.omec.svc.cluster.local:9089/config^g' MEGA_Patch.curl
132
133 #apply the patch
134 ./MEGA_Patch.curl
135
136(Note that if your Aether-in-a-Box was installed on a different machine that port-forwarding may be necessary)
137
138
139Expected CURL output from a successful mega-patch post will be a UUID.
Zack Williams1ae109e2021-07-27 11:17:04 -0700140
141You can also verify that the mega-patch was successful by going into the
142``aether-roc-gui`` in a browser (see the section on useful port-forwards
143below). The GUI may open to a dashboard that is unpopulated -- you can use the
144dropdown menu (upper-right hand corner of the screen) to select an object such
145as VCS and you will see a list of VCS.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700146
147 |ROCGUI|
148
Zack Williams1ae109e2021-07-27 11:17:04 -0700149Uninstalling the ``aether-roc-umbrella`` Helm chart
150---------------------------------------------------
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700151
152To tear things back down, usually as part of a developer loop prior to redeploying again, do the following::
153
154 helm -n micro-onos del aether-roc-umbrella
155
156If the uninstall hangs or if a subsequent reinstall hangs, it could be an issue with some of the CRDs
157not getting cleaned up. The following may be useful::
158
159 # fix stuck finalizers in operator CRDs
160
161 kubectl -n micro-onos patch entities connectivity-service-v2 --type json --patch='[ { "op": "remove", "path": "/metadata/finalizers" } ]'
162
163 kubectl -n micro-onos patch entities connectivity-service-v3 --type json --patch='[ { "op": "remove", "path": "/metadata/finalizers" } ]'
164
165 kubectl -n micro-onos patch kind aether --type json --patch='[ { "op": "remove", "path": "/metadata/finalizers" } ]'
166
167Useful port forwards
168--------------------
169
170Port forwarding is often necessary to allow access to ports inside of Kubernetes pods that use ClusterIP addressing.
171Note that you typically need to leave a port-forward running (you can put it in the background).
172Also, If you redeploy the ROC and/or if a pod crashes then you might have to restart a port-forward.
173The following port-forwards may be useful::
174
175 # aether-roc-api
176
177 kubectl -n micro-onos port-forward service/aether-roc-api --address 0.0.0.0 8181:8181
178
179 # aether-roc-gui
180
181 kubectl -n micro-onos port-forward service/aether-roc-gui --address 0.0.0.0 8183:80
182
183 # grafana
184
185 kubectl -n micro-onos port-forward service/aether-roc-umbrella-grafana --address 0.0.0.0 8187:80
186
187 # onos gui
188
189 kubectl -n micro-onos port-forward service/onos-gui --address 0.0.0.0 8182:80
190
Zack Williams1ae109e2021-07-27 11:17:04 -0700191``aether-roc-api`` and ``aether-roc-gui`` are in our experience the most useful two port-forwards.
192
193``aether-roc-api`` is useful to be able to POST REST API requests.
194
195``aether-roc-gui`` is useful to be able to interactively browse the current configuration.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700196
Sean Condon257687f2021-08-23 11:13:20 +0100197.. note:: Internally the ``aether-roc-gui`` operates a Reverse Proxy on the ``aether-roc-api``. This
198 means that if you have done a ``port-forward`` to ``aether-roc-gui`` say on port ``8183`` there's no
199 need to do another on the ``aether-roc-api`` instead you can access the API on
200 ``http://localhost:8183/aether-roc-api``
201
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700202Deploying using custom images
203-----------------------------
204
205Custom images may be used by editing the values-override.yaml file.
Zack Williams1ae109e2021-07-27 11:17:04 -0700206For example, to deploy a custom ``sdcore-adapter``::
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700207
208 sdcore-adapter-v3:
209
210 prometheusEnabled: false
211
212 image:
213
214 repository: my-private-repo/sdcore-adapter
215
216 tag: my-tag
217
218 pullPolicy: Always
219
Zack Williams1ae109e2021-07-27 11:17:04 -0700220The above example assumes you have published a docker images at ``my-private-repo/sdcore-adapter:my-tag``.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700221My particular workflow is to deploy a local-docker registry and push my images to that.
222Please do not publish ONF images to a public repository unless the image is intended to be public.
223Several ONF repositories are private, and therefore their docker artifacts should also be private.
224
225There are alternatives to using a private docker repository.
Zack Williams1ae109e2021-07-27 11:17:04 -0700226For example, if you are using kubeadm, then you may be able to simply tag the image locally.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700227If you’re using KinD, then you can push a local image to into the kind cluster::
228
229 kind load docker-image sdcore-adapter:my-tag
230
231Inspecting logs
232---------------
233
234Most of the relevant Kubernetes pods are in the micro-onos namespace.
235The names may change from deployment to deployment, so start by getting a list of pods::
236
237 kubectl -n micro-onos get pods
238
239Then you can inspect a specific pod/container::
240
241 kubectl -n micro-onos logs sdcore-adapter-v3-7468cc58dc-ktctz sdcore-adapter-v3
242
Sean Condoneb95cd62021-08-04 19:44:18 +0100243.. _securing_roc:
244
245Securing ROC
246------------
247
Zack Williams1ae109e2021-07-27 11:17:04 -0700248When deploying ROC with the ``aether-roc-umbrella`` chart, secure mode can be enabled by
Sean Condoneb95cd62021-08-04 19:44:18 +0100249specifying an OpenID Connect (OIDC) issuer like::
250
251 helm -n micro-onos install aether-roc-umbrella sdran/aether-roc-umbrella \
252 --set onos-config.openidc.issuer=http://dex-ldap-umbrella:5556 \
253 --set aether-roc-gui-v3.openidc.issuer=http://dex-ldap-umbrella:5556
254
Zack Williams1ae109e2021-07-27 11:17:04 -0700255The choice of OIDC issuer in this case is ``dex-ldap-umbrella``.
Sean Condoneb95cd62021-08-04 19:44:18 +0100256
Zack Williams1ae109e2021-07-27 11:17:04 -0700257``dex-ldap-umbrella``
258"""""""""""""""""""""
Sean Condoneb95cd62021-08-04 19:44:18 +0100259
260Dex is a cloud native OIDC Issuer than can act as a front end to several authentication systems
261e.g. LDAP, Crowd, Google, GitHub
262
Zack Williams1ae109e2021-07-27 11:17:04 -0700263``dex-ldap-umbrella`` is a Helm chart that combines a Dex server with an LDAP
264installation, and an LDAP administration tool. It can be deployed in to the
265same cluster namespace as ``aether-roc-umbrella``.
Sean Condoneb95cd62021-08-04 19:44:18 +0100266
267Its LDAP server is populated with 7 different users in the 2 example enterprises - *starbucks* and *acme*.
268
269When running it should be available at *http://dex-ldap-umbrella:5556/.well-known/openid-configuration*.
270
271See `dex-ldap-umbrella <https://github.com/onosproject/onos-helm-charts/tree/master/dex-ldap-umbrella#readme>`_
272for more details.
273
274As an alternative there is a public Dex server connected to the ONF Crowd server, that allows
275ONF staff to login with their own credentials:
276See `public dex <https://dex.aetherproject.org/dex/.well-known/openid-configuration>`_ for more details.
277
278.. note:: Your RBAC access to ROC will be limited by the groups you belong to in Crowd.
279
280Role Based Access Control
Zack Williams1ae109e2021-07-27 11:17:04 -0700281"""""""""""""""""""""""""
282
Sean Condoneb95cd62021-08-04 19:44:18 +0100283When secured, access to the configuration in ROC is limited by the **groups** that a user belongs to.
284
285* **AetherROCAdmin** - users in this group have full read **and** write access to all configuration.
286* *<enterprise>* - users in a group the lowercase name of an enterprise, will have **read** access to that enterprise.
287* **EnterpriseAdmin** - users in this group will have read **and** write access the enterprise they belong to.
288
289 For example in *dex-ldap-umbrella* the user *Daisy Duke* belongs to *starbucks* **and**
290 *EnterpriseAdmin* and so has read **and** write access to items linked with *starbucks* enterprise.
291
292 By comparison the user *Elmer Fudd* belongs only to *starbucks* group and so has only **read** access to items
293 linked with the *starbucks* enterprise.
294
295Requests to a Secure System
Zack Williams1ae109e2021-07-27 11:17:04 -0700296"""""""""""""""""""""""""""
297
Sean Condoneb95cd62021-08-04 19:44:18 +0100298When configuration is retrieved or updated through *aether-config*, a Bearer Token in the
Zack Williams1ae109e2021-07-27 11:17:04 -0700299form of a JSON Web Token (JWT) issued by the selected OIDC Issuer server must accompany
Sean Condoneb95cd62021-08-04 19:44:18 +0100300the request as an Authorization Header.
301
Zack Williams1ae109e2021-07-27 11:17:04 -0700302This applies to both the REST interface of ``aether-roc-api`` **and** the *gnmi* interface of
303``aether-rconfig``.
Sean Condoneb95cd62021-08-04 19:44:18 +0100304
305In the Aether ROC, a Bearer Token can be generated by logging in and selecting API Key from the
306menu. This pops up a window with a copy button, where the key can be copied.
307
308The key will expire after 24 hours.
309
310.. image:: images/aether-roc-gui-copy-api-key.png
311 :width: 580
312 :alt: Aether ROC GUI allows copying of API Key to clipboard
313
314Accessing the REST interface from a tool like Postman, should include this Auth token.
315
316.. image:: images/postman-auth-token.png
317 :width: 930
318 :alt: Postman showing Authentication Token pasted in
319
320Logging
Zack Williams1ae109e2021-07-27 11:17:04 -0700321"""""""
322
Sean Condoneb95cd62021-08-04 19:44:18 +0100323The logs of *aether-config* will contain the **username** and **timestamp** of
324any **gnmi** call when security is enabled.
325
326.. image:: images/aether-config-log.png
327 :width: 887
328 :alt: aether-config log message showing username and timestamp
329
Sean Condon435be9a2021-08-06 14:28:37 +0100330Accessing GUI from an external system
Zack Williams1ae109e2021-07-27 11:17:04 -0700331"""""""""""""""""""""""""""""""""""""
332
Sean Condon435be9a2021-08-06 14:28:37 +0100333To access the ROC GUI from a computer outside the Cluster machine using *port-forwarding* then
334it is necessary to:
335
336* Ensure that all *port-forward*'s have **--address=0.0.0.0**
337* Add to the IP address of the cluster machine to the **/etc/hosts** of the outside computer as::
338
339 <ip address of cluster> dex-ldap-umbrella aether-roc-gui
340* Verify that you can access the Dex server by its name *http://dex-ldap-umbrella:5556/.well-known/openid-configuration*
Zack Williams1ae109e2021-07-27 11:17:04 -0700341* Access the GUI through the hostname (rather than ip address) ``http://aether-roc-gui:8183``
Sean Condon435be9a2021-08-06 14:28:37 +0100342
Sean Condoneb95cd62021-08-04 19:44:18 +0100343Troubleshooting Secure Access
Zack Williams1ae109e2021-07-27 11:17:04 -0700344"""""""""""""""""""""""""""""
345
Sean Condoneb95cd62021-08-04 19:44:18 +0100346While every effort has been made to ensure that securing Aether is simple and effective,
347some difficulties may arise.
348
349One of the most important steps is to validate that the OIDC Issuer (Dex server) can be reached
350from the browser. The **well_known** URL should be available and show the important endpoints are correct.
351
352.. image:: images/dex-ldap-umbrella-well-known.png
353 :width: 580
354 :alt: Dex Well Known page
355
356If logged out of the Browser when accessing the Aether ROC GUI, accessing any page of the application should
357redirect to the Dex login page.
358
359.. image:: images/dex-ldap-login-page.png
360 :width: 493
361 :alt: Dex Login page
362
363When logged in the User details can be seen by clicking the User's name in the drop down menu.
364This shows the **groups** that the user belongs to, and can be used to debug RBAC issues.
365
366.. image:: images/aether-roc-gui-user-details.png
367 :width: 700
368 :alt: User Details page
369
370When you sign out of the ROC GUI, if you are not redirected to the Dex Login Page,
371you should check the Developer Console of the browser. The console should show the correct
Zack Williams1ae109e2021-07-27 11:17:04 -0700372OIDC issuer (Dex server), and that Auth is enabled.
Sean Condoneb95cd62021-08-04 19:44:18 +0100373
374.. image:: images/aether-roc-gui-console-loggedin.png
375 :width: 418
376 :alt: Browser Console showing correct configuration
377
Scott Bakerb46a6ed2021-08-02 14:03:10 -0700378ROC Data Model Conventions and Requirements
379-------------------------------------------
380
381The MEGA-Patch described above will bring up a fully compliant sample data model.
382However, it may be useful to bring up your own data model, customized to a different
383site of sites. This subsection documents conventions and requirements for the Aether
Zack Williams1ae109e2021-07-27 11:17:04 -0700384modeling within the ROC.
Scott Bakerb46a6ed2021-08-02 14:03:10 -0700385
386The ROC models must be configured with the following:
387
388* A default enterprise with the id `defaultent`.
389* A default ip-domain with the id `defaultent-defaultip`.
390* A default site with the id `defaultent-defaultsite`.
391 This site should be linked to the `defaultent` enterprise.
392* A default device group with the id `defaultent-defaultsite-default`.
393 This device group should be linked to the `defaultent-defaultip` ip-domain
394 and the `defaultent-defaultsite` site.
395
396Each Enterprise Site must be configured with a default device group and that default
397device group's name must end in the suffix `-default`. For example, `acme-chicago-default`.
398
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700399Some exercises to get familiar
400------------------------------
401
Zack Williams1ae109e2021-07-27 11:17:04 -07004021. Deploy the ROC and POST the mega-patch, go into the ``aether-roc-gui`` and click
403 through the VCS, DeviceGroup, and other objects to see that they were
404 created as expected.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700405
Zack Williams1ae109e2021-07-27 11:17:04 -07004062. Examine the log of the ``sdcore-adapter-v3`` container. It should be
407 attempting to push the mega-patch’s changes. If you don’t have a core
408 available, it may be failing the push, but you should see the attempts.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700409
Zack Williams1ae109e2021-07-27 11:17:04 -07004103. Change an object in the GUI. Watch the ``sdcore-adapter-v3`` log file and
411 see that the adapter attempts to push the change.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700412
Zack Williams1ae109e2021-07-27 11:17:04 -07004134. Try POSTing a change via the API. Observe the ``sdcore-adapter-v3`` log
414 file and see that the adapter attempts to push the change.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700415
Zack Williams1ae109e2021-07-27 11:17:04 -07004165. Deploy a 5G Aether-in-a-Box (See :doc:`Aether SD-Core Developer Guide
417 <sdcore>`), modify the mega-patch to specify the URL for the Aether-in-a-Box
418 ``webui`` container, POST the mega-patch, and observe that the changes were
419 correctly pushed via the ``sdcore-adapter-v3`` into the ``sd-core``’s
420 ``webui`` container (``webui`` container log will show configuration as it
421 is received)
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700422
423.. |ROCGUI| image:: images/rocgui.png
Sean Condoneb95cd62021-08-04 19:44:18 +0100424 :width: 945
425 :alt: ROC GUI showing list of VCS