blob: 4b8c727e4f8869423e3e77dd7db83606d54e3ed1 [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 Condon257687f2021-08-23 11:13:20 +010031 export ATOMIX_CONTROLLER_VERSION=0.6.7
32 helm -n kube-system install atomix-controller atomix/atomix-controller --version $ATOMIX_CONTROLLER_VERSION
33 export ATOMIX_RAFT_VERSION=0.1.8
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
44 :widths: 28 24 24 24
45 :header-rows: 1
46
47 * - ROC Version
48 - Atomix Controller
49 - Atomix Raft
50 - Onos Operator
51 * - 1.2.x
52 - 0.6.7
53 - 0.1.8
54 - 0.4.8
Scott Bakerfab7c9e2021-07-29 17:12:16 -070055
56Verify that these services were installed properly.
57You should see pods for *atomix-controller*, *atomix-raft-storage-controller*,
58*onos-operator-config*, and *onos-operator-topo*.
59Execute these commands::
60
Sean Condon257687f2021-08-23 11:13:20 +010061 helm -n kube-system list
Scott Bakerfab7c9e2021-07-29 17:12:16 -070062 kubectl -n kube-system get pods | grep -i atomix
63 kubectl -n kube-system get pods | grep -i onos
64
Scott Bakerfab7c9e2021-07-29 17:12:16 -070065Create a values-override.yaml
66-----------------------------
67
68You’ll want to override several of the defaults in the ROC helm charts::
69
70 cat > values-override.yaml <<EOF
71 import:
Scott Bakerb46a6ed2021-08-02 14:03:10 -070072 onos-gui:
73 enabled: true
Scott Bakerfab7c9e2021-07-29 17:12:16 -070074
75 onos-gui:
Scott Bakerb46a6ed2021-08-02 14:03:10 -070076 ingress:
77 enabled: false
Scott Bakerfab7c9e2021-07-29 17:12:16 -070078
79 aether-roc-gui-v3:
Scott Bakerb46a6ed2021-08-02 14:03:10 -070080 ingress:
81 enabled: false
Scott Bakerfab7c9e2021-07-29 17:12:16 -070082 EOF
83
Zack Williams1ae109e2021-07-27 11:17:04 -070084Installing the ``aether-roc-umbrella`` Helm chart
85-------------------------------------------------
Scott Bakerfab7c9e2021-07-29 17:12:16 -070086
87Add the necessary helm repositories::
88
89 # obtain username and password from Michelle and/or ONF infra team
90 export repo_user=<username>
91 export repo_password=<password>
92 helm repo add sdran --username "$repo_user" --password "$repo_password" https://sdrancharts.onosproject.org
93
Zack Williams1ae109e2021-07-27 11:17:04 -070094``aether-roc-umbrella`` will bring up the ROC and its services::
Scott Bakerfab7c9e2021-07-29 17:12:16 -070095
96 helm -n micro-onos install aether-roc-umbrella sdran/aether-roc-umbrella -f values-override.yaml
97
98 kubectl wait pod -n micro-onos --for=condition=Ready -l type=config --timeout=300s
99
100
Sean Condonf918f642021-08-04 14:32:53 +0100101.. _posting-the-mega-patch:
102
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700103Posting the mega-patch
104----------------------
105
106The ROC usually comes up in a blank state -- there are no Enterprises, UEs, or other artifacts present in it.
107The mega-patch is an example patch that populates the ROC with some sample enterprises, UEs, slices, etc.
108Execute the following::
109
110 # launch a port-forward for the API
111 # this will continue to run in the background
112 kubectl -n micro-onos port-forward service/aether-roc-api --address 0.0.0.0 8181:8181 &
113
114 git clone https://github.com/onosproject/aether-roc-api.git
115
116 # execute the mega-patch (it will post via CURL to localhost:8181)
117 bash ~/path/to/aether-roc-api/examples/MEGA_Patch.curl
118
119
120You may wish to customize the mega patch.
Zack Williams1ae109e2021-07-27 11:17:04 -0700121
122For example, by default the patch configures the ``sdcore-adapter`` to push to
123``sdcore-test-dummy``.
124
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700125You could configure it to push to a live aether-in-a-box core by doing something like this::
126
127 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
128
129 #apply the patch
130 ./MEGA_Patch.curl
131
132(Note that if your Aether-in-a-Box was installed on a different machine that port-forwarding may be necessary)
133
134
135Expected CURL output from a successful mega-patch post will be a UUID.
Zack Williams1ae109e2021-07-27 11:17:04 -0700136
137You can also verify that the mega-patch was successful by going into the
138``aether-roc-gui`` in a browser (see the section on useful port-forwards
139below). The GUI may open to a dashboard that is unpopulated -- you can use the
140dropdown menu (upper-right hand corner of the screen) to select an object such
141as VCS and you will see a list of VCS.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700142
143 |ROCGUI|
144
Zack Williams1ae109e2021-07-27 11:17:04 -0700145Uninstalling the ``aether-roc-umbrella`` Helm chart
146---------------------------------------------------
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700147
148To tear things back down, usually as part of a developer loop prior to redeploying again, do the following::
149
150 helm -n micro-onos del aether-roc-umbrella
151
152If the uninstall hangs or if a subsequent reinstall hangs, it could be an issue with some of the CRDs
153not getting cleaned up. The following may be useful::
154
155 # fix stuck finalizers in operator CRDs
156
157 kubectl -n micro-onos patch entities connectivity-service-v2 --type json --patch='[ { "op": "remove", "path": "/metadata/finalizers" } ]'
158
159 kubectl -n micro-onos patch entities connectivity-service-v3 --type json --patch='[ { "op": "remove", "path": "/metadata/finalizers" } ]'
160
161 kubectl -n micro-onos patch kind aether --type json --patch='[ { "op": "remove", "path": "/metadata/finalizers" } ]'
162
163Useful port forwards
164--------------------
165
166Port forwarding is often necessary to allow access to ports inside of Kubernetes pods that use ClusterIP addressing.
167Note that you typically need to leave a port-forward running (you can put it in the background).
168Also, If you redeploy the ROC and/or if a pod crashes then you might have to restart a port-forward.
169The following port-forwards may be useful::
170
171 # aether-roc-api
172
173 kubectl -n micro-onos port-forward service/aether-roc-api --address 0.0.0.0 8181:8181
174
175 # aether-roc-gui
176
177 kubectl -n micro-onos port-forward service/aether-roc-gui --address 0.0.0.0 8183:80
178
179 # grafana
180
181 kubectl -n micro-onos port-forward service/aether-roc-umbrella-grafana --address 0.0.0.0 8187:80
182
183 # onos gui
184
185 kubectl -n micro-onos port-forward service/onos-gui --address 0.0.0.0 8182:80
186
Zack Williams1ae109e2021-07-27 11:17:04 -0700187``aether-roc-api`` and ``aether-roc-gui`` are in our experience the most useful two port-forwards.
188
189``aether-roc-api`` is useful to be able to POST REST API requests.
190
191``aether-roc-gui`` is useful to be able to interactively browse the current configuration.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700192
Sean Condon257687f2021-08-23 11:13:20 +0100193.. note:: Internally the ``aether-roc-gui`` operates a Reverse Proxy on the ``aether-roc-api``. This
194 means that if you have done a ``port-forward`` to ``aether-roc-gui`` say on port ``8183`` there's no
195 need to do another on the ``aether-roc-api`` instead you can access the API on
196 ``http://localhost:8183/aether-roc-api``
197
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700198Deploying using custom images
199-----------------------------
200
201Custom images may be used by editing the values-override.yaml file.
Zack Williams1ae109e2021-07-27 11:17:04 -0700202For example, to deploy a custom ``sdcore-adapter``::
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700203
204 sdcore-adapter-v3:
205
206 prometheusEnabled: false
207
208 image:
209
210 repository: my-private-repo/sdcore-adapter
211
212 tag: my-tag
213
214 pullPolicy: Always
215
Zack Williams1ae109e2021-07-27 11:17:04 -0700216The above example assumes you have published a docker images at ``my-private-repo/sdcore-adapter:my-tag``.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700217My particular workflow is to deploy a local-docker registry and push my images to that.
218Please do not publish ONF images to a public repository unless the image is intended to be public.
219Several ONF repositories are private, and therefore their docker artifacts should also be private.
220
221There are alternatives to using a private docker repository.
Zack Williams1ae109e2021-07-27 11:17:04 -0700222For example, if you are using kubeadm, then you may be able to simply tag the image locally.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700223If you’re using KinD, then you can push a local image to into the kind cluster::
224
225 kind load docker-image sdcore-adapter:my-tag
226
227Inspecting logs
228---------------
229
230Most of the relevant Kubernetes pods are in the micro-onos namespace.
231The names may change from deployment to deployment, so start by getting a list of pods::
232
233 kubectl -n micro-onos get pods
234
235Then you can inspect a specific pod/container::
236
237 kubectl -n micro-onos logs sdcore-adapter-v3-7468cc58dc-ktctz sdcore-adapter-v3
238
Sean Condoneb95cd62021-08-04 19:44:18 +0100239.. _securing_roc:
240
241Securing ROC
242------------
243
Zack Williams1ae109e2021-07-27 11:17:04 -0700244When deploying ROC with the ``aether-roc-umbrella`` chart, secure mode can be enabled by
Sean Condoneb95cd62021-08-04 19:44:18 +0100245specifying an OpenID Connect (OIDC) issuer like::
246
247 helm -n micro-onos install aether-roc-umbrella sdran/aether-roc-umbrella \
248 --set onos-config.openidc.issuer=http://dex-ldap-umbrella:5556 \
249 --set aether-roc-gui-v3.openidc.issuer=http://dex-ldap-umbrella:5556
250
Zack Williams1ae109e2021-07-27 11:17:04 -0700251The choice of OIDC issuer in this case is ``dex-ldap-umbrella``.
Sean Condoneb95cd62021-08-04 19:44:18 +0100252
Zack Williams1ae109e2021-07-27 11:17:04 -0700253``dex-ldap-umbrella``
254"""""""""""""""""""""
Sean Condoneb95cd62021-08-04 19:44:18 +0100255
256Dex is a cloud native OIDC Issuer than can act as a front end to several authentication systems
257e.g. LDAP, Crowd, Google, GitHub
258
Zack Williams1ae109e2021-07-27 11:17:04 -0700259``dex-ldap-umbrella`` is a Helm chart that combines a Dex server with an LDAP
260installation, and an LDAP administration tool. It can be deployed in to the
261same cluster namespace as ``aether-roc-umbrella``.
Sean Condoneb95cd62021-08-04 19:44:18 +0100262
263Its LDAP server is populated with 7 different users in the 2 example enterprises - *starbucks* and *acme*.
264
265When running it should be available at *http://dex-ldap-umbrella:5556/.well-known/openid-configuration*.
266
267See `dex-ldap-umbrella <https://github.com/onosproject/onos-helm-charts/tree/master/dex-ldap-umbrella#readme>`_
268for more details.
269
270As an alternative there is a public Dex server connected to the ONF Crowd server, that allows
271ONF staff to login with their own credentials:
272See `public dex <https://dex.aetherproject.org/dex/.well-known/openid-configuration>`_ for more details.
273
274.. note:: Your RBAC access to ROC will be limited by the groups you belong to in Crowd.
275
276Role Based Access Control
Zack Williams1ae109e2021-07-27 11:17:04 -0700277"""""""""""""""""""""""""
278
Sean Condoneb95cd62021-08-04 19:44:18 +0100279When secured, access to the configuration in ROC is limited by the **groups** that a user belongs to.
280
281* **AetherROCAdmin** - users in this group have full read **and** write access to all configuration.
282* *<enterprise>* - users in a group the lowercase name of an enterprise, will have **read** access to that enterprise.
283* **EnterpriseAdmin** - users in this group will have read **and** write access the enterprise they belong to.
284
285 For example in *dex-ldap-umbrella* the user *Daisy Duke* belongs to *starbucks* **and**
286 *EnterpriseAdmin* and so has read **and** write access to items linked with *starbucks* enterprise.
287
288 By comparison the user *Elmer Fudd* belongs only to *starbucks* group and so has only **read** access to items
289 linked with the *starbucks* enterprise.
290
291Requests to a Secure System
Zack Williams1ae109e2021-07-27 11:17:04 -0700292"""""""""""""""""""""""""""
293
Sean Condoneb95cd62021-08-04 19:44:18 +0100294When configuration is retrieved or updated through *aether-config*, a Bearer Token in the
Zack Williams1ae109e2021-07-27 11:17:04 -0700295form of a JSON Web Token (JWT) issued by the selected OIDC Issuer server must accompany
Sean Condoneb95cd62021-08-04 19:44:18 +0100296the request as an Authorization Header.
297
Zack Williams1ae109e2021-07-27 11:17:04 -0700298This applies to both the REST interface of ``aether-roc-api`` **and** the *gnmi* interface of
299``aether-rconfig``.
Sean Condoneb95cd62021-08-04 19:44:18 +0100300
301In the Aether ROC, a Bearer Token can be generated by logging in and selecting API Key from the
302menu. This pops up a window with a copy button, where the key can be copied.
303
304The key will expire after 24 hours.
305
306.. image:: images/aether-roc-gui-copy-api-key.png
307 :width: 580
308 :alt: Aether ROC GUI allows copying of API Key to clipboard
309
310Accessing the REST interface from a tool like Postman, should include this Auth token.
311
312.. image:: images/postman-auth-token.png
313 :width: 930
314 :alt: Postman showing Authentication Token pasted in
315
316Logging
Zack Williams1ae109e2021-07-27 11:17:04 -0700317"""""""
318
Sean Condoneb95cd62021-08-04 19:44:18 +0100319The logs of *aether-config* will contain the **username** and **timestamp** of
320any **gnmi** call when security is enabled.
321
322.. image:: images/aether-config-log.png
323 :width: 887
324 :alt: aether-config log message showing username and timestamp
325
Sean Condon435be9a2021-08-06 14:28:37 +0100326Accessing GUI from an external system
Zack Williams1ae109e2021-07-27 11:17:04 -0700327"""""""""""""""""""""""""""""""""""""
328
Sean Condon435be9a2021-08-06 14:28:37 +0100329To access the ROC GUI from a computer outside the Cluster machine using *port-forwarding* then
330it is necessary to:
331
332* Ensure that all *port-forward*'s have **--address=0.0.0.0**
333* Add to the IP address of the cluster machine to the **/etc/hosts** of the outside computer as::
334
335 <ip address of cluster> dex-ldap-umbrella aether-roc-gui
336* 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 -0700337* Access the GUI through the hostname (rather than ip address) ``http://aether-roc-gui:8183``
Sean Condon435be9a2021-08-06 14:28:37 +0100338
Sean Condoneb95cd62021-08-04 19:44:18 +0100339Troubleshooting Secure Access
Zack Williams1ae109e2021-07-27 11:17:04 -0700340"""""""""""""""""""""""""""""
341
Sean Condoneb95cd62021-08-04 19:44:18 +0100342While every effort has been made to ensure that securing Aether is simple and effective,
343some difficulties may arise.
344
345One of the most important steps is to validate that the OIDC Issuer (Dex server) can be reached
346from the browser. The **well_known** URL should be available and show the important endpoints are correct.
347
348.. image:: images/dex-ldap-umbrella-well-known.png
349 :width: 580
350 :alt: Dex Well Known page
351
352If logged out of the Browser when accessing the Aether ROC GUI, accessing any page of the application should
353redirect to the Dex login page.
354
355.. image:: images/dex-ldap-login-page.png
356 :width: 493
357 :alt: Dex Login page
358
359When logged in the User details can be seen by clicking the User's name in the drop down menu.
360This shows the **groups** that the user belongs to, and can be used to debug RBAC issues.
361
362.. image:: images/aether-roc-gui-user-details.png
363 :width: 700
364 :alt: User Details page
365
366When you sign out of the ROC GUI, if you are not redirected to the Dex Login Page,
367you should check the Developer Console of the browser. The console should show the correct
Zack Williams1ae109e2021-07-27 11:17:04 -0700368OIDC issuer (Dex server), and that Auth is enabled.
Sean Condoneb95cd62021-08-04 19:44:18 +0100369
370.. image:: images/aether-roc-gui-console-loggedin.png
371 :width: 418
372 :alt: Browser Console showing correct configuration
373
Scott Bakerb46a6ed2021-08-02 14:03:10 -0700374ROC Data Model Conventions and Requirements
375-------------------------------------------
376
377The MEGA-Patch described above will bring up a fully compliant sample data model.
378However, it may be useful to bring up your own data model, customized to a different
379site of sites. This subsection documents conventions and requirements for the Aether
Zack Williams1ae109e2021-07-27 11:17:04 -0700380modeling within the ROC.
Scott Bakerb46a6ed2021-08-02 14:03:10 -0700381
382The ROC models must be configured with the following:
383
384* A default enterprise with the id `defaultent`.
385* A default ip-domain with the id `defaultent-defaultip`.
386* A default site with the id `defaultent-defaultsite`.
387 This site should be linked to the `defaultent` enterprise.
388* A default device group with the id `defaultent-defaultsite-default`.
389 This device group should be linked to the `defaultent-defaultip` ip-domain
390 and the `defaultent-defaultsite` site.
391
392Each Enterprise Site must be configured with a default device group and that default
393device group's name must end in the suffix `-default`. For example, `acme-chicago-default`.
394
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700395Some exercises to get familiar
396------------------------------
397
Zack Williams1ae109e2021-07-27 11:17:04 -07003981. Deploy the ROC and POST the mega-patch, go into the ``aether-roc-gui`` and click
399 through the VCS, DeviceGroup, and other objects to see that they were
400 created as expected.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700401
Zack Williams1ae109e2021-07-27 11:17:04 -07004022. Examine the log of the ``sdcore-adapter-v3`` container. It should be
403 attempting to push the mega-patch’s changes. If you don’t have a core
404 available, it may be failing the push, but you should see the attempts.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700405
Zack Williams1ae109e2021-07-27 11:17:04 -07004063. Change an object in the GUI. Watch the ``sdcore-adapter-v3`` log file and
407 see that the adapter attempts to push the change.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700408
Zack Williams1ae109e2021-07-27 11:17:04 -07004094. Try POSTing a change via the API. Observe the ``sdcore-adapter-v3`` log
410 file and see that the adapter attempts to push the change.
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700411
Zack Williams1ae109e2021-07-27 11:17:04 -07004125. Deploy a 5G Aether-in-a-Box (See :doc:`Aether SD-Core Developer Guide
413 <sdcore>`), modify the mega-patch to specify the URL for the Aether-in-a-Box
414 ``webui`` container, POST the mega-patch, and observe that the changes were
415 correctly pushed via the ``sdcore-adapter-v3`` into the ``sd-core``’s
416 ``webui`` container (``webui`` container log will show configuration as it
417 is received)
Scott Bakerfab7c9e2021-07-29 17:12:16 -0700418
419.. |ROCGUI| image:: images/rocgui.png
Sean Condoneb95cd62021-08-04 19:44:18 +0100420 :width: 945
421 :alt: ROC GUI showing list of VCS