CORD-3162 exampleservice documentation
Change-Id: I637b059fae037fafed2cf4515044e52773495edd
diff --git a/docs/example-service.md b/docs/example-service.md
new file mode 100644
index 0000000..d191f58
--- /dev/null
+++ b/docs/example-service.md
@@ -0,0 +1,143 @@
+# ExampleService #
+
+`ExampleService` is a service intended to demonstrate integration with the XOS `openstack` service. `ExampleService` provides a `ExampleServiceInstance` model that generates and hosts a web page, displaying two text strings on the web page: a `service_message` and a `tenant_message`. Each time a `ExampleServiceInstance` is created, a corresponding `Instance` will also be created which will in turn cause an OpenStack VM to be created that runs an apache web server hosting the web page.
+
+Destroying the `ExampleServiceInstance` will cause the linked `Instance` to also be destroyed, which will in turn cause the OpenStack VM to be cleaned up.
+
+## Implementation ##
+
+Inside the `ExampleService` repository's `xos/synchronizer` directory, there are three key parts to the service.
+
+1. The `models` directory. This directory contains the models that comprise `ExampleService`. The full text of the models are specified in a file, `exampleservice.xproto`. A summary of the models is below:
+
+ * `ExampleService` holds global service-wide settings, including a `service_message`, which appears in all web pages generated by `ExampleService`, and a `service_secret` that is installed into all container that run the web servers.
+
+ * `ExampleServiceInstance` holds per-tenant settings, including a `tenant_message`. Each `ExampleServiceInstance` corresponds to one web server serving one web page. This model has relations for `foreground_color` and `background_color` that allow some additional customization of the served page. `tenant_secret` is a secret that is installed into the container running the web server
+
+ * `Color` implements the color model used by the `foreground_color` and `background_color` fields of `SimpleExampleServiceInstance`.
+
+ * `EmbeddedImage` allows embedded images to be attached to web pages. As the foreign key relation is from the embedded image to the service instance, this forms a many-to-one relation that allows many images to be attached to a single web page.
+
+2. The `model_policies` directory contains a model policy. This model policy is reponsible for automatically creating and deleting the `Instance` associated with each `ExampleServiceInstance`.
+
+3. The `sync_steps` directory contains a sync step that uses Ansible to provision the web server and configure the web page.
+
+## Demonstration ##
+
+The following subsections work through a quick demonstration of `ExampleService`.
+
+### Prerequisites ###
+
+This document assumes that you have already installed [OpenStack-helm](../prereqs/openstack-helm).
+
+> Note: Depending on the method that was used to deploy your Kubernetes installation, your installation may require root privilege to interact with Kubernetes. If so, then you may need to use `sudo` with many of the commands in this tutorial, for example `sudo helm init` instead of `helm init`.
+
+### Simulating fabric Internet connectivity ###
+
+The `ExampleServiceInstance` sync step requires connectivity to the public Internet so that it can fetch some apt packages. In order to support this, it's necessary that your fabric is properly connected to the Internet. This subsection describes how to setup a simulated fabric bridge, for example on a bare metal Ubuntu machine. If your deployment contains a physical fabric with Internet connectivity already, then you may skip this subsection.
+
+First we need to setup the fabric bridge. Make sure to replace `my.host.name` with the hostname of your head node.
+
+```shell
+# Create an inventory file.
+cd ~/cord/automation-tools/interface-config
+cat > my_inventory.yaml <<EOF
+all:
+ hosts:
+ my.host.name:
+ fabric_net_ip_cidr: "10.8.1.1/24"
+EOF
+
+# Run playbook to setup fabric bridge
+ansible-playbook -v -i my_inventory.yaml prep-interfaces-playbook.yaml
+```
+
+> Note: Some environments do not like network interface files with dots in the name and/or place their interface files in unusual locations. If you have errors running the above playbook, then the following modifications to the playbook may be useful: `sed -i -e "s:/etc/network/interfaces.d:/etc/interfaces.d:g" roles/interface-config/tasks/main.yml` and `sed -i -e "s:/etc/interfaces.d/fabric.cfg:/etc/interfaces.d/fabriccfg:g" roles/interface-config/tasks/main.yml`.
+
+After the playbook has successfully completed, it's time to setup a veth pair. The reason for this is that VTN will place packets onto the fabric interface, but without a veth pair, those packets will never be "received" by Linux, and therefore never have an opportunity to be forwarded and masqueraded. The following commands set up the veth pair:
+
+```shell
+sudo ip link add fabricveth1 type veth peer name fabricveth2
+sudo ip link set fabricveth2 address a4:23:05:06:01:01
+sudo ifconfig fabricveth2 10.8.1.1/24 up
+sudo ifconfig fabricveth1 up
+sudo brctl addif fabricbridge fabricveth1
+```
+
+We also need to enable masquerade so the packets will be NATed. In our case the physical ethernet device is `eno1`. Adjust for your configuration as necessary:
+
+```shell
+sudo iptables -t nat -A POSTROUTING -o eno1 -j MASQUERADE
+```
+
+### Deploy the necessary profiles ###
+
+It's necessary for us to deploy three helm charts, `xos-core`, `base-openstack`. and `demo-exampleservice`.
+
+> Note: If you've already installed a different set of XOS profile helm charts, such as the `base-openstack` profile or the `mcord` profile, then it will be necessary to first delete those helm charts (using `helm del --purge <chartname>`). Please also delete the `onos-cord` chart. Deleting and redeploying these charts is recommended so that the new fabric bridge configuration is used in VTN.
+
+```bash
+# Go into the helm-charts repository
+cd ~/cord/helm-charts
+
+# Initialize helm
+helm init
+
+# Install the onos-cord helm chart
+helm dep update onos
+helm install onos -n onos-cord
+
+# Install the xos-core helm chart
+helm dep update xos-core
+helm install xos-core -n xos-core
+
+# Install the base-openstack helm chart
+helm dep update xos-profiles/base-openstack
+helm install xos-profiles/base-openstack -n base-openstack \
+ --set computeNodes.master.name="$( hostname )" \
+ --set vtn-service.sshUser="$( whoami )" \
+ --set computeNodes.master.dataPlaneIntf=fabricbridge
+
+# Install the demo-exampleservice helm chart
+helm dep update xos-profiles/demo-exampleservice
+helm install xos-profiles/demo-exampleservice -n demo-exampleservice \
+ --set global.proxySshUser="$( whoami )"
+```
+
+The helm charts above install successive layers of CORD. The first chart, `xos-core` installs core components such as the XOS core, database, TOSCA engine, etc. The second chart, `base-openstack` installs the XOS OpenStack Service, which provides modeling and synchronizers for instantiating OpenStack resources using the XOS data model. The argument `--set computeNodes.master.dataPlaneIntf=fabricbridge` was passed to helm when deploying the `base-openstack` helm chart, causing the fabricbridge device to be used instead of the default.
+
+The final helm chart, `demo-exampleservice` installs the synchronizer for `ExampleService`, including registering models with the core.
+
+> Note: It will take some time for the various helm charts to deploy and the containers to come online. We recommend using `kubectl get pods` to explore the state of the system during deployment. In particular, note the presence of `tosca-loader` containers. These containers are responsible for running TOSCA that configures services in the stack. The `tosca-loaders` may error and retry several times as they wait for services to be dynamically loaded. This is normal, and eventually the `tosca-loader` containers will enter the `Completed` state.
+
+Use `kubectl get pods` to verify that all containers in the profile are successful and none are in error state. At this point, we've installed all of the necessary infrastructure to support `ExampleService`. The chart also automatically creates an `ExampleServiceInstance` and the OpenStack synchronizer will bring up a VM.
+
+### Wait for OpenStack VM to be created ###
+
+Issue the following commands:
+
+```shell
+export OS_CLOUD=openstack_helm
+openstack server list --all-projects
+```
+
+It may take some time for the instance to be created, but eventually you will see an instance, for example `exampleservice-1`. Note the management IP address of that instance.
+
+### SSH into the VM ###
+
+```shell
+# adjust ssh key permissions
+cp ~/cord/helm-charts/xos-services/exampleservice/files/id_rsa ~/exampleservice_rsa
+chmod 0600 ~/exampleservice_rsa
+
+# ssh into the VM
+ssh -i ~/exampleservice_rsa ubuntu@<management-ip-of-vm>
+```
+
+You can view the created web page by doing the following:
+
+```shell
+curl http://localhost/
+```
+
+You should see a web page that contains "hello" and "world" strings embedded in it.