Merge "CORD-2929 Helm chart for XOS 'openstack' service"
diff --git a/configs/onos-fabric.yaml b/configs/onos-fabric.yaml
index ccdafce..8115b1d 100644
--- a/configs/onos-fabric.yaml
+++ b/configs/onos-fabric.yaml
@@ -19,7 +19,10 @@
 # helm install -f configs/onos-fabric.yaml onos
 
 services:
-  serviceType: NodePort
+  openflowServiceType: NodePort
+  ovsdbServiceType: NodePort
+  sshServiceType: NodePort
+  uiServiceType: NodePort
   ovsdb:
     nodePort: 31640
   openflow:
diff --git a/configs/onos-voltha.yaml b/configs/onos-voltha.yaml
new file mode 100644
index 0000000..2bce674
--- /dev/null
+++ b/configs/onos-voltha.yaml
@@ -0,0 +1,51 @@
+---
+
+# Copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+# Expose ONOS services using NodePorts, for onos-voltha configuration
+#
+# helm install -f configs/onos-voltha.yaml onos
+nameOverride: "onosv"
+fullnameOverride: "onos-voltha"
+
+namespace: voltha
+serviceAccountName: voltha-serviceaccount
+
+image:
+  repository: voltha/voltha-onos
+  tag: 'latest'
+  pullPolicy: IfNotPresent
+
+services:
+  openflowServiceType: ClusterIP
+  ovsdbServiceType: ClusterIP
+  sshServiceType: NodePort
+  uiServiceType: NodePort
+  ssh:
+    nodePort: 30115
+  ui:
+    nodePort: 30120
+
+onos_env:
+- name: POD_IP
+  valueFrom:
+  fieldRef:
+    fieldPath: status.podIP
+- name: NAMESPACE
+  valueFrom:
+  fieldRef:
+    fieldPath: metadata.namespace
+- name: ONOS_APPS
+  value: "drivers,openflow-base"
diff --git a/onos/templates/deployment.yaml b/onos/templates/deployment.yaml
index 840dc0a..5d9e343 100644
--- a/onos/templates/deployment.yaml
+++ b/onos/templates/deployment.yaml
@@ -18,6 +18,7 @@
 kind: Deployment
 metadata:
   name: {{ template "onos.fullname" . }}
+  namespace: {{ .Values.namespace }}
   labels:
     app: {{ template "onos.name" . }}
     chart: {{ template "onos.chart" . }}
@@ -35,10 +36,14 @@
         app: {{ template "onos.name" . }}
         release: {{ .Release.Name }}
     spec:
+      serviceAccount: {{ .Values.serviceAccountName }}
+      serviceAccountName: {{ .Values.serviceAccountName }}
       containers:
         - name: {{ .Chart.Name }}
           image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
           imagePullPolicy: {{ .Values.image.pullPolicy }}
+          env:
+{{ toYaml .Values.onos_env | indent 12 }}
           ports:
             - name: ovsdb
               containerPort: {{ .Values.services.ovsdb.port }}
diff --git a/onos/templates/openflow-service.yaml b/onos/templates/openflow-service.yaml
index c61f611..05fadeb 100644
--- a/onos/templates/openflow-service.yaml
+++ b/onos/templates/openflow-service.yaml
@@ -16,13 +16,14 @@
 kind: Service
 metadata:
   name: {{ template "onos.fullname" . }}-openflow
+  namespace: {{ .Values.namespace }}
   labels:
     app: {{ template "onos.name" . }}
     chart: {{ template "onos.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 spec:
-  type: {{ .Values.services.serviceType }}
+  type: {{ .Values.services.openflowServiceType }}
   ports:
   - name: openflow
 {{ toYaml .Values.services.openflow | indent 4 }}
diff --git a/onos/templates/ovsdb-service.yaml b/onos/templates/ovsdb-service.yaml
index cfda477..f0760fe 100644
--- a/onos/templates/ovsdb-service.yaml
+++ b/onos/templates/ovsdb-service.yaml
@@ -16,13 +16,14 @@
 kind: Service
 metadata:
   name: {{ template "onos.fullname" . }}-ovsdb
+  namespace: {{ .Values.namespace }}
   labels:
     app: {{ template "onos.name" . }}
     chart: {{ template "onos.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 spec:
-  type: {{ .Values.services.serviceType }}
+  type: {{ .Values.services.ovsdbServiceType }}
   ports:
   - name: ovsdb
 {{ toYaml .Values.services.ovsdb | indent 4 }}
diff --git a/onos/templates/ssh-service.yaml b/onos/templates/ssh-service.yaml
index fdcbb66..bf0b8a0 100644
--- a/onos/templates/ssh-service.yaml
+++ b/onos/templates/ssh-service.yaml
@@ -16,13 +16,14 @@
 kind: Service
 metadata:
   name: {{ template "onos.fullname" . }}-ssh
+  namespace: {{ .Values.namespace }}
   labels:
     app: {{ template "onos.name" . }}
     chart: {{ template "onos.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 spec:
-  type: {{ .Values.services.serviceType }}
+  type: {{ .Values.services.sshServiceType }}
   ports:
   - name: ssh
 {{ toYaml .Values.services.ssh | indent 4 }}
diff --git a/onos/templates/ui-service.yaml b/onos/templates/ui-service.yaml
index 40cbd68..4c05f4d 100644
--- a/onos/templates/ui-service.yaml
+++ b/onos/templates/ui-service.yaml
@@ -16,13 +16,14 @@
 kind: Service
 metadata:
   name: {{ template "onos.fullname" . }}-ui
+  namespace: {{ .Values.namespace }}
   labels:
     app: {{ template "onos.name" . }}
     chart: {{ template "onos.chart" . }}
     release: {{ .Release.Name }}
     heritage: {{ .Release.Service }}
 spec:
-  type: {{ .Values.services.serviceType }}
+  type: {{ .Values.services.uiServiceType }}
   ports:
   - name: ui
 {{ toYaml .Values.services.ui | indent 4 }}
diff --git a/onos/values.yaml b/onos/values.yaml
index 688fff6..c46008f 100644
--- a/onos/values.yaml
+++ b/onos/values.yaml
@@ -28,8 +28,14 @@
 nameOverride: ""
 fullnameOverride: ""
 
+namespace: default
+serviceAccountName: default
+
 services:
-  serviceType: ClusterIP
+  openflowServiceType: ClusterIP
+  ovsdbServiceType: ClusterIP
+  sshServiceType: ClusterIP
+  uiServiceType: ClusterIP
   ovsdb:
     port: 6640
   openflow:
@@ -41,6 +47,8 @@
   cluster:
     port: 9876
 
+onos_env: []
+
 resources: {}
 
 nodeSelector: {}
diff --git a/voltha/templates/envoy_for_etcd.yaml b/voltha/templates/envoy_for_etcd.yaml
index 7903605..38e9585 100644
--- a/voltha/templates/envoy_for_etcd.yaml
+++ b/voltha/templates/envoy_for_etcd.yaml
@@ -44,7 +44,7 @@
   name: voltha
   namespace: {{ .Values.global.namespace }}
 spec:
-  replicas: 1
+  replicas: {{ .Values.replicas.envoy_for_etcd }}
   template:
     metadata:
       labels:
diff --git a/voltha/templates/fluentd-config.yaml b/voltha/templates/fluentd-config.yaml
deleted file mode 100644
index 2329a6f..0000000
--- a/voltha/templates/fluentd-config.yaml
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright 2017-present Open Networking Foundation
-#
-# 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.
-
-apiVersion: v1
-data:
-  fluentd.conf: |
-
-    #   Uncomment this source in environments where voltha services are forwarding logs to the fluentd port directly.
-    #    <source>
-    #      @type forward
-    #      port 24224
-    #    </source>
-
-    <source>
-      @id fluentd-containers.log
-      @type tail
-      path /var/log/containers/*.log
-      exclude_path ["/var/log/containers/*kube-system*.log"]
-      pos_file /var/log/containers/ag-containers.log.pos
-      time_format %Y-%m-%dT%H:%M:%S.%NZ
-      tag voltha.*
-      log_level debug
-      format json
-      read_from_head true
-    </source>
-    <match **>
-      @type forward
-      heartbeat_type tcp
-
-      # primary host
-      <server>
-        host fluentdactv
-        port 24224
-      </server>
-      # use secondary host
-      <server>
-        host fluentdstby
-        port 24224
-        standby
-      </server>
-      # use longer flush_interval to reduce CPU usage.
-      # note that this is a trade-off against latency.
-      flush_interval 60s
-    </match>
-
-  fluentd-agg.conf: |
-    <source>
-      @type forward
-      port 24224
-    </source>
-    <match **>
-      @type file
-
-      path /fluentd/log/voltha
-      buffer_path /fluentd/log/*.log
-      append true
-      time_slice_wait 10m
-      time_format %Y%m%dT%H%M%S%z
-      time_slice_format %Y%m%d%H
-    </match>
-kind: ConfigMap
-metadata:
-  name: fluentd-config
-  namespace: {{ .Values.global.namespace }}
diff --git a/voltha/templates/fluentd.yaml b/voltha/templates/fluentd.yaml
deleted file mode 100644
index 1e5b886..0000000
--- a/voltha/templates/fluentd.yaml
+++ /dev/null
@@ -1,219 +0,0 @@
-# Copyright 2017-present Open Networking Foundation
-#
-# 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.
-
-#
-# This file describes a cluster of 3 fluentd forwarders that
-# send logs to a cluster of 2 fluentd aggregators: one active
-# and one standby.
-#
-# The active fluentd aggregator
-#
-apiVersion: v1
-kind: Service
-metadata:
-  name: fluentdactv
-  namespace: {{ .Values.global.namespace }}
-  serviceAccountName: {{ .Values.global.namespace }}-serviceaccount
-spec:
-  clusterIP: None
-  selector:
-    app: fluentdactv
-  ports:
-  - protocol: TCP
-    port: 24224
-    targetPort: 24224
----
-#
-# Ensure that the active aggregator is not deployed to the
-# same node as the standby
-#
-apiVersion: apps/v1beta1
-kind: Deployment
-metadata:
-  name: fluentdactv
-  namespace: {{ .Values.global.namespace }}
-  serviceAccountName: {{ .Values.global.namespace }}-serviceaccount
-spec:
-  replicas: 1
-  template:
-    metadata:
-      labels:
-        app: fluentdactv
-      annotations:
-        cni: "weave"
-    spec:
-      serviceAccountName: {{ .Values.global.namespace }}-serviceaccount
-      terminationGracePeriodSeconds: 10
-      affinity:
-        podAntiAffinity:
-          requiredDuringSchedulingIgnoredDuringExecution:
-          - labelSelector:
-              matchExpressions:
-              - key: app
-                operator: In
-                values:
-                - fluentdstby
-            topologyKey: kubernetes.io/hostname
-      containers:
-      - name: fluentdactv
-        image: {{ .Values.k8s_docker_registry }}{{ .Values.images.fluentd.repository }}:{{ .Values.images.fluentd.tag }}
-        imagePullPolicy: {{ .Values.image_pull_policy }}
-        volumeMounts:
-        - name: fluentd-log
-          mountPath: /fluentd/log
-        - name: config-volume
-          mountPath: /etc/fluentd-config
-        ports:
-        - containerPort: 24224
-        env:
-        - name: FLUENTD_ARGS
-          value: -c /etc/fluentd-config/fluentd-agg.conf
-      volumes:
-      - name: config-volume
-        configMap:
-          name: fluentd-config
-      - name: fluentd-log
-        hostPath:
-          path: /var/log/voltha/logging_volume
-          type: Directory
----
-#
-# The standby fluentd aggregator
-#
-apiVersion: v1
-kind: Service
-metadata:
-  name: fluentdstby
-  namespace: {{ .Values.global.namespace }}
-spec:
-  clusterIP: None
-  selector:
-    app: fluentdstby
-  ports:
-  - protocol: TCP
-    port: 24224
-    targetPort: 24224
----
-#
-# Ensure thet the standby aggregator is not deployed to the
-# same node as the active
-#
-apiVersion: apps/v1beta1
-kind: Deployment
-metadata:
-  name: fluentdstby
-  namespace: {{ .Values.global.namespace }}
-spec:
-  replicas: 1
-  template:
-    metadata:
-      labels:
-        app: fluentdstby
-      annotations:
-        cni: "weave"
-    spec:
-      serviceAccountName: {{ .Values.global.namespace }}-serviceaccount
-      terminationGracePeriodSeconds: 10
-      affinity:
-        podAntiAffinity:
-          requiredDuringSchedulingIgnoredDuringExecution:
-          - labelSelector:
-              matchExpressions:
-              - key: app
-                operator: In
-                values:
-                - fluentdactv
-            topologyKey: kubernetes.io/hostname
-      containers:
-      - name: fluentdstby
-        image: k8s.gcr.io/fluentd-gcp:1.30 
-        imagePullPolicy: Never
-        volumeMounts:
-        - name: fluentd-log
-          mountPath: /fluentd/log
-        - name: config-volume
-          mountPath: /etc/fluentd-config
-        ports:
-        - containerPort: 24224
-        env:
-        - name: FLUENTD_ARGS
-          value: -c /etc/fluentd-config/fluentd-agg.conf
-      volumes:
-      - name: config-volume
-        configMap:
-          name: fluentd-config
-      - name: fluentd-log
-        hostPath:
-          path: /var/log/voltha/logging_volume
-          type: Directory
----
-#
-# The cluster of fluentd forwarders.  The service itself will be removed once all fluentd forwarding logic are removed
-# from the specific voltha services.   Fluentd is defined as a DaemonSet which implies that only 1 instance will
-# run on each node.   Each instance will also gets its configuration data from a config map (fluentd-config.yml).
-#
-apiVersion: v1
-kind: Service
-metadata:
-  name: fluentd
-  namespace: {{ .Values.global.namespace }}
-spec:
-  clusterIP: None
-  selector:
-    app: fluentd
-  ports:
-  - protocol: TCP
-    port: 24224
-    targetPort: 24224
----
-apiVersion: extensions/v1beta1
-kind: DaemonSet
-metadata:
-  name: fluentd
-  namespace: {{ .Values.global.namespace }}
-spec:
-   template:
-    metadata:
-      labels:
-        app: fluentd
-      annotations:
-        cni: "weave"
-    spec:
-      serviceAccountName: {{ .Values.global.namespace }}-serviceaccount
-      tolerations:
-        - key: node-role.kubernetes.io/master
-          effect: NoSchedule
-      containers:
-      - name: fluentd
-        image: k8s.gcr.io/fluentd-gcp:1.30
-        env:
-        - name: FLUENTD_ARGS
-          value: -c /etc/fluentd-config/fluentd.conf
-        volumeMounts:
-        - name: varlog
-          mountPath: /var/log/
-        - name: varlogcontainers
-          mountPath: /var/lib/docker/containers/
-        - name: config-volume
-          mountPath: /etc/fluentd-config
-      volumes:
-      - name: varlog
-        hostPath:
-          path: /var/log/
-      - name: varlogcontainers
-        hostPath:
-          path: /var/lib/docker/containers/
-      - name: config-volume
-        configMap:
-          name: fluentd-config
diff --git a/voltha/templates/netconf.yaml b/voltha/templates/netconf.yaml
index d05afa8..cacbf2e 100644
--- a/voltha/templates/netconf.yaml
+++ b/voltha/templates/netconf.yaml
@@ -33,7 +33,7 @@
   namespace: {{ .Values.global.namespace }}
   serviceAccountName: {{ .Values.global.namespace }}-serviceaccount
 spec:
-  replicas: 3
+  replicas: {{ .Values.replicas.netconf }}
   template:
     metadata:
       labels:
diff --git a/voltha/templates/ofagent.yaml b/voltha/templates/ofagent.yaml
index 5f6d81e..124f0b4 100644
--- a/voltha/templates/ofagent.yaml
+++ b/voltha/templates/ofagent.yaml
@@ -19,7 +19,7 @@
   namespace: {{ .Values.global.namespace }}
   serviceAccountName: {{ .Values.global.namespace }}-serviceaccount
 spec:
-  replicas: 3
+  replicas: {{ .Values.replicas.ofagent }}
   template:
     metadata:
       labels:
diff --git a/voltha/templates/onos.yaml b/voltha/templates/onos.yaml
deleted file mode 100644
index 1549551..0000000
--- a/voltha/templates/onos.yaml
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright 2017-present Open Networking Foundation
-#
-# 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.
-
-apiVersion: v1
-kind: Service
-metadata:
-   name: onos
-   namespace: {{ .Values.global.namespace }}
-   serviceAccountName: {{ .Values.global.namespace }}-serviceaccount
-   labels:
-     name: onos
-spec:
-  ports:
-    - name: ssh
-      port: 8101
-      targetPort: 8101
-    - name: of
-      port: 6653
-      targetPort: 6653
-    - name: ui
-      port: 8181
-      targetPort: 8181
-  selector:
-    app: onos
----
-apiVersion: apps/v1beta1
-kind: Deployment
-metadata:
-  name: onos
-  namespace: {{ .Values.global.namespace }}
-  serviceAccountName: {{ .Values.global.namespace }}-serviceaccount
-spec:
-  replicas: 1
-  template:
-    metadata:
-      labels:
-        app: onos
-      annotations:
-        cni: "calico"
-    spec:
-      serviceAccountName: {{ .Values.global.namespace }}-serviceaccount
-      containers:
-        - name: onos
-          image: {{ .Values.pull_docker_registry }}{{ .Values.images.onos.repository }}:{{ .Values.images.onos.tag }}
-          env:
-            - name: POD_IP
-              valueFrom:
-                fieldRef:
-                  fieldPath: status.podIP
-            - name: NAMESPACE
-              valueFrom:
-                fieldRef:
-                  fieldPath: metadata.namespace
-            - name: ONOS_APPS
-              value: "drivers,openflow-base"
-          ports:
-            - containerPort: 8101
-              name: ssh-port
-            - containerPort: 6653
-              name: of-port
-            - containerPort: 8181
-              name: ui-port
-          imagePullPolicy: {{ .Values.image_pull_policy }}
diff --git a/voltha/templates/vcli.yaml b/voltha/templates/vcli.yaml
index 76c8681..5b8fbdb 100644
--- a/voltha/templates/vcli.yaml
+++ b/voltha/templates/vcli.yaml
@@ -37,7 +37,7 @@
   namespace: {{ .Values.global.namespace }}
   serviceAccountName: {{ .Values.global.namespace }}-serviceaccount
 spec:
-  replicas: 2
+  replicas: {{ .Values.replicas.vcli }}
   template:
     metadata:
       labels:
diff --git a/voltha/templates/vcore_for_etcd.yaml b/voltha/templates/vcore_for_etcd.yaml
index 8ceb6f3..b9051ee 100644
--- a/voltha/templates/vcore_for_etcd.yaml
+++ b/voltha/templates/vcore_for_etcd.yaml
@@ -42,7 +42,7 @@
   namespace: {{ .Values.global.namespace }}
   serviceAccountName: {{ .Values.global.namespace }}-serviceaccount
 spec:
-  replicas: 3
+  replicas: {{ .Values.replicas.vcore }}
   template:
     metadata:
       labels:
diff --git a/voltha/values.yaml b/voltha/values.yaml
index 0f0ef27..13b23c5 100644
--- a/voltha/values.yaml
+++ b/voltha/values.yaml
@@ -17,6 +17,13 @@
 
 image_pull_policy: IfNotPresent
 
+replicas:
+  vcore: 1
+  vcli: 1
+  ofagent: 1
+  netconf: 1
+  envoy_for_etcd: 1
+
 
 node_ports:
   vcli_port: 30110
@@ -120,7 +127,7 @@
 - "/ofagent/ofagent/main.py"
 - "-v"
 - "--consul=consul.$(NAMESPACE).svc.cluster.local:8500"
-- "--controller=onos:6653"
+- "--controller=onos-voltha-openflow:6653"
 - "--grpc-endpoint=vcore.$(NAMESPACE).svc.cluster.local:50556"
 - "--enable-tls"
 - "--key-file=/ofagent/pki/voltha.key"
diff --git a/xos-profiles/rcord-lite/requirements.yaml b/xos-profiles/rcord-lite/requirements.yaml
index 31551dc..6219740 100644
--- a/xos-profiles/rcord-lite/requirements.yaml
+++ b/xos-profiles/rcord-lite/requirements.yaml
@@ -27,3 +27,6 @@
 - name: vsg-hw
   version: 0.1.0
   repository: file://../../xos-services/vsg-hw
+- name: vrouter
+  version: 0.1.0
+  repository: file://../../xos-services/vrouter
diff --git a/xos-profiles/rcord-lite/values.yaml b/xos-profiles/rcord-lite/values.yaml
index 49084b6..cf65680 100644
--- a/xos-profiles/rcord-lite/values.yaml
+++ b/xos-profiles/rcord-lite/values.yaml
@@ -240,6 +240,7 @@
       - custom_types/serviceinstancelink.yaml
       - custom_types/slice.yaml
       - custom_types/voltservice.yaml
+      - custom_types/vrouterservice.yaml
       - custom_types/vsghwservice.yaml
     topology_template:
       node_templates:
@@ -272,6 +273,15 @@
           type: tosca.nodes.VSGHWService
           properties:
             name: vsg-hw
+        service#vrouter:
+          type: tosca.nodes.VRouterService
+          properties:
+            name: vrouter
+            kind: rcord
+            rest_hostname: onos-fabric-ui
+            rest_port: 8181
+            rest_user: karaf
+            rest_pass: karaf
         volt_vsg-hw:
           type: tosca.nodes.ServiceDependency
           properties:
@@ -294,6 +304,17 @@
             - provider_service:
                 node: service#ONOS_Fabric
                 relationship: tosca.relationships.BelongsToOne
+        vsg-hw_vrouter:
+          type: tosca.nodes.ServiceDependency
+          properties:
+            connect_method: None
+          requirements:
+            - subscriber_service:
+                node: service#vsg-hw
+                relationship: tosca.relationships.BelongsToOne
+            - provider_service:
+                node: service#vrouter
+                relationship: tosca.relationships.BelongsToOne
 
   serviceGraphConstraints:
     tosca_definitions_version: tosca_simple_yaml_1_0
@@ -305,4 +326,4 @@
         constraints:
           type: tosca.nodes.ServiceGraphConstraint
           properties:
-            constraints: '[[null, "rcord"], [null, "volt"], ["ONOS_Fabric", "vsg-hw"]]'
+            constraints: '[[null, "rcord"], [null, "volt"], ["ONOS_Fabric", "vsg-hw"], [null, "vrouter"]]'
diff --git a/xos-services/volt/values.yaml b/xos-services/volt/values.yaml
index aa537a3..a25cc99 100644
--- a/xos-services/volt/values.yaml
+++ b/xos-services/volt/values.yaml
@@ -53,7 +53,7 @@
   model_policies_dir: "/opt/xos/synchronizers/volt/model_policies"
   models_dir: "/opt/xos/synchronizers/volt/models"
   steps_dir: "/opt/xos/synchronizers/volt/steps"
-  # pull_steps_dir: "/opt/xos/synchronizers/volt/pull_steps"
+  pull_steps_dir: "/opt/xos/synchronizers/volt/pull_steps"
   logging:
     version: 1
     handlers:
diff --git a/xos-services/vrouter/.helmignore b/xos-services/vrouter/.helmignore
new file mode 100644
index 0000000..f0c1319
--- /dev/null
+++ b/xos-services/vrouter/.helmignore
@@ -0,0 +1,21 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
diff --git a/xos-services/vrouter/Chart.yaml b/xos-services/vrouter/Chart.yaml
new file mode 100644
index 0000000..29f15d0
--- /dev/null
+++ b/xos-services/vrouter/Chart.yaml
@@ -0,0 +1,21 @@
+---
+
+# Copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+apiVersion: v1
+appVersion: "1.0"
+description: A Helm chart for XOS's "vRouter" service
+name: vrouter
+version: 0.1.0
diff --git a/xos-services/vrouter/templates/_helpers.tpl b/xos-services/vrouter/templates/_helpers.tpl
new file mode 100644
index 0000000..03d5458
--- /dev/null
+++ b/xos-services/vrouter/templates/_helpers.tpl
@@ -0,0 +1,47 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Copyright 2018-present Open Networking Foundation
+
+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.
+*/}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "vrouter.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "vrouter.fullname" -}}
+{{- if .Values.fullnameOverride -}}
+{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- $name := default .Chart.Name .Values.nameOverride -}}
+{{- if contains $name .Release.Name -}}
+{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
+{{- else -}}
+{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
+
+{{/*
+Create chart name and version as used by the chart label.
+*/}}
+{{- define "vrouter.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/xos-services/vrouter/templates/configmap.yaml b/xos-services/vrouter/templates/configmap.yaml
new file mode 100644
index 0000000..dd8e766
--- /dev/null
+++ b/xos-services/vrouter/templates/configmap.yaml
@@ -0,0 +1,23 @@
+---
+
+# Copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: vrouter
+data:
+  serviceConfig: |
+{{ toYaml .Values.serviceConfig | indent 4 }}
diff --git a/xos-services/vrouter/templates/deployment.yaml b/xos-services/vrouter/templates/deployment.yaml
new file mode 100644
index 0000000..82630a3
--- /dev/null
+++ b/xos-services/vrouter/templates/deployment.yaml
@@ -0,0 +1,73 @@
+---
+
+# Copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+apiVersion: apps/v1beta2
+kind: Deployment
+metadata:
+  name: {{ template "vrouter.fullname" . }}
+  labels:
+    app: {{ template "vrouter.name" . }}
+    chart: {{ template "vrouter.chart" . }}
+    release: {{ .Release.Name }}
+    heritage: {{ .Release.Service }}
+spec:
+  replicas: {{ .Values.replicaCount }}
+  selector:
+    matchLabels:
+      app: {{ template "vrouter.name" . }}
+      release: {{ .Release.Name }}
+  template:
+    metadata:
+      labels:
+        app: {{ template "vrouter.name" . }}
+        release: {{ .Release.Name }}
+      annotations:
+        checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
+    spec:
+      containers:
+        - name: {{ .Chart.Name }}
+          image: "{{ .Values.pull_docker_registry }}{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+          imagePullPolicy: {{ .Values.image.pullPolicy }}
+          resources:
+{{ toYaml .Values.resources | indent 12 }}
+          volumeMounts:
+            - name: vrouter-config
+              mountPath: /opt/xos/synchronizers/vrouter/vrouter_config.yaml
+              subPath: vrouter_config.yaml
+            - name: cert-chain-secret
+              mountPath: /usr/local/share/ca-certificates
+      volumes:
+        - name: vrouter-config
+          configMap:
+            name: vrouter
+            items:
+              - key: serviceConfig
+                path: vrouter_config.yaml
+        - name: cert-chain-secret
+          secret:
+            secretName: cert-chain-secret
+    {{- with .Values.nodeSelector }}
+      nodeSelector:
+{{ toYaml . | indent 8 }}
+    {{- end }}
+    {{- with .Values.affinity }}
+      affinity:
+{{ toYaml . | indent 8 }}
+    {{- end }}
+    {{- with .Values.tolerations }}
+      tolerations:
+{{ toYaml . | indent 8 }}
+    {{- end }}
diff --git a/xos-services/vrouter/values.yaml b/xos-services/vrouter/values.yaml
new file mode 100644
index 0000000..c267596
--- /dev/null
+++ b/xos-services/vrouter/values.yaml
@@ -0,0 +1,71 @@
+---
+
+# Copyright 2018-present Open Networking Foundation
+#
+# 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.
+
+# Default values for addressmanager.
+# This is a YAML-formatted file.
+# Declare variables to be passed into your templates.
+
+replicaCount: 1
+
+pull_docker_registry:
+
+nameOverride: ""
+fullnameOverride: ""
+
+image:
+  repository: xosproject/vrouter-synchronizer
+  tag: master
+  pullPolicy: IfNotPresent
+
+resources: {}
+
+nodeSelector: {}
+
+tolerations: []
+
+affinity: {}
+
+serviceConfig:
+  name: vrouter
+  accessor:
+    username: admin@opencord.org
+    password: letmein
+    endpoint: xos-core:50051
+  required_models:
+    - VRouterService
+    - VRouterDevice
+    - VRouterApp
+    - VRouterPort
+  dependency_graph: "/opt/xos/synchronizers/vrouter/model-deps"
+  steps_dir: "/opt/xos/synchronizers/vrouter/steps"
+  sys_dir: "/opt/xos/synchronizers/vrouter/sys"
+  models_dir: "/opt/xos/synchronizers/vrouter/models"
+  logging:
+    version: 1
+    handlers:
+      console:
+        class: logging.StreamHandler
+      file:
+        class: logging.handlers.RotatingFileHandler
+        filename: /var/log/xos.log
+        maxBytes: 10485760
+        backupCount: 5
+    loggers:
+      'multistructlog':
+        handlers:
+            - console
+            - file
+        level: DEBUG