initial commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..8656b01
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,4 @@
+bin
+onos-apps
+pkg
+src
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..cd352ea
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright 2019 Ciena Corporation
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..bca537d
--- /dev/null
+++ b/README.md
@@ -0,0 +1,336 @@
+# Kubernetes Kind VOLTHA Test Environment
+This repository describes how to deploy a 4 node (one control plane and 
+
+## Prerequisites
+You must have both Docker and the Go programming language install for this
+test environment to function. How to get these working is beyond the scope
+of this document.
+
+## Fetch Tools
+```bash
+export GOPATH=$(pwd)
+GO111MODULE="on" go get sigs.k8s.io/kind@v0.4.0
+curl -L https://git.io/get_helm.sh | HELM_INSTALL_DIR=$(go env GOPATH)/bin bash
+go get github.com/ciena/voltctl/cmd/voltctl
+export PATH=$(go env GOPATH)/bin:$PATH
+```
+
+## Minimal v. Full
+This files contained in this repository can be used to deploy either a minimal
+or full voltha deployment. The difference is characterized in the following
+table:
+| RESOURCE                | MINIMAL       | FULL                      |
+| ----------------------- | ------------- | ------------------------- |
+| K8s Control Plane Nodes | 1             | 1                         |
+| K8s Workers             | 2             | 3                         |
+| EtcdOperator Components | Operator only | Operator, Backup, Restore |
+| EtcdCluster             | 1 Member      | 3 Members                 |
+
+Throughout this `README.md` file deployment and configuration files are
+referenced in the form **$TYPE-cluster.cfg** and **$TYPE-values.yaml**. 
+Depending on which type of deloyment you wish to install replace **$TYPE**
+with either **minimal** or **full**. If you set the environment variable to the
+desired deployment type, example below, then the commands can be executed via
+a simply copy and paste to your command line.
+```bash
+export TYPE=minimal
+```
+
+## Create Kubernetes Cluster
+Kind provides a command line control tool to easily create Kubernetes clusters
+using just a basic Docker envionrment. The following commands will create
+the desired deployment of Kubernetes and then configure your local copy of 
+`kubectl` to connect to this cluster.
+```bash
+kind create cluster --config $TYPE-cluster.cfg
+export KUBECONFIG="$(kind get kubeconfig-path --name="kind")"
+kubectl cluster-info
+```
+
+## Initialize Helm
+Helm provide a capabilty to install and manage Kubernetes applications. VOLTHA's
+default deployment mechanism utilized Helm. Before Helm can be used to deploy
+VOLTHA it must be initialized and the repositories that container the artifacts
+required to deploy VOLTHA must be added to Helm.
+```bash
+# Initialize Helm and add the required chart repositories
+helm init
+helm repo add incubator https://kubernetes-charts-incubator.storage.googleapis.com
+helm repo add stable https://kubernetes-charts.storage.googleapis.com
+helm repo add onf https://charts.opencord.org
+helm repo update
+
+# Create and k8s service account so that Helm can create pods
+kubectl create serviceaccount --namespace kube-system tiller
+kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller
+kubectl patch deploy --namespace kube-system tiller-deploy -p '{"spec":{"template":{"spec":{"serviceAccount":"tiller"}}}}'
+```
+
+## Install EtcdOperator
+ETCD Operator is a utility that allows applications to create and manage ETCD
+key/value clusters as Kubernetes resources. VOLTHA utilizes this utility to 
+create its key/value store. _NOTE: it is not required that VOLTHA create its
+own datastore as VOLTHA can utilize and existing datastore, but for this 
+example VOLTHA will creates its own datastore_
+```bash
+helm install -f $TYPE-values.yaml --namespace voltha --name etcd-operator stable/etcd-operator
+```
+
+### Wait for operator pods
+Before continuing the Kubernetes pods associated with ETCD Operator must be in 
+the `Running` state.
+```bash
+kubectl get -n voltha pod
+```
+
+Once all the pods are in the `Running` state the output, for a **full**
+deployment should be similar to the output below. For a **minimal** deployment
+there will only be a single pod, the `etcd-operator-etcd-operator-etcd-operator`
+pod.
+```bash
+NAME                                                              READY     STATUS    RESTARTS   AGE
+etcd-operator-etcd-operator-etcd-backup-operator-7897665cfq75w2   1/1       Running   0          2m
+etcd-operator-etcd-operator-etcd-operator-7d579799f7-bjdnj        1/1       Running   0          2m
+etcd-operator-etcd-operator-etcd-restore-operator-7d77d878wwcn7   1/1       Running   0          2m
+```
+
+## Install VOLTHA Core
+VOLTHA has two main _parts_: core and adapters. The **core** provides the main
+logic for the VOLTHA application and the **adapters** contain logic to adapter
+vendor neutral operations to vendor specific devices.
+
+Before any adapters can be deployed the VOLTHA core must be installed and in
+the `Running` state. The following Helm command installs the core components
+of VOLTHA based on the desired deployment type.
+```bash
+helm install -f $TYPE-values.yaml --namespace voltha --name voltha onf/voltha
+```
+
+During the install of the core VOLTHA components some containers may "crash" or
+restart. This is normal as there are dependencies, such as the read/write cores
+cannot start until the ETCD cluster is established and so they crash until the
+ETCD cluster is operational. Eventually all the containers should be in a
+`Running` state as queried by the command:
+```bash
+kubectl get -n voltha pod
+```
+
+The output should be similar to the following with a different number of
+`etcd-operator` and `voltha-etcd-cluster` pods depending on the deployment
+type.
+```bash
+NAME                                                         READY     STATUS    RESTARTS   AGE
+etcd-operator-etcd-operator-etcd-operator-7d579799f7-xq6f2   1/1       Running   0          19m
+ofagent-8ccb7f5fb-hwgfn                                      1/1       Running   0          4m
+ro-core-564f5cdcc7-2pch8                                     1/1       Running   0          4m
+rw-core1-7fbb878cdd-6npvr                                    1/1       Running   2          4m
+rw-core2-7fbb878cdd-k7w9j                                    1/1       Running   3          4m
+voltha-api-server-5f7c8b5b77-k6mrg                           2/2       Running   0          4m
+voltha-cli-server-5df4c95b7f-kcpdl                           1/1       Running   0          4m
+voltha-etcd-cluster-4rsqcvpwr4                               1/1       Running   0          4m
+voltha-kafka-0                                               1/1       Running   0          4m
+voltha-zookeeper-0                                           1/1       Running   0          4m
+```
+
+## Install Adapters
+The following commands install both the simulated OLT and ONU adapters as well
+as the adapters for an OpenOLT and OpenONU device.
+```bash
+helm install -f $TYPE-values.yaml --namespace voltha --name sim onf/voltha-adapter-simulated
+helm install -f $TYPE-values.yaml --namespace voltha --name open-olt onf/voltha-adapter-openolt
+helm install -f $TYPE-values.yaml --namespace voltha --name open-onu onf/voltha-adapter-openonu
+```
+
+## Exposing VOLTHA Services
+At this point VOLTHA is deployed and from within the Kubernetes cluster the
+VOLTHA services can be reached. However, from outside the Kubernetes cluster the
+services cannot be reached. 
+```bash
+screen -dmS voltha-api kubectl port-forward -n voltha service/voltha-api 55555:55555
+```
+
+## It is not just VOLTHA
+At this point the VOLTHA application is deployed but alone the VOLTHA
+application can do little. To demonstrate the capability of VOLTHA other
+_partner_ applications are required, such as ONOS. The followins sections
+describe how to install and configure these _partner_ applications.
+
+### ONOS (OpenFlow Controller)
+VOLTHA exposes an OLT and its connected ONUs as an OpenFlow switch. To control
+that virtual OpenFlow switch an OpenFlow controller is required. For most VOLTHA
+deployments that controller is ONOS with a set of ONOS applications installed.
+To install ONOS use the following Helm command:
+```bash
+helm install -f $TYPE-values.yaml --name onos onf/onos
+```
+
+#### Exposing ONOS Services
+```bash
+screen -dmS onos-ui kubectl port-forward service/onos-ui 8181:8181
+screen -dmS onos-ssh kubectl port-forward service/onos-ssh 8101:8101
+```
+
+#### Installing and Configuring ONOS Applications
+A script has been included, `install-onos-applications.sh`, that can be used
+to download and install the required applications into ONOS.
+```bash
+./onos-files/install-onos-applications.sh
+```
+
+## Configure `voltctl` to Connect to VOLTHA
+In order for `voltctl` to connect to the VOLTHA instance deplpoyed in the
+Kubernetes cluster it must know which IP address and port to use. This
+configuration can be persisted to a local config file using the following
+commands.
+```bash
+mkdir -p $HOME/.volt
+voltctl -a v2 -s localhost:55555 config > $HOME/.volt/config
+```
+
+To test the connectivity you can query the version of the VOLTHA client and
+server.
+```bash
+voltctl version
+```
+
+The output should be similar to the following
+```bash
+Client:
+ Version        unknown-version
+ Go version:    unknown-goversion
+ Vcs reference: unknown-vcsref
+ Vcs dirty:     unknown-vcsdirty
+ Built:         unknown-buildtime
+ OS/Arch:       unknown-os/unknown-arch
+
+Cluster:
+ Version        2.1.0-dev
+ Go version:    1.12.6
+ Vcs feference: 28f120f1f4751284cadccf73f2f559ce838dd0a5
+ Vcs dirty:     false
+ Built:         2019-06-26T16:58:22Z
+ OS/Arch:       linux/amd64
+```
+
+## Create and Enable a Simulated device
+Once all the containers are up and running, a simulated device to "test" the
+system can be created using the following command.
+```bash
+voltctl device create
+```
+
+_NOTE: If the device fails to create and an error message is displayed you may
+have hit an existing bug in onos. To work around this, use the
+`restart-api.sh` included in the repository. After running this script you will
+have to quit and restart the screen sesssion associated with the voltha-api._
+
+The output of the command will be the device ID. All the known devices can be
+listed with the following command.
+```bash
+voltctl device list
+```
+
+The output should be similar to the following
+```bash
+ID                          TYPE             ROOT    PARENTID    SERIALNUMBER    VLAN    ADMINSTATE        OPERSTATUS    CONNECTSTATUS
+1d5382581e2198ded3b9bcd8    simulated_olt    true                                0       PREPROVISIONED    UNKNOWN       UNKNOWN
+```
+
+To enable a device, specify the the device ID
+```bash
+voltctl device enable 1d5382581e2198ded3b9bcd8
+```
+
+When a device is enabled VOLTHA communicates with the device to discover the
+ONUs associated with the devices. Using the device and logicaldevice 
+sub-commands, `list` and `ports` the information VOLTHA discovered can be
+displayed.
+
+```bash
+$ voltctl device list
+ID                          TYPE             ROOT     PARENTID                    SERIALNUMBER           VLAN    ADMINSTATE    OPERSTATUS    CONNECTSTATUS
+1d5382581e2198ded3b9bcd8    simulated_olt    true     4F35373B6528                44.141.111.238:7941    0       ENABLED       ACTIVE        REACHABLE
+5660880ea2b602081b8203fd    simulated_onu    false    1d5382581e2198ded3b9bcd8    82.24.38.124:9913      101     ENABLED       ACTIVE        REACHABLE
+7ff85b36a13fdf98450b9d13    simulated_onu    false    1d5382581e2198ded3b9bcd8    204.200.47.166:9758    103     ENABLED       ACTIVE        REACHABLE
+bda9d3442e4cf93f9a58b1f2    simulated_onu    false    1d5382581e2198ded3b9bcd8    66.130.155.136:1448    100     ENABLED       ACTIVE        REACHABLE
+f546b18b101c287601d5a9dd    simulated_onu    false    1d5382581e2198ded3b9bcd8    72.157.213.155:5174    102     ENABLED       ACTIVE        REACHABLE
+
+$ voltctl device ports 1d5382581e2198ded3b9bcd8
+PORTNO    LABEL    TYPE            ADMINSTATE    OPERSTATUS    DEVICEID    PEERS
+2         nni-2    ETHERNET_NNI    ENABLED       ACTIVE                    []
+1         pon-1    PON_OLT         ENABLED       ACTIVE                    [{7ff85b36a13fdf98450b9d13 1} {bda9d3442e4cf93f9a58b1f2 1} {5660880ea2b602081b8203fd 1} {f546b18b101c287601d5a9dd 1}]
+
+$ voltctl logicaldevice list
+ID              DATAPATHID          ROOTDEVICEID                SERIALNUMBER           FEATURES.NBUFFERS    FEATURES.NTABLES    FEATURES.CAPABILITIES
+4F35373B6528    00004f35373b6528    1d5382581e2198ded3b9bcd8    44.141.111.238:7941    256                  2                   0x0000000f
+
+$ voltctl logicaldevice ports 4F35373B6528
+ID         DEVICEID                    DEVICEPORTNO    ROOTPORT    OPENFLOW.PORTNO    OPENFLOW.HWADDR      OPENFLOW.NAME    OPENFLOW.STATE    OPENFLOW.FEATURES.CURRENT    OPENFLOW.BITRATE.CURRENT
+nni-2      1d5382581e2198ded3b9bcd8    2               true        2                  4f:35:37:3b:65:28    nni-2            0x00000004        0x00001020                   32
+uni-103    7ff85b36a13fdf98450b9d13    103             false       103                0b:23:05:64:46:2b                     0x00000004        0x00001020                   32
+uni-100    bda9d3442e4cf93f9a58b1f2    100             false       100                68:05:4a:56:28:5b                     0x00000004        0x00001020                   32
+uni-101    5660880ea2b602081b8203fd    101             false       101                21:57:68:39:44:55                     0x00000004        0x00001020                   32
+uni-102    f546b18b101c287601d5a9dd    102             false       102                01:02:03:04:05:06                     0x00000004        0x00001020                   32
+```
+
+When a device is enabled VOLTHA also presents that devices as a virtual
+OpenFlow switch to ONOS. This can be seen in ONOS via the CLI and UI. ONOS, in
+turn, pushes flows down to the virual OpenFlow device, which can then be
+displayed via the `voltctl` command. Seeing flows in `voltctl` demonstrates that
+VOLTHA has successfully presented the OLT/ONUs as an virtual OpenFlow switch to
+ONOS and ONOS has been able to enfluence the OLT/ONU configuraton by assigning
+flows.
+
+```bash
+$ ssh -p 8101 karaf@localhost
+Password:
+Welcome to Open Network Operating System (ONOS)!
+     ____  _  ______  ____
+    / __ \/ |/ / __ \/ __/
+   / /_/ /    / /_/ /\ \
+   \____/_/|_/\____/___/
+
+Documentation: wiki.onosproject.org
+Tutorials:     tutorials.onosproject.org
+Mailing lists: lists.onosproject.org
+
+Come help out! Find out how at: contribute.onosproject.org
+
+Hit '<tab>' for a list of available commands
+and '[cmd] --help' for help on a specific command.
+Hit '<ctrl-d>' or type 'system:shutdown' or 'logout' to shutdown ONOS.
+
+onos> devices
+id=of:00004f35373b6528, available=true, local-status=connected 6m51s ago, role=MASTER, type=SWITCH, mfr=, hw=simulated_pon, sw=simulated_pon, serial=44.141.111.238:7941, chassis=4f35373b6528, driver=default, channelId=10.244.1.16:56302, managementAddress=10.244.1.16, protocol=OF_13
+onos> ^D
+onos>
+Connection to localhost closed.
+```
+
+```bash
+$ voltctl device flows 1d5382581e2198ded3b9bcd8
+ID                  TABLEID    PRIORITY    COOKIE       INPORT    VLANID    VLANPCP    ETHTYPE    METADATA              TUNNELID    SETVLANID    POPVLAN    PUSHVLANID    OUTPUT
+7504ed89e9db100f    0          40000       ~deb05c25    1         103                  0x888e                           103         4000                    0x8100        CONTROLLER
+2d0d9951533d886c    0          40000       0            2         4000      0                     0x0000000000000067    103                      yes                      1
+fa6b175a31b29ab2    0          40000       ~deb05c25    1         100                  0x888e                           100         4000                    0x8100        CONTROLLER
+211e554ad8933810    0          40000       0            2         4000      0                     0x0000000000000064    100                      yes                      1
+3c61b06b7140f699    0          40000       ~deb05c25    1         101                  0x888e                           101         4000                    0x8100        CONTROLLER
+faf13be01f7220fe    0          40000       0            2         4000      0                     0x0000000000000065    101                      yes                      1
+f0002ab45e5d9c0a    0          40000       ~deb05c25    1         102                  0x888e                           102         4000                    0x8100        CONTROLLER
+cb6506ce6cd5f815    0          40000       0            2         4000      0                     0x0000000000000066    102                      yes                      1
+1ba03e16bcc071eb    0          40000       ~2ab3e948    1         103                  0x0806                           103         4000                    0x8100        2
+18d6c34108732730    0          40000       ~2ab3e948    1         100                  0x0806                           100         4000                    0x8100        2
+c6a21ac1bc742efd    0          40000       ~2ab3e948    1         101                  0x0806                           101         4000                    0x8100        2
+a8346901fe5c6547    0          40000       ~2ab3e948    1         102                  0x0806                           102         4000                    0x8100        2
+
+$ voltctl logicaldevice flows 4F35373B6528
+ID                  TABLEID    PRIORITY    COOKIE       ETHTYPE    OUTPUT        CLEARACTIONS
+85df95ba0c6fbff3    0          40000       ~2ab3e948    0x0806     CONTROLLER    []
+dd6707b7a6ff74cf    0          40000       ~deb05c25    0x888e     CONTROLLER    []
+```
+
+## Teardown
+To remove the cluster simply use the `kind` command:
+```
+kind delete cluster
+```
diff --git a/full-cluster.cfg b/full-cluster.cfg
new file mode 100644
index 0000000..a2d6d71
--- /dev/null
+++ b/full-cluster.cfg
@@ -0,0 +1,21 @@
+# Copyright 2019 Ciena Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+kind: Cluster
+apiVersion: kind.sigs.k8s.io/v1alpha3
+nodes:
+- role: control-plane
+- role: worker
+- role: worker
+- role: worker
diff --git a/full-values.yaml b/full-values.yaml
new file mode 100644
index 0000000..73f8fb7
--- /dev/null
+++ b/full-values.yaml
@@ -0,0 +1,29 @@
+# Copyright 2019 Ciena Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+defaults:
+  image_tag: master
+
+onos_env:
+- name: POD_IP
+  valueFrom:
+  fieldRef:
+    fieldPath: status.podIP
+- name: NAMESPACE
+  valueFrom:
+  fieldRef:
+    fieldPath: metadata.namespace
+- name: ONOS_APPS
+  value: "drivers,openflow-base,hostprovider"
+
diff --git a/minimal-cluster.cfg b/minimal-cluster.cfg
new file mode 100644
index 0000000..63e6279
--- /dev/null
+++ b/minimal-cluster.cfg
@@ -0,0 +1,25 @@
+# Copyright 2019 Ciena Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+kind: Cluster
+apiVersion: kind.sigs.k8s.io/v1alpha3
+nodes:
+- role: control-plane
+  extraPortMappings:
+  - containerPort: 80
+    hostPort: 8080
+  - containerPort: 443
+    hostPort: 8443
+- role: worker
+- role: worker
diff --git a/minimal-values.yaml b/minimal-values.yaml
new file mode 100644
index 0000000..db83e46
--- /dev/null
+++ b/minimal-values.yaml
@@ -0,0 +1,36 @@
+# Copyright 2019 Ciena Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+defaults:
+  image_tag: master
+
+deployments:
+  etcdOperator: true
+  backupOperator: false
+  restoreOperator: false
+
+voltha-etcd-cluster:
+  clusterSize: 1
+
+onos_env:
+- name: POD_IP
+  valueFrom:
+  fieldRef:
+    fieldPath: status.podIP
+- name: NAMESPACE
+  valueFrom:
+  fieldRef:
+    fieldPath: metadata.namespace
+- name: ONOS_APPS
+  value: "drivers,openflow-base,hostprovider"
diff --git a/onos-files/dhcp-to-controller-flow.json b/onos-files/dhcp-to-controller-flow.json
new file mode 100644
index 0000000..f2d31a2
--- /dev/null
+++ b/onos-files/dhcp-to-controller-flow.json
@@ -0,0 +1,26 @@
+{
+  "priority": 40000,
+  "timeout": 0,
+  "isPermanent": true,
+  "deviceId": "of:0000000000000001",
+  "treatment": {
+    "instructions": [
+      {
+        "type": "OUTPUT",
+        "port": "CONTROLLER"
+      }
+    ]
+  },
+  "selector": {
+    "criteria": [
+      {
+        "type": "IN_PORT",
+        "port": 1
+      },
+      {
+        "type": "VLAN_VID",
+        "vlanId": 222
+      }
+    ]
+  }
+}
diff --git a/onos-files/install-onos-applications.sh b/onos-files/install-onos-applications.sh
new file mode 100755
index 0000000..fca199c
--- /dev/null
+++ b/onos-files/install-onos-applications.sh
@@ -0,0 +1,39 @@
+#!/usr/bin/env bash
+
+# Copyright 2019 Ciena Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+CONFIG_VER=1.4.0
+SADIS_VER=2.2.0
+OLT_VER=2.1.0
+AAA_VER=1.8.0
+DHCP_VER=1.5.0
+
+mkdir -p onos-files/onos-apps
+echo "Downloading ONOS applications"
+curl --fail -sSL https://repo.maven.apache.org/maven2/org/opencord/cord-config/$CONFIG_VER/cord-config-$CONFIG_VER.oar -o ./onos-files/onos-apps/cord-config-$CONFIG_VER.oar
+curl --fail -sSL https://repo.maven.apache.org/maven2/org/opencord/sadis-app/$SADIS_VER/sadis-app-$SADIS_VER.oar -o ./onos-files/onos-apps/sadis-app-$SADIS_VER.oar
+curl --fail -sSL https://repo.maven.apache.org/maven2/org/opencord/aaa/$AAA_VER/aaa-$AAA_VER.oar -o ./onos-files/onos-apps/aaa-$AAA_VER.oar
+curl --fail -sSL https://repo.maven.apache.org/maven2/org/opencord/olt-app/$OLT_VER/olt-app-$OLT_VER.oar -o ./onos-files/onos-apps/olt-app-$OLT_VER.oar
+curl --fail -sSL https://repo.maven.apache.org/maven2/org/opencord/dhcpl2relay/$DHCP_VER/dhcpl2relay-$DHCP_VER.oar -o ./onos-files/onos-apps/dhcpl2relay-$DHCP_VER.oar
+
+until test $(curl -w '\n%{http_code}' --fail -sSL --user karaf:karaf -X POST -H Content-Type:application/octet-stream http://127.0.0.1:8181/onos/v1/applications?activate=true --data-binary @./onos-files/onos-apps/cord-config-$CONFIG_VER.oar 2>/dev/null | tail -1) -eq 409; do echo "Installing 'CONFIG' ONOS application ..."; sleep 1; done
+until test $(curl -w '\n%{http_code}' --fail -sSL --user karaf:karaf -X POST -H Content-Type:application/octet-stream http://127.0.0.1:8181/onos/v1/applications?activate=true --data-binary @./onos-files/onos-apps/sadis-app-$SADIS_VER.oar 2>/dev/null | tail -1) -eq 409; do echo "Installing 'SADIS' ONOS application ..."; sleep 1; done
+until test $(curl -w '\n%{http_code}' --fail -sSL --user karaf:karaf -X POST -H Content-Type:application/octet-stream http://127.0.0.1:8181/onos/v1/applications?activate=true --data-binary @./onos-files/onos-apps/olt-app-$OLT_VER.oar 2>/dev/null | tail -1) -eq 409; do echo "Installing 'OLT' ONOS application ..."; sleep 1; done
+until test $(curl -w '\n%{http_code}' --fail -sSL --user karaf:karaf -X POST -H Content-Type:application/octet-stream http://127.0.0.1:8181/onos/v1/applications?activate=true --data-binary @./onos-files/onos-apps/aaa-$AAA_VER.oar 2>/dev/null | tail -1) -eq 409; do echo "Installing 'AAA' ONOS application ..."; sleep 1; done
+until test $(curl -w '\n%{http_code}' --fail -sSL --user karaf:karaf -X POST -H Content-Type:application/octet-stream http://127.0.0.1:8181/onos/v1/applications?activate=true --data-binary @./onos-files/onos-apps/dhcpl2relay-$DHCP_VER.oar 2>/dev/null | tail -1) -eq 409; do echo "Installing 'DHCP L2 Relay' ONOS application ..."; sleep 1; done
+until test $(curl -w '\n%{http_code}' --fail -sSL --user karaf:karaf -X POST -H Content-Type:application/json http://127.0.0.1:8181/onos/v1/network/configuration --data @onos-files/olt-onos-netcfg.json 2>/dev/null | tail -1) -eq 200; do echo "Configuring VOLTHA ONOS ..."; sleep 1; done
+until test $(curl -w '\n%{http_code}' --fail -sSL --user karaf:karaf -X POST -H Content-Type:application/json http://127.0.0.1:8181/onos/v1/configuration/org.opencord.olt.impl.Olt --data @onos-files/olt-onos-olt-settings.json 2>/dev/null | tail -1) -eq 200; do echo "Enabling VOLTHA ONOS DHCP provisioning..."; sleep 1; done
+until test $(curl -w '\n%{http_code}' --fail -sSL --user karaf:karaf -X POST -H Content-Type:application/json http://127.0.0.1:8181/onos/v1/configuration/org.onosproject.net.flow.impl.FlowRuleManager --data @onos-files/olt-onos-enableExtraneousRules.json 2>/dev/null | tail -1) -eq 200; do echo "Enabling extraneous rules for ONOS..."; sleep 1; done
+until test $(curl -w '\n%{http_code}' --fail -sSL --user karaf:karaf -X POST -H Content-Type:application/json 'http://127.0.0.1:8181/onos/v1/flows/of:0000000000000001?appId=env.voltha' --data @onos-files/dhcp-to-controller-flow.json 2>/dev/null | tail -1) -eq 201; do echo "Establishing DHCP packet-in flow ..."; sleep 1; done
diff --git a/onos-files/olt-onos-enableExtraneousRules.json b/onos-files/olt-onos-enableExtraneousRules.json
new file mode 100644
index 0000000..0ba1863
--- /dev/null
+++ b/onos-files/olt-onos-enableExtraneousRules.json
@@ -0,0 +1,3 @@
+{
+ "allowExtraneousRules": true
+}
diff --git a/onos-files/olt-onos-netcfg.json b/onos-files/olt-onos-netcfg.json
new file mode 100644
index 0000000..6fd4486
--- /dev/null
+++ b/onos-files/olt-onos-netcfg.json
@@ -0,0 +1,53 @@
+{
+  "devices": {
+    "of:0000aabbccddeeff": {
+      "basic": {
+        "driver": "voltha"
+      }
+    }
+  },
+  "apps": {
+    "org.opencord.aaa": {
+      "AAA": {
+        "radiusIp": "10.1.5.3",
+        "nasIp": "10.1.5.3",
+        "radiusServerPort": "1812",
+        "radiusSecret": "SECRET"
+      }
+    },
+    "org.opencord.sadis": {
+      "sadis": {
+        "integration": {
+          "cache": {
+            "enabled": false,
+            "maxsize": 50,
+            "ttl": "PT0m"
+          }
+        },
+        "entries": [
+          {
+            "id": "PSMO12345678",
+            "cTag": 111,
+            "sTag": 222,
+            "nasPortId": "",
+            "circuitId": "",
+            "remoteId": ""
+          },
+          {
+            "id": "10.1.4.4:50060",
+            "hardwareIdentifier": "aa:bb:cc:dd:ee:ff",
+            "ipAddress": "10.233.111.16",
+            "nasId": "10.1.4.4:50060",
+            "uplinkPort": 2
+          }
+        ]
+      }
+    },
+    "org.opencord.dhcpl2relay": {
+      "dhcpl2relay" : {
+        "dhcpServerConnectPoints" : [ "of:0000000000000001/1" ],
+        "useOltUplinkForServerPktInOut" : false
+      }
+    }
+  }
+}
diff --git a/onos-files/olt-onos-olt-settings.json b/onos-files/olt-onos-olt-settings.json
new file mode 100644
index 0000000..f70077d
--- /dev/null
+++ b/onos-files/olt-onos-olt-settings.json
@@ -0,0 +1,4 @@
+{
+ "enableDhcpOnProvisioning" : true,
+ "defaultVlan" : 65535
+}
diff --git a/restart-api.sh b/restart-api.sh
new file mode 100755
index 0000000..487b3ec
--- /dev/null
+++ b/restart-api.sh
@@ -0,0 +1,28 @@
+#!/usr/bin/env bash
+
+# Copyright 2019 Ciena Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+echo "Scaling down voltha-api-server and ofagent"
+(set -x; kubectl scale --replicas=0 deployment -n voltha voltha-api-server ofagent)
+echo "Waiting for PODS to be terminated"
+echo -n "Waiting "
+until [ $(kubectl -n voltha get pods -o name | grep -c voltha-api-server) -eq 0 ]; do echo -n "."; sleep 3; done
+until [ $(kubectl -n voltha get pods -o name | grep -c ofagent) -eq 0 ]; do echo -n "."; sleep 3; done
+echo " Terminated"
+
+echo "Scaling up voltha-api-server and ofagent"
+(set -x; kubectl scale --replicas=1 deployment -n voltha voltha-api-server ofagent)
+
+