[SDFAB-590] - Update deployment doc and config pusher

Change-Id: I3a5540ae9f354af4f6115ba5e9504dcd1ea2feab
diff --git a/configuration.rst b/configuration.rst
index d8b26ef..01e23af 100644
--- a/configuration.rst
+++ b/configuration.rst
@@ -9,3 +9,64 @@
    configuration/network
    configuration/component
    configuration/chassis
+
+Configuration Pusher
+--------------------
+
+Once the SD-Fabric has been deployed to the Kubernetes, a special Kubernetes
+pod, config pusher will enter to a reconciliation loop to update both
+network configuration and component configuration to ONOS controller.
+
+Config pusher will read running state from ONOS controller and
+then update the ONOS with desired state if running state isn't same as desired state.
+
+.. image:: images/config-pusher.svg
+
+.. note::
+   We highly recommend using the Helm Chart to update the configuration instead of manually changing the ONOS unless you're working on debugging or testing.
+
+Config Pusher supports variety options to adjust its behavior and you can change it via Helm Chart's value file.
+
+Below is the default values of config pusher and please change it to meet your environment.
+
+
+.. code-block::
+
+      onos:
+        config:
+          reconcile_mode: true
+          reconcile_interval: 30s
+          image:
+            registry: ""
+            repository: opencord/onos-classic-helm-utils
+            tag: 0.1.0
+            pullPolicy: "IfNotPresent"
+          service_account_name: onos-config-loader
+          # NOTE that these values won't change the configuration in the ONOS container, they are only used in the script that loads the config
+          username: karaf
+          password: karaf
+          # netcfg: >
+          #  {}
+          # componentConfig:
+          #   "org.onosproject.provider.lldp.impl.LldpLinkProvider": >
+          #     {
+          #       "enabled": "false"
+          #     }
+
+
+* ``reconcile_mode``: If disable, config pusher will only update the configuration once, it's useful for debugging.
+* ``reconcile_interval``: The interval(seconds) config pusher used to perform reconciliation loop.
+* ``image``: About how to pull config pusher's container image, keep it default unless you have special requirement.
+
+  * ``registry``: If empty, the config pusher image will be downloaded from Docker Hub.
+  * ``repository``: The repository of config push.
+  * ``tag``: The image tag of config pusher.
+  * ``pullPolicy``: How Kubernetes pull the image, available options are `Never, Always, IfNotPresent`.
+
+* ``service_account_name``: Name of the Kubernetes Service Account, config pusher pods needs the permission to read
+  information from Kubernetes.
+* ``username``: Username is used to access ONOS,
+* ``password``: Password is used to access ONOS.
+* ``netcfg``: Json data for network configuration.
+* ``componentConfig``: A map contains "component-name": "json config" that will be iterated
+  over and sent via POST to ONOS.
diff --git a/deployment.rst b/deployment.rst
index 4419e62..9dc50f9 100644
--- a/deployment.rst
+++ b/deployment.rst
@@ -1,2 +1,114 @@
+..
+   SPDX-FileCopyrightText: © 2020 Open Networking Foundation <support@opennetworking.org>
+   SPDX-License-Identifier: Apache-2.0
+
 Deployment Guide
 ================
+
+
+Provision Switches
+------------------
+
+We follow Open Network Install Environment(ONIE) way to install Open Network Linux (ONL) image to switch.
+To work with the SD-Fabric environment, we have customized the ONL image to support related packages and dependencies.
+
+Image source file can be found on ONF repository `opennetworkinglab/OpenNetworkLinux <https://github.com/opennetworkinglab/OpenNetworkLinux>`_.
+You can also download pre-compiled artifacts from `Github Release page <https://github.com/opennetworkinglab/OpenNetworkLinux/releases>`_
+
+
+.. note::
+    If you're not familiar with ONIE/ONL environment, please check `Getting Started <https://github.com/opencomputeproject/OpenNetworkLinux/blob/master/docs/GettingStarted.md>`_ to
+    see how to install the ONL image to an ONIE supported switch.
+
+Below is an example about how to install the ONL image.
+
+1. Prepare a server which is accessible by the switch and then download the
+pre-compiled installer from the release page.
+
+.. code-block::
+
+   wget https://github.com/opennetworkinglab/OpenNetworkLinux/releases/download/v1.4.3/ONL-onf-ONLPv2_ONL-OS_2021-07-16.2159-5195444_AMD64_INSTALLED_INSTALLER
+   python -m http.server 8080
+
+2. Reboot the switch to enter ONIE installation mode
+
+.. note::
+    Please access the switch via BMC or serial console to keep connection during the installation.
+
+
+.. code-block::
+
+   onl-onie-boot-mode rescue; reboot
+
+3. Install ONL installer
+
+.. code-block::
+
+   onie-nos-install http://$SERVER_IP:8080/ONL-onf-ONLPv2_ONL-OS_2021-07-16.2159-5195444_AMD64_INSTALLED_INSTALLER
+
+4. Setup switch IP and hostname after the installation.
+
+
+Kubernetes Environment
+----------------------
+
+Our `ONL <https://github.com/opennetworkinglab/OpenNetworkLinux>`_ version
+includes all packages required by running the Kubernetes on top of it.
+Once the Kubernetes is ready, the `Stratum <https://opennetworking.org/stratum/>`_ application will be deployed to the switch to manage it.
+
+Unlike server, switch has less CPU and memory resources and we should avoid
+deploying unnecessary workloads into switch.
+Besides, the Stratum application should only be deployed to all switches.
+
+To achieve the above goals, please apply the resources to your Kubernetes cluster.
+
+1. Set up Label to all switch node, e.g ``node-role.kubernetes.io=switch``
+2. Set up Taint with ``NoSchedule`` to all switch node, e.g ``node-role.kubernetes.io=switch:NoSchedule``
+3. Properly configure the ``NodeSelector`` and ``Toleration`` when deploying Stratum via DaemonSet
+
+Example of a five nodes Kubernetes cluster, two switches and three servers
+
+.. code-block::
+
+     ╰─$ kubectl get node -o custom-columns=NAME:.metadata.name,TAINT:.spec.taints
+     NAME       TAINT
+     compute1   <none>
+     compute2   <none>
+     compute3   <none>
+     leaf1      [map[effect:NoSchedule key:node-role.kubernetes.io value:switch]]
+     leaf2      [map[effect:NoSchedule key:node-role.kubernetes.io value:switch]]
+     ╰─$ kubectl get nodes -lnode-role.kubernetes.io=switch                                                                                                             130 ↵
+     NAME    STATUS   ROLES    AGE   VERSION
+     leaf1   Ready    worker   27d   v1.18.8
+     leaf2   Ready    worker   27d   v1.18.8
+
+
+# TODO
+Build Image
+-----------
+
+Fetch Images From Private Registry
+----------------------------------
+
+Container images can be download from ONF self-hosted container registry but you have to gain the access token first.
+
+1. Login to `Aether Harbor Registry <https://registry.aetherproject.org/harbor/sign-in?redirect_url=%2Fharbor%2Fprojects>`_ using your ONF Crowd credential,
+2. Select ``User Profile`` drop-down menu in the upper-right corner
+3. Generate the CLI secret and it's the secret token you have to access the container registry via CLI tool.
+4. Login to the container registry with your username and access token
+   by ``docker login command`` to ensure you can access it.
+
+.. code-block::
+
+      ╰─$ docker login registry.aetherproject.org --username hwchiu                                                                                                          255 ↵
+      Password:
+      Login Succeeded
+
+
+Please follow the `Kubernetes official document <https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/>`_ to see how to
+download the image from the private registry with a valid credential
+
+
+# TODO, wait for the umbrella chart
+Install SD-Fabric
+-----------------
diff --git a/dict.txt b/dict.txt
index 0576d63..661dec5 100644
--- a/dict.txt
+++ b/dict.txt
@@ -18,6 +18,7 @@
 Netlink
 NxM
 ONF
+ONIE
 OpenConfig
 PFCP
 Pre
@@ -60,9 +61,11 @@
 gNOI
 gRPC
 gatewayIP
+hostname
 hyperscalers
 instantiation
 ip
+json
 keepalives
 lifecycle
 linecard
@@ -79,10 +82,11 @@
 pipeconf
 pipeconfs
 pluggable
+pre
 programmability
 protobuf
-recirculation
 reStructuredText
+recirculation
 routable
 scalability
 scalable
@@ -97,7 +101,7 @@
 unicast
 untagged
 uplink
-virtualenv
 vRouter
 verifiability
+virtualenv
 whitepaper
diff --git a/images/config-pusher.svg b/images/config-pusher.svg
new file mode 100644
index 0000000..d82605f
--- /dev/null
+++ b/images/config-pusher.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="402px" height="230px" viewBox="-0.5 -0.5 402 230" content="&lt;mxfile host=&quot;Electron&quot; modified=&quot;2021-10-05T23:49:44.430Z&quot; agent=&quot;5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/15.3.7 Chrome/93.0.4577.63 Electron/14.0.1 Safari/537.36&quot; etag=&quot;coMMEweBIdqTiL2q_kJ-&quot; version=&quot;15.3.7&quot; type=&quot;device&quot;&gt;&lt;diagram id=&quot;yaYsB4gJezcaPKQ2ly58&quot; name=&quot;Page-1&quot;&gt;7VjbctowEP0aHpPxBRvyGAgk02maTEmnzaOCha1GaKksA87Xd21LvnAbMoGUZsJDYh3tyvKeo+OFltufLq8lmUW3EFDecqxg2XKvWo5z0fbxbwakBeC1LwoglCwoILsCRuyFatDSaMICGjcCFQBXbNYExyAEHasGRqSERTNsArx51xkJ6RowGhO+jv5kgYoKtOtZFX5DWRiZO9uWnpkSE6yBOCIBLGqQO2i5fQmgiqvpsk95VjtTlyJvuGW23JikQu2T8DBvP3x5Yd7DzeP18613BqFIzzQ7sUrNA9MAn18PQaoIQhCEDyq0JyERAc1WtXBUxXwFmCFoI/ibKpVqMkmiAKFITbmepUumfmXp554ePdZmrpZ65XyQ6sEEhNIL2m097gMHme/a7To91/cRj5WE55IqLHKveMLssbYWTkMxJHJMd1TLLmlDuVOYUiVTzJOUE8XmzfWJFl5YxpWp98Dwzo6lz4jb1QrRR8Qx4jJLKCJDqnRWxTBe1LZRQTnvr9CA3vCc8EQ/QsvxudJFzs+WqbP/J8nkijV1rfxTh/xQ/89znwzQBzFhIS5zn8QRlWYet/q0moNYcUsDr2izqbxFxBQdzUhO2QLdp6myfRUzp1IxPPCXnIUC56YsCHKdr0upQGqLDIc9r2OVW82WosvdMluXj5GB05SB3dbjReU7tomJap7jW9sV19DKa4Xh/S/mgBWWaS0pG5ZZ2aBKy0cnZSqOfqvlh3xHnPtG83mTFJzjesQVjZlE1TjWSBFFP5RHdAaX/uBAHmGvviq6/9oj2qfjEaUtvMojKlc4YY9w9/QI5xANyqWUJK0FzLLGI97ev3j25v5luCW+7G82x+NFsYODNjnukZucROasfhrYbgNr+6dmYJ2DCuOeygnI6b5cYyFVk9Bm9QWIjKQJ43wFIprIMRYem+odDG9SUFNj+4roEE3u6gvMXue/u4F+51j0dw9K/3dKsiZGJkIwEeZc525gTSSgKKy7b3ejT21s0YbT6Zx7G98MdXU4lveO8rg4qDx+zIJCDtjQfIphtxj8phTcDd+GsdDvKAXjVFu1YCxgDGLMOMOOCwTG513tR6J5OHTxY+L05u1jcG4dj3McVj+9Fk1m9fu1O/gL&lt;/diagram&gt;&lt;/mxfile&gt;"><defs/><g><path d="M 201 61 L 201 102.76" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 201 108.76 L 197 100.76 L 201 102.76 L 205 100.76 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/><rect x="141" y="1" width="120" height="60" fill="#ffffff" stroke="#ffb570" stroke-width="2" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 31px; margin-left: 142px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(130, 179, 102); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font color="#000000"><b>Config Pusher</b></font></div></div></div></foreignObject><text x="201" y="35" fill="#82B366" font-family="Helvetica" font-size="14px" text-anchor="middle">Config Pusher</text></switch></g><path d="M 61 201 L 61 221 L 341 221 L 341 209.24" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 341 203.24 L 345 211.24 L 341 209.24 L 337 211.24 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/><rect x="1" y="141" width="120" height="60" fill="#ffffff" stroke="#7ea6e0" stroke-width="2" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 171px; margin-left: 2px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(130, 179, 102); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font color="#000000"><b>Desired State</b></font></div></div></div></foreignObject><text x="61" y="175" fill="#82B366" font-family="Helvetica" font-size="14px" text-anchor="middle">Desired State</text></switch></g><path d="M 341 141 L 341 111 L 331 111 L 61 111 L 61 132.76" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke"/><path d="M 61 138.76 L 57 130.76 L 61 132.76 L 65 130.76 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all"/><rect x="281" y="141" width="120" height="60" fill="#ffffff" stroke="#7ea6e0" stroke-width="2" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 171px; margin-left: 282px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(130, 179, 102); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font color="#000000"><b>Current State</b></font></div></div></div></foreignObject><text x="341" y="175" fill="#82B366" font-family="Helvetica" font-size="14px" text-anchor="middle">Current State</text></switch></g><rect x="201" y="71" width="80" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 81px; margin-left: 202px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(130, 179, 102); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font color="#000000">Perform</font></div></div></div></foreignObject><text x="241" y="85" fill="#82B366" font-family="Helvetica" font-size="14px" text-anchor="middle">Perform</text></switch></g><rect x="98.5" y="111" width="205" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 203px; height: 1px; padding-top: 121px; margin-left: 100px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(130, 179, 102); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font color="#000000">Read running state from ONOS</font></div></div></div></foreignObject><text x="201" y="125" fill="#82B366" font-family="Helvetica" font-size="14px" text-anchor="middle">Read running state from ONOS</text></switch></g><rect x="86" y="201" width="230" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 228px; height: 1px; padding-top: 211px; margin-left: 87px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(130, 179, 102); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"><font color="#000000">Update to ONOS</font></div></div></div></foreignObject><text x="201" y="215" fill="#82B366" font-family="Helvetica" font-size="14px" text-anchor="middle">Update to ONOS</text></switch></g><rect x="86" y="161" width="230" height="20" fill="none" stroke="none" pointer-events="all"/><g transform="translate(-0.5 -0.5)"><switch><foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 228px; height: 1px; padding-top: 171px; margin-left: 87px;"><div style="box-sizing: border-box; font-size: 0px; text-align: center;"><div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(255, 51, 51); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; overflow-wrap: normal;"><font>Reconciliation Loop</font></div></div></div></foreignObject><text x="201" y="175" fill="#FF3333" font-family="Helvetica" font-size="14px" text-anchor="middle" font-weight="bold">Reconciliation Loop</text></switch></g></g><switch><g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/><a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank"><text text-anchor="middle" font-size="10px" x="50%" y="100%">Viewer does not support full SVG 1.1</text></a></switch></svg>