Merge branch 'master' of github.com:open-cloud/xos
diff --git a/containers/nagios/Dockerfile b/containers/nagios/Dockerfile
new file mode 100644
index 0000000..c33f71c
--- /dev/null
+++ b/containers/nagios/Dockerfile
@@ -0,0 +1,63 @@
+FROM cpuguy83/ubuntu
+ENV NAGIOS_HOME /opt/nagios
+ENV NAGIOS_USER nagios
+ENV NAGIOS_GROUP nagios
+ENV NAGIOS_CMDUSER nagios
+ENV NAGIOS_CMDGROUP nagios
+ENV NAGIOSADMIN_USER nagiosadmin
+ENV NAGIOSADMIN_PASS nagios
+ENV APACHE_RUN_USER nagios
+ENV APACHE_RUN_GROUP nagios
+ENV NAGIOS_TIMEZONE UTC
+
+RUN sed -i 's/universe/universe multiverse/' /etc/apt/sources.list
+RUN apt-get update && apt-get install -y iputils-ping netcat build-essential snmp snmpd snmp-mibs-downloader php5-cli apache2 libapache2-mod-php5 runit bc postfix bsd-mailx
+RUN ( egrep -i  "^${NAGIOS_GROUP}" /etc/group || groupadd $NAGIOS_GROUP ) && ( egrep -i "^${NAGIOS_CMDGROUP}" /etc/group || groupadd $NAGIOS_CMDGROUP )
+RUN ( id -u $NAGIOS_USER || useradd --system $NAGIOS_USER -g $NAGIOS_GROUP -d $NAGIOS_HOME ) && ( id -u $NAGIOS_CMDUSER || useradd --system -d $NAGIOS_HOME -g $NAGIOS_CMDGROUP $NAGIOS_CMDUSER )
+
+ADD http://downloads.sourceforge.net/project/nagios/nagios-3.x/nagios-3.5.1/nagios-3.5.1.tar.gz?r=http%3A%2F%2Fwww.nagios.org%2Fdownload%2Fcore%2Fthanks%2F%3Ft%3D1398863696&ts=1398863718&use_mirror=superb-dca3 /tmp/nagios.tar.gz
+RUN cd /tmp && tar -zxvf nagios.tar.gz && cd nagios  && ./configure --prefix=${NAGIOS_HOME} --exec-prefix=${NAGIOS_HOME} --enable-event-broker --with-nagios-command-user=${NAGIOS_CMDUSER} --with-command-group=${NAGIOS_CMDGROUP} --with-nagios-user=${NAGIOS_USER} --with-nagios-group=${NAGIOS_GROUP} && make all && make install && make install-config && make install-commandmode && cp sample-config/httpd.conf /etc/apache2/conf.d/nagios.conf
+ADD http://www.nagios-plugins.org/download/nagios-plugins-1.5.tar.gz /tmp/
+RUN cd /tmp && tar -zxvf nagios-plugins-1.5.tar.gz && cd nagios-plugins-1.5 && ./configure --prefix=${NAGIOS_HOME} && make && make install
+
+RUN sed -i.bak 's/.*\=www\-data//g' /etc/apache2/envvars
+RUN export DOC_ROOT="DocumentRoot $(echo $NAGIOS_HOME/share)"; sed -i "s,DocumentRoot.*,$DOC_ROOT," /etc/apache2/sites-available/default
+
+RUN ln -s ${NAGIOS_HOME}/bin/nagios /usr/local/bin/nagios && mkdir -p /usr/share/snmp/mibs && chmod 0755 /usr/share/snmp/mibs && touch /usr/share/snmp/mibs/.foo
+
+RUN echo "use_timezone=$NAGIOS_TIMEZONE" >> ${NAGIOS_HOME}/etc/nagios.cfg && echo "SetEnv TZ \"${NAGIOS_TIMEZONE}\"" >> /etc/apache2/conf.d/nagios.conf
+
+RUN mkdir -p ${NAGIOS_HOME}/etc/conf.d && mkdir -p ${NAGIOS_HOME}/etc/monitor && ln -s /usr/share/snmp/mibs ${NAGIOS_HOME}/libexec/mibs
+RUN echo "cfg_dir=${NAGIOS_HOME}/etc/conf.d" >> ${NAGIOS_HOME}/etc/nagios.cfg
+RUN echo "cfg_dir=${NAGIOS_HOME}/etc/monitor" >> ${NAGIOS_HOME}/etc/nagios.cfg
+RUN download-mibs && echo "mibs +ALL" > /etc/snmp/snmp.conf
+
+RUN sed -i 's,/bin/mail,/usr/bin/mail,' /opt/nagios/etc/objects/commands.cfg && \
+  sed -i 's,/usr/usr,/usr,' /opt/nagios/etc/objects/commands.cfg
+RUN cp /etc/services /var/spool/postfix/etc/
+
+RUN mkdir -p /etc/sv/nagios && mkdir -p /etc/sv/apache && rm -rf /etc/sv/getty-5 && mkdir -p /etc/sv/postfix
+ADD nagios.init /etc/sv/nagios/run
+ADD apache.init /etc/sv/apache/run
+ADD postfix.init /etc/sv/postfix/run
+ADD postfix.stop /etc/sv/postfix/finish
+
+ADD start.sh /usr/local/bin/start_nagios
+
+# install slack alert notification plugin
+ADD slack_nagios.cfg ${NAGIOS_HOME}/etc/conf.d/slack_nagios.cfg
+ADD slack_nagios.sh  /usr/local/bin/slack_nagios.sh
+RUN chmod +x /usr/local/bin/slack_nagios.sh
+
+ENV APACHE_LOCK_DIR /var/run
+ENV APACHE_LOG_DIR /var/log/apache2
+
+EXPOSE 80
+
+VOLUME /opt/nagios/var
+VOLUME /opt/nagios/etc
+VOLUME /opt/nagios/libexec
+VOLUME /var/log/apache2
+VOLUME /usr/share/snmp/mibs
+
+CMD ["/usr/local/bin/start_nagios"]
diff --git a/containers/nagios/Makefile b/containers/nagios/Makefile
new file mode 100644
index 0000000..0c6cb32
--- /dev/null
+++ b/containers/nagios/Makefile
@@ -0,0 +1,12 @@
+.PHONY: build
+	build: ; docker build --rm -t xosproject/nagios .
+
+.PHONY: run
+	run: ; docker run -d --name xosproject_nagios -p 8001:80 -t xosproject/nagios
+
+.PHONY: stop
+	stop: ; docker stop xosproject_nagios
+
+.PHONY: rm
+	rm: ; docker rm xosproject_nagios
+
diff --git a/containers/nagios/README.md b/containers/nagios/README.md
new file mode 100644
index 0000000..e6c2c0e
--- /dev/null
+++ b/containers/nagios/README.md
@@ -0,0 +1,14 @@
+## Docker-Nagios  [![Docker Build Status](http://72.14.176.28/cpuguy83/nagios)](https://registry.hub.docker.com/u/cpuguy83/nagios)
+
+Basic Docker image for running Nagios.<br />
+This is running Nagios 3.5.1
+
+You should either link a mail container in as "mail" or set MAIL_SERVER, otherwise
+mail will not work.
+
+### Knobs ###
+- NAGIOSADMIN_USER=nagiosadmin
+- NAGIOSAMDIN_PASS=nagios
+
+### Web UI ###
+The Nagios Web UI is available on port 80 of the container<br />
diff --git a/containers/nagios/apache.init b/containers/nagios/apache.init
new file mode 100755
index 0000000..9cb9a38
--- /dev/null
+++ b/containers/nagios/apache.init
@@ -0,0 +1,4 @@
+#!/bin/bash
+. /etc/default/apache2
+
+exec /usr/sbin/apache2 -D FOREGROUND
diff --git a/containers/nagios/nagios.init b/containers/nagios/nagios.init
new file mode 100755
index 0000000..30448f9
--- /dev/null
+++ b/containers/nagios/nagios.init
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+exec ${NAGIOS_HOME}/bin/nagios ${NAGIOS_HOME}/etc/nagios.cfg
diff --git a/containers/nagios/postfix.init b/containers/nagios/postfix.init
new file mode 100755
index 0000000..29bf50b
--- /dev/null
+++ b/containers/nagios/postfix.init
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+: ${MAIL_SERVER=$MAIL_PORT_25_TCP_ADDR}
+
+
+sed -i "s/relayhost =.*/relayhost = ${MAIL_SERVER}/" /etc/postfix/main.cf
+sed -i "s/myhostname =.*/myhostname = `hostname`/" /etc/postfix/main.cf
+
+exec /usr/lib/postfix/master -d -c /etc/postfix
diff --git a/containers/nagios/postfix.stop b/containers/nagios/postfix.stop
new file mode 100755
index 0000000..50646e8
--- /dev/null
+++ b/containers/nagios/postfix.stop
@@ -0,0 +1 @@
+postfix stop
diff --git a/containers/nagios/slack_nagios.cfg b/containers/nagios/slack_nagios.cfg
new file mode 100644
index 0000000..8840c87
--- /dev/null
+++ b/containers/nagios/slack_nagios.cfg
@@ -0,0 +1,21 @@
+define contact {
+      contact_name                             slack
+      alias                                    Slack
+      service_notification_period              24x7
+      host_notification_period                 24x7
+      service_notification_options             w,u,c,r
+      host_notification_options                d,r
+      service_notification_commands            notify-service-by-slack
+      host_notification_commands               notify-host-by-slack
+}
+
+define command {
+      command_name     notify-service-by-slack
+      command_line     /usr/local/bin/slack_nagios.sh > /tmp/slack.log 2>&1
+}
+
+define command {
+      command_name     notify-host-by-slack
+      command_line     /usr/local/bin/slack_nagios.sh > /tmp/slack.log 2>&1
+}
+
diff --git a/containers/nagios/slack_nagios.sh b/containers/nagios/slack_nagios.sh
new file mode 100755
index 0000000..7c5e205
--- /dev/null
+++ b/containers/nagios/slack_nagios.sh
@@ -0,0 +1,46 @@
+#!/bin/bash
+
+# This script is used by Nagios to post alerts into a Slack channel
+# using the Incoming WebHooks integration. Create the channel, botname
+# and integration first and then add this notification script in your
+# Nagios configuration.
+#
+# All variables that start with NAGIOS_ are provided by Nagios as
+# environment variables when an notification is generated.
+# A list of the env variables is available here:
+#   http://nagios.sourceforge.net/docs/3_0/macrolist.html
+#
+# More info on Slack
+# Website: https://slack.com/
+# Twitter: @slackhq, @slackapi
+#
+# My info
+# Website: http://matthewcmcmillan.blogspot.com/
+# Twitter: @matthewmcmillan
+
+#Modify these variables for your environment
+MY_NAGIOS_HOSTNAME=""        # This server's hostname
+SLACK_HOSTNAME=""               
+SLACK_CHANNEL="#alerts"      
+SLACK_BOTNAME="nagios"
+WEBHOOK_URL=""               # Incomming webhook url for the slack account 
+
+#Set the message icon based on Nagios service state
+if [ "$NAGIOS_SERVICESTATE" = "CRITICAL" ]
+then
+    ICON=":exclamation:"
+elif [ "$NAGIOS_SERVICESTATE" = "WARNING" ]
+then
+    ICON=":warning:"
+elif [ "$NAGIOS_SERVICESTATE" = "OK" ]
+then
+    ICON=":white_check_mark:"
+elif [ "$NAGIOS_SERVICESTATE" = "UNKNOWN" ]
+then
+    ICON=":question:"
+else
+    ICON=":white_medium_square:"
+fi
+
+#Send message to Slack
+curl -X POST --data-urlencode "payload={\"channel\": \"${SLACK_CHANNEL}\", \"username\": \"${SLACK_USERNAME}\", \"text\": \"${ICON} HOST: ${MY_NAGIOS_HOSTNAME}   SERVICE: ${NAGIOS_SERVICEDISPLAYNAME}     MESSAGE: ${NAGIOS_SERVICEOUTPUT} <https://${MY_NAGIOS_HOSTNAME}/cgi-bin/nagios3/extinfo.cgi?type=1&host=${NAGIOS_HOSTNAME}|See Nagios>\"}" $WEBHOOK_URL
diff --git a/containers/nagios/start.sh b/containers/nagios/start.sh
new file mode 100755
index 0000000..f295e5b
--- /dev/null
+++ b/containers/nagios/start.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+if [ ! -f ${NAGIOS_HOME}/etc/htpasswd.users ] ; then
+  htpasswd -c -b -s ${NAGIOS_HOME}/etc/htpasswd.users ${NAGIOSADMIN_USER} ${NAGIOSADMIN_PASS}
+  chown -R nagios.nagios ${NAGIOS_HOME}/etc/htpasswd.users
+fi
+
+exec runsvdir /etc/sv
+
+/etc/init.d/apache2 start
diff --git a/xos/configurations/cord-pod/README-Tutorial.md b/xos/configurations/cord-pod/README-Tutorial.md
index 805812f..4bd68c5 100644
--- a/xos/configurations/cord-pod/README-Tutorial.md
+++ b/xos/configurations/cord-pod/README-Tutorial.md
@@ -5,29 +5,27 @@
 
 ## Prepare the development POD
 
-Follow steps 1-3 under the **How to Bring up CORD** heading in the
-[README.md](./README.md) file.  For best results, use on a clean Ubuntu 14.04
+This tutorial runs on a single-node CORD POD development environment.
+For best results, prepare a clean Ubuntu 14.04
 LTS installation on a server with at least 48GB RAM and 12 CPU cores.
+Update the packages to the latest versions.
 
-For step 1, use the single-node POD setup described at
-https://github.com/open-cloud/openstack-cluster-setup.  If you like, you can run
-[this script](https://github.com/open-cloud/openstack-cluster-setup/blob/master/scripts/single-node-pod.sh) to perform steps 1 and 2:
+To set up the POD, run
+[this script](https://github.com/open-cloud/openstack-cluster-setup/blob/master/scripts/single-node-pod.sh)
+with the `-e` option:
 
 ```
 ubuntu@pod:~$ wget https://raw.githubusercontent.com/open-cloud/openstack-cluster-setup/master/scripts/single-node-pod.sh
-ubuntu@pod:~$ bash single-node-pod.sh
+ubuntu@pod:~$ bash single-node-pod.sh -e
 ```
 
-For step 3, in place of the `compute-ext-net.sh` script, run
-[this script](https://github.com/open-cloud/openstack-cluster-setup/blob/master/scripts/compute-ext-net-tutorial.sh)
-inside the nova-compute VM.  It enables routing packets between the ExampleService and vSG subnets on a
-single-node POD.
+> NOTE: The above script can also automatically perform (nearly) all the steps of this
+> tutorial if run as `bash single-node-pod -e -t`.  However, you will still need 
+> to manually log into XOS and create an ExampleTenant, as described under 
+> [Configure ExampleService in XOS](#configure-exampleservice-in-xos)
+> below.  The script will tell you when it's time to do this.
 
-```
-ubuntu@pod:~$ ssh ubuntu@nova-compute
-ubuntu@nova-compute:~$ wget https://raw.githubusercontent.com/open-cloud/openstack-cluster-setup/master/scripts/compute-ext-net-tutorial.sh
-ubuntu@nova-compute:~$ sudo bash compute-ext-net-tutorial.sh
-```
+Be patient... it will take at least one hour to fully set up the single-node POD.
 
 ## Include ExampleService in XOS
 
@@ -37,15 +35,14 @@
 Change the XOS code as described in the
 [ExampleService Tutorial](http://guide.xosproject.org/devguide/exampleservice/)
 under the **Install the Service in Django** heading, and rebuild the XOS containers as
-described in that Tutorial:
+follows:
 
 ```
-ubuntu@xos:~$ cd xos/xos/configurations/devel
-ubuntu@xos:~/xos/xos/configurations/devel$ make containers
+ubuntu@xos:~$ cd xos/xos/configurations/cord-pod
+ubuntu@xos:~/xos/xos/configurations/cord-pod$ make local_containers
 ```
 
-Change directories to `../cord-pod`.  
-Modify the `docker-compose.yml` file in this directory to include the synchronizer
+Modify the `docker-compose.yml` file in the `cord-pod` directory to include the synchronizer
 for ExampleService:
 
 ```yaml
@@ -65,7 +62,7 @@
 
 Also, add ExampleService's public key to the `volumes` section of the `xos` docker container:
 
-```
+```yaml
 xos:
     ...
     volumes:
@@ -75,21 +72,8 @@
 
 ## Bring up XOS
 
-Run the `make` commands described in the [README.md](./README.md) file:
-
-```
-ubuntu@xos:~/xos/xos/configurations/cord-pod$ make
-ubuntu@xos:~/xos/xos/configurations/cord-pod$ make vtn
-ubuntu@xos:~/xos/xos/configurations/cord-pod$ make cord
-```
-
-The first `make` command initializes XOS and configures it to talk to OpenStack.
-After running it you should be able to login to the XOS UI at http://xos
-using credentials padmin@vicci.org/letmein.
-
-The `make vtn` tells XOS to start and configure the ONOS VTN app.  The `make cord`
-installs the CORD services in XOS and configures a sample subscriber; the end
-result is that XOS will spin up the subscriber's vSG.
+Run the `make` commands described in the [Bringing up XOS](https://github.com/open-cloud/xos/blob/master/xos/configurations/cord-pod/README.md#bringing-up-xos)
+section of the README.md file.
 
 ## Configure ExampleService in XOS
 
@@ -100,9 +84,10 @@
 ubuntu@xos:~/xos/xos/configurations/cord-pod$ make exampleservice
 ```
 
-In the XOS UI, create an ExampleTenant. Go to *http://xos/admin/exampleservice*
-and add / save an Example Tenant (when creating the tenant, fill in a message that
-this tenant should display).  This will cause an Instance to be created
+Next, in the XOS UI, create an ExampleTenant. Go to *http://xos/admin/exampleservice*
+([caveat](https://github.com/open-cloud/xos/blob/master/xos/configurations/cord-pod/README.md#logging-into-xos-on-cloudlab-or-any-remote-host))
+and add / save an Example Tenant.  When creating the tenant, fill in a message that
+this tenant should display.  This will cause an Instance to be created
 in the the *mysite_exampleservice* slice.
 
 ## Set up a Subscriber Device
diff --git a/xos/configurations/cord-pod/README.md b/xos/configurations/cord-pod/README.md
index d5051c9..8813d3e 100644
--- a/xos/configurations/cord-pod/README.md
+++ b/xos/configurations/cord-pod/README.md
@@ -50,7 +50,7 @@
 The CORD fabric is responsible for providing external (Internet) connectivity
 for VMs created on CORD.  If you are running on CloudLab (or another development
 environment) and want external connectivity without the fabric, download [this script](https://raw.githubusercontent.com/open-cloud/openstack-cluster-setup/master/scripts/compute-ext-net.sh)
- and run it as root:
+ and run it on the Nova compute node(s) as root:
  ```
  $ sudo compute-ext-net.sh
  ```
@@ -87,11 +87,9 @@
 ubuntu@xos:~/xos/xos/configurations/cord-pod$ make
 ```
 
-After this you will be able to login to the XOS GUI at
-*http://xos/* using username/password `padmin@vicci.org/letmein`.
 Before proceeding, you should verify that objects in XOS are
-being sync'ed with OpenStack.  Log into the GUI and select *Users*
-at left.  Make sure there is a green check next to `padmin@vicci.org`.
+being sync'ed with OpenStack. [Login to the XOS GUI](#logging-into-xos-on-cloudlab-or-any-remote-host) 
+and select *Users* at left.  Make sure there is a green check next to `padmin@vicci.org`.
 
 > If you are **not** building the single-node development POD, the next
 > step is to create and edit the VTN configuration.  Run `make vtn-external.yaml`
@@ -112,7 +110,8 @@
 and pushing it to ONOS.  You are able to see and modify the configuration
 via the GUI as follows:
 
-* To see the generated configuration, go to *http://xos/admin/onos/onosapp/*, select
+* To see the generated configuration, go to *http://xos/admin/onos/onosapp/* 
+([caveat](#logging-into-xos-on-cloudlab-or-any-remote-host)), select
 *VTN_ONOS_app*, then the *Attributes* tab, and look for the
 `rest_onos/v1/network/configuration/` attribute.  
 
@@ -182,3 +181,20 @@
 CONTAINER ID        IMAGE                    COMMAND             CREATED             STATUS              PORTS               NAMES
 2b0bfb3662c7        andybavier/docker-vcpe   "/sbin/my_init"     5 days ago          Up 5 days                               vcpe-222-111
 ```
+
+### Logging into XOS on CloudLab (or any remote host)
+
+The XOS service is accessible on the POD at `http://xos/`, but `xos` maps to a private IP address
+on the management network.  If you install CORD on CloudLab 
+you will not be able to directly access the XOS GUI.
+In order to log into the XOS GUI in the browser on your local machine (desktop or laptop), 
+you can set up an SSH tunnel to your CloudLab node.  Assuming that 
+`<your-cloudlab-node>` is the DNS name of the CloudLab node hosting your experiment,
+run the following on your local machine to create the tunnel:
+
+```
+$ ssh -L 8888:xos:80 <your-cloudlab-node>
+```
+
+Then you should be able to access the XOS GUI by pointing your browser to
+`http://localhost:8888`.  Default username/password is `padmin@vicci.org/letmein`.