Merge "Use ServiceAccount for netcheker server."
diff --git a/README.rst b/README.rst
index 37fa482..799495a 100644
--- a/README.rst
+++ b/README.rst
@@ -33,10 +33,9 @@
             image: gcr.io/google_containers/hyperkube:v1.6.5
         pool:
           network:
-            calicoctl:
-              image: calico/ctl
-            cni:
-              image: calico/cni
+            calico:
+              calicoctl_image: calico/ctl
+              cni_image: calico/cni
 
 Enable helm-tiller addon
 
@@ -319,11 +318,8 @@
           kubelet:
             allow_privileged: true
           network:
-            engine: calico
-            mtu: 1500
-            hash: fb5e30ebe6154911a66ec3fb5f1195b2
-            private_ip_range: 10.150.0.0/16
-            version: v0.19.0
+            cnis:
+            - calico
           service_addresses: 10.254.0.0/16
           storage:
             engine: glusterfs
@@ -368,10 +364,8 @@
               - host: 10.0.175.100
             host: 10.0.175.100
           network:
-            engine: calico
-            mtu: 1500
-            hash: fb5e30ebe6154911a66ec3fb5f1195b2
-            version: v0.19.0
+            cnis:
+            - calico
           token:
             kube_proxy: DFvQ8GelB7afH3wClC9romaMPhquyyEe
             kubelet: 7bN5hJ9JD4fKjnFTkUKsvVNfuyEddw3r
@@ -424,19 +418,21 @@
             image: yashulyak/contrail-controller:latest
       master:
         network:
-          engine: opencontrail
-          default_domain: default-domain
-          default_project: default-domain:default-project
-          public_network: default-domain:default-project:Public
-          public_ip_range: 185.22.97.128/26
-          private_ip_range: 10.150.0.0/16
-          service_cluster_ip_range: 10.254.0.0/16
-          network_label: name
-          service_label: uses
-          cluster_service: kube-system/default
-          config:
-            api:
-              host: 10.0.170.70
+          cnis:
+          - opencontrail
+          contrail:
+            default_domain: default-domain
+            default_project: default-domain:default-project
+            public_network: default-domain:default-project:Public
+            public_ip_range: 185.22.97.128/26
+            private_ip_range: 10.150.0.0/16
+            service_cluster_ip_range: 10.254.0.0/16
+            network_label: name
+            service_label: uses
+            cluster_service: kube-system/default
+            config:
+              api:
+                host: 10.0.170.70
 On pools:
 
 .. code-block:: yaml
@@ -444,7 +440,8 @@
     kubernetes:
       pool:
         network:
-          engine: opencontrail
+          cnis:
+          - opencontrail
 
 
 Dashboard public IP must be configured when Contrail network is used:
@@ -490,19 +487,8 @@
     kubernetes:
       master:
         network:
-          engine: flannel
-    # If you don't register master as node:
-          etcd:
-            members:
-              - host: 10.0.175.101
-                port: 4001
-              - host: 10.0.175.102
-                port: 4001
-              - host: 10.0.175.103
-                port: 4001
-      common:
-        network:
-          engine: flannel
+          cnis:
+          - flannel
 
 On pools:
 
@@ -511,18 +497,8 @@
     kubernetes:
       pool:
         network:
-          engine: flannel
-          etcd:
-            members:
-              - host: 10.0.175.101
-                port: 4001
-              - host: 10.0.175.102
-                port: 4001
-              - host: 10.0.175.103
-                port: 4001
-      common:
-        network:
-          engine: flannel
+          cnis:
+          - flannel
 
 Kubernetes with Calico
 -----------------------
@@ -534,17 +510,19 @@
     kubernetes:
       master:
         network:
-          engine: calico
-          mtu: 1500
+          cnis:
+          - calico
+          calico:
+            mtu: 1500
     # If you don't register master as node:
-          etcd:
-            members:
-              - host: 10.0.175.101
-                port: 4001
-              - host: 10.0.175.102
-                port: 4001
-              - host: 10.0.175.103
-                port: 4001
+            etcd:
+              members:
+                - host: 10.0.175.101
+                  port: 4001
+                - host: 10.0.175.102
+                  port: 4001
+                - host: 10.0.175.103
+                  port: 4001
 
 On pools:
 
@@ -553,16 +531,18 @@
     kubernetes:
       pool:
         network:
-          engine: calico
-          mtu: 1500
-          etcd:
-            members:
-              - host: 10.0.175.101
-                port: 4001
-              - host: 10.0.175.102
-                port: 4001
-              - host: 10.0.175.103
-                port: 4001
+          cnis:
+          - calico
+          calico:
+            mtu: 1500
+            etcd:
+              members:
+                - host: 10.0.175.101
+                  port: 4001
+                - host: 10.0.175.102
+                  port: 4001
+                - host: 10.0.175.103
+                  port: 4001
 
 Running with secured etcd:
 
@@ -571,17 +551,20 @@
     kubernetes:
       pool:
         network:
-          engine: calico
-          mtu: 1500
-          etcd:
-            ssl:
-              enabled: true
+          cnis:
+          - calico
+          calico:
+            etcd:
+              ssl:
+                enabled: true
       master:
         network:
-          engine: calico
-          etcd:
-            ssl:
-              enabled: true
+          cnis:
+          - calico
+          calico:
+            etcd:
+              ssl:
+                enabled: true
 
 Running with calico-policy controller:
 
@@ -590,16 +573,16 @@
     kubernetes:
       pool:
         network:
-          engine: calico
-          mtu: 1500
+          cnis:
+          - calico
           addons:
             calico_policy:
               enabled: true
 
       master:
         network:
-          engine: calico
-          mtu: 1500
+          cnis:
+          - calico
           addons:
             calico_policy:
               enabled: true
@@ -613,12 +596,14 @@
     kubernetes:
       pool:
         network:
-          prometheus:
-            enabled: true
+          calico:
+            prometheus:
+              enabled: true
       master:
         network:
-          prometheus:
-            enabled: true
+          calico:
+            prometheus:
+              enabled: true
 
 Post deployment configuration
 
diff --git a/kubernetes/files/calico/calico-node.service.master b/kubernetes/files/calico/calico-node.service.master
index 995f517..c91dd5c 100644
--- a/kubernetes/files/calico/calico-node.service.master
+++ b/kubernetes/files/calico/calico-node.service.master
@@ -11,22 +11,22 @@
  -e NODENAME={{ master.host.name }}{% if master.host.get('domain') %}.{{ master.host.domain }}{%- endif %} \
  -e IP={{ master.apiserver.address }} \
  -e IP6={{ master.get('ipv6_address', '') }} \
-{%- if master.network.calico_network_backend is defined %}
- -e CALICO_NETWORKING_BACKEND="{{ master.network.calico_network_backend }}"
+{%- if master.network.calico.network_backend is defined %}
+ -e CALICO_NETWORKING_BACKEND="{{ master.network.calico.network_backend }}"
 {%- endif %}
- -e AS={{ master.network.get('as', '64512') }} \
- -e NO_DEFAULT_MASTERS={{ master.network.get('no_default_masters') }} \
- -e CALICO_LIBNETWORK_ENABLED={{ master.network.get('libnetwork_enabled', true ) }} \
- -e ETCD_ENDPOINTS={% for member in master.network.etcd.members %}http{% if master.network.etcd.get('ssl', {}).get('enabled') %}s{% endif %}://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %} \
-{%- if master.network.etcd.get('ssl', {}).get('enabled') %}
+ -e AS={{ master.network.calico.get('as', '64512') }} \
+ -e NO_DEFAULT_MASTERS={{ master.network.calico.get('no_default_masters') }} \
+ -e CALICO_LIBNETWORK_ENABLED={{ master.network.calico.get('libnetwork_enabled', true ) }} \
+ -e ETCD_ENDPOINTS={% for member in master.network.calico.etcd.members %}http{% if master.network.calico.etcd.get('ssl', {}).get('enabled') %}s{% endif %}://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %} \
+{%- if master.network.calico.etcd.get('ssl', {}).get('enabled') %}
  -e ETCD_CA_CERT_FILE=/var/lib/etcd/ca.pem \
  -e ETCD_CERT_FILE=/var/lib/etcd/etcd-client.crt \
  -e ETCD_KEY_FILE=/var/lib/etcd/etcd-client.key \
  -v /var/lib/etcd/:/var/lib/etcd/:ro \
 {%- endif %}
-{%- if master.network.get('prometheus', {}).get('enabled') %}
+{%- if master.network.calico.get('prometheus', {}).get('enabled') %}
  -e FELIX_PROMETHEUSMETRICSENABLED=true \
- -p {{ pool.network.prometheus.get('address', '0.0.0.0') }}:{{ master.network.get('prometheus', {}).get('port', 9091) }}:9091 \
+ -p {{ pool.network.calico.prometheus.get('address', '0.0.0.0') }}:{{ master.network.calico.get('prometheus', {}).get('port', 9091) }}:9091 \
 {%- endif %}
  -v /var/log/calico:/var/log/calico \
  -v /run/docker/plugins:/run/docker/plugins \
@@ -37,7 +37,7 @@
  -v {{ volume }} \
 {%- endfor %}
 {%- endif %}
- {{ master.network.get('image', 'calico/node') }}
+ {{ master.network.calico.get('image', 'calico/node') }}
 
 Restart=always
 RestartSec=10s
diff --git a/kubernetes/files/calico/calico-node.service.pool b/kubernetes/files/calico/calico-node.service.pool
index 305518f..034a900 100644
--- a/kubernetes/files/calico/calico-node.service.pool
+++ b/kubernetes/files/calico/calico-node.service.pool
@@ -11,23 +11,23 @@
  -e NODENAME={{ pool.host.name }}{% if pool.host.get('domain') %}.{{ pool.host.domain }}{%- endif %} \
  -e IP={{ pool.address }} \
  -e IP6={{ pool.get('ipv6_address', '') }} \
-{%- if pool.network.calico_network_backend is defined %}
- -e CALICO_NETWORKING_BACKEND="{{ pool.network.calico_network_backend }}"
+{%- if pool.network.calico.network_backend is defined %}
+ -e CALICO_NETWORKING_BACKEND="{{ pool.network.calico.network_backend }}"
 {%- endif %}
- -e AS={{ pool.network.get('as', '64512') }} \
- -e NO_DEFAULT_POOLS={{ pool.network.get('no_default_pools') }} \
- -e CALICO_LIBNETWORK_ENABLED={{ pool.network.get('libnetwork_enabled', true ) }} \
- -e ETCD_ENDPOINTS={% for member in pool.network.etcd.members %}http{% if pool.network.etcd.get('ssl', {}).get('enabled') %}s{% endif %}://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %} \
-{%- if pool.network.etcd.get('ssl', {}).get('enabled') %}
+ -e AS={{ pool.network.calico.get('as', '64512') }} \
+ -e NO_DEFAULT_POOLS={{ pool.network.calico.get('no_default_pools') }} \
+ -e CALICO_LIBNETWORK_ENABLED={{ pool.network.calico.get('libnetwork_enabled', true ) }} \
+ -e ETCD_ENDPOINTS={% for member in pool.network.calico.etcd.members %}http{% if pool.network.calico.etcd.get('ssl', {}).get('enabled') %}s{% endif %}://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %} \
+{%- if pool.network.calico.etcd.get('ssl', {}).get('enabled') %}
  -e ETCD_CA_CERT_FILE=/var/lib/etcd/ca.pem \
  -e ETCD_CERT_FILE=/var/lib/etcd/etcd-client.crt \
  -e ETCD_KEY_FILE=/var/lib/etcd/etcd-client.key \
  -v /var/lib/etcd/:/var/lib/etcd/:ro \
 {%- endif %}
-{%- if pool.network.get('prometheus', {}).get('enabled') %}
+{%- if pool.network.calico.get('prometheus', {}).get('enabled') %}
  -e FELIX_PROMETHEUSMETRICSENABLED=true \
- -e FELIX_PROMETHEUSMETRICSPORT={{ pool.network.prometheus.get('port', 9091) }} \
- -p {{ pool.network.prometheus.get('address', '0.0.0.0') }}:{{ pool.network.prometheus.get('port', 9091) }}:9091 \
+ -e FELIX_PROMETHEUSMETRICSPORT={{ pool.network.calico.prometheus.get('port', 9091) }} \
+ -p {{ pool.network.calico.prometheus.get('address', '0.0.0.0') }}:{{ pool.network.calico.prometheus.get('port', 9091) }}:9091 \
 {%- endif %}
  -v /var/log/calico:/var/log/calico \
  -v /run/docker/plugins:/run/docker/plugins \
@@ -38,7 +38,7 @@
  -v {{ volume }} \
 {%- endfor %}
 {%- endif %}
- {{ pool.network.get('image', 'calico/node') }}
+ {{ pool.network.calico.get('image', 'calico/node') }}
 
 Restart=always
 RestartSec=10s
diff --git a/kubernetes/files/calico/calico.conf b/kubernetes/files/calico/calico.conf
index 7952945..81e383f 100644
--- a/kubernetes/files/calico/calico.conf
+++ b/kubernetes/files/calico/calico.conf
@@ -3,9 +3,10 @@
 {
     "nodeName": "{{ pool.host.name }}{% if pool.host.get('domain') %}.{{ pool.host.domain }}{%- endif %}",
     "name": "calico-k8s-network",
+    "cniVersion": "0.3.0",
     "type": "calico",
-    "etcd_endpoints": "{% for member in pool.network.etcd.members %}http{% if pool.network.etcd.get('ssl', {}).get('enabled') %}s{% endif %}://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %}",
-{%- if pool.network.etcd.get('ssl', {}).get('enabled') %}
+    "etcd_endpoints": "{% for member in pool.network.calico.etcd.members %}http{% if pool.network.calico.etcd.get('ssl', {}).get('enabled') %}s{% endif %}://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %}",
+{%- if pool.network.calico.etcd.get('ssl', {}).get('enabled') %}
     "etcd_key_file": "/var/lib/etcd/etcd-client.pem",
     "etcd_cert_file": "/var/lib/etcd/etcd-client.pem",
     "etcd_ca_cert_file": "/var/lib/etcd/ca.pem",
@@ -15,8 +16,8 @@
       "type": "k8s"
     },
 {%- endif %}
-{%- if pool.network.get('mtu') %}
-    "mtu": {{ pool.network.mtu }},
+{%- if pool.network.calico.get('mtu') %}
+    "mtu": {{ pool.network.calico.mtu }},
 {%- endif %}
     "log_level": "info",
     "ipam": {
diff --git a/kubernetes/files/calico/calicoctl.cfg.master b/kubernetes/files/calico/calicoctl.cfg.master
index 144c9a8..39e40d2 100644
--- a/kubernetes/files/calico/calicoctl.cfg.master
+++ b/kubernetes/files/calico/calicoctl.cfg.master
@@ -4,8 +4,8 @@
 metadata:
 spec:
   datastoreType: "etcdv3"
-  etcdEndpoints: {% for member in master.network.etcd.members %}http{% if master.network.etcd.get('ssl', {}).get('enabled') %}s{% endif %}://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %}
-{%- if master.network.etcd.get('ssl', {}).get('enabled') %}
+  etcdEndpoints: {% for member in master.network.calico.etcd.members %}http{% if master.network.calico.etcd.get('ssl', {}).get('enabled') %}s{% endif %}://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %}
+{%- if master.network.calico.etcd.get('ssl', {}).get('enabled') %}
   etcdKeyFile: /var/lib/etcd/etcd-client.pem
   etcdCertFile: /var/lib/etcd/etcd-client.pem
   etcdCACertFile: /var/lib/etcd/ca.pem
diff --git a/kubernetes/files/calico/calicoctl.cfg.pool b/kubernetes/files/calico/calicoctl.cfg.pool
index 25e95ad..b31ba68 100644
--- a/kubernetes/files/calico/calicoctl.cfg.pool
+++ b/kubernetes/files/calico/calicoctl.cfg.pool
@@ -4,8 +4,8 @@
 metadata:
 spec:
   datastoreType: "etcdv3"
-  etcdEndpoints: {% for member in pool.network.etcd.members %}http{% if pool.network.etcd.get('ssl', {}).get('enabled') %}s{% endif %}://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %}
-{%- if pool.network.etcd.get('ssl', {}).get('enabled') %}
+  etcdEndpoints: {% for member in pool.network.calico.etcd.members %}http{% if pool.network.calico.etcd.get('ssl', {}).get('enabled') %}s{% endif %}://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %}
+{%- if pool.network.calico.etcd.get('ssl', {}).get('enabled') %}
   etcdKeyFile: /var/lib/etcd/etcd-client.pem
   etcdCertFile: /var/lib/etcd/etcd-client.pem
   etcdCACertFile: /var/lib/etcd/ca.pem
diff --git a/kubernetes/files/calico/network-environment.master b/kubernetes/files/calico/network-environment.master
index 71d17c5..101fa5b 100644
--- a/kubernetes/files/calico/network-environment.master
+++ b/kubernetes/files/calico/network-environment.master
@@ -4,4 +4,4 @@
 DEFAULT_IPV4={{ master.apiserver.address }}
 
 # IP and port of etcd instance used by Calico
-ETCD_ENDPOINTS={% for member in master.network.etcd.members %}http://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %}
\ No newline at end of file
+ETCD_ENDPOINTS={% for member in master.network.calico.etcd.members %}http://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %}
\ No newline at end of file
diff --git a/kubernetes/files/calico/network-environment.pool b/kubernetes/files/calico/network-environment.pool
index 5607e65..06443bd 100644
--- a/kubernetes/files/calico/network-environment.pool
+++ b/kubernetes/files/calico/network-environment.pool
@@ -7,4 +7,4 @@
 KUBERNETES_MASTER={{ pool.apiserver.host }}:{{ pool.apiserver.secure_port }}
 
 # IP and port of etcd instance used by Calico
-ETCD_ENDPOINTS={% for member in pool.network.etcd.members %}http://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %}
+ETCD_ENDPOINTS={% for member in pool.network.calico.etcd.members %}http://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %}
diff --git a/kubernetes/files/dockershim/default.pool b/kubernetes/files/dockershim/default.pool
index 85f8230..308b5d6 100644
--- a/kubernetes/files/dockershim/default.pool
+++ b/kubernetes/files/dockershim/default.pool
@@ -21,12 +21,8 @@
 {%- else %}
 --node-labels=node-role.kubernetes.io/node=true \
 {%- endif %}
-{%- if pool.network.engine in ['calico', 'opencontrail', 'flannel'] %}
 --network-plugin=cni \
 --cni-bin-dir={{ pool.apiserver.get('cni_bin_dir', '/opt/cni/bin') }} \
-{%- else %}
---network-plugin-dir=/etc/cni/net.d \
-{%- endif %}
 --file-check-frequency={{ pool.kubelet.frequency }} \
 {%- if common.get('cloudprovider', {}).get('enabled') %}
 --cloud-provider={{ common.cloudprovider.provider }} \
diff --git a/kubernetes/files/flannel/flannel.conflist b/kubernetes/files/flannel/flannel.conflist
index 9c17665..583e5e6 100644
--- a/kubernetes/files/flannel/flannel.conflist
+++ b/kubernetes/files/flannel/flannel.conflist
@@ -1,8 +1,10 @@
 {
   "name": "cbr0",
+  "cniVersion": "0.3.0",
   "plugins": [
     {
       "type": "flannel",
+      "cniVersion": "0.3.0",
       "delegate": {
         "hairpinMode": true,
         "isDefaultGateway": true
diff --git a/kubernetes/files/genie/genie.conf b/kubernetes/files/genie/genie.conf
new file mode 100644
index 0000000..819ee56
--- /dev/null
+++ b/kubernetes/files/genie/genie.conf
@@ -0,0 +1,15 @@
+{
+    "name": "k8s-pod-network",
+    "cniVersion": "0.3.0",
+    "type": "genie",
+    "log_level": "info",
+    "datastore_type": "kubernetes",
+    "hostname": "{{ hostname }}",
+    "policy": {
+        "type": "k8s"
+    },
+    "kubernetes": {
+        "kubeconfig": "/etc/kubernetes/kubelet.kubeconfig"
+    }
+}
+
diff --git a/kubernetes/files/kube-addons/calico-policy/calico-policy-controller.yml b/kubernetes/files/kube-addons/calico-policy/calico-policy-controller.yml
index 3234421..19611f2 100644
--- a/kubernetes/files/kube-addons/calico-policy/calico-policy-controller.yml
+++ b/kubernetes/files/kube-addons/calico-policy/calico-policy-controller.yml
@@ -20,6 +20,10 @@
       namespace: {{ common.addons.calico_policy.namespace }}
       labels:
         k8s-app: calico-policy
+      annotations:
+{%- if common.addons.calico_policy.cni is defined %}
+        cni: {{ common.addons.calico_policy.cni }}
+{%- endif %}
     spec:
       hostNetwork: true
       tolerations:
@@ -38,7 +42,7 @@
               memory: 64M
           env:
             - name: ETCD_ENDPOINTS
-              value: "{% for member in master.network.etcd.members %}http{% if master.network.etcd.get('ssl', {}).get('enabled') %}s{% endif %}://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %}"
+              value: "{% for member in master.network.calico.etcd.members %}http{% if master.network.calico.etcd.get('ssl', {}).get('enabled') %}s{% endif %}://{{ member.host }}:{{ member.port }}{% if not loop.last %},{% endif %}{% endfor %}"
             - name: ETCD_CA_CERT_FILE
               value: "/var/lib/etcd/ca.pem"
             - name: ETCD_CERT_FILE
diff --git a/kubernetes/files/kube-addons/contrail-network-controller/contrail-network-controller-configmap.yml b/kubernetes/files/kube-addons/contrail-network-controller/contrail-network-controller-configmap.yml
index 4252e5a..1402d13 100644
--- a/kubernetes/files/kube-addons/contrail-network-controller/contrail-network-controller-configmap.yml
+++ b/kubernetes/files/kube-addons/contrail-network-controller/contrail-network-controller-configmap.yml
@@ -14,14 +14,14 @@
     service-cluster-ip-range = {{ master.service_addresses }}
 
     [opencontrail]
-    default-domain = {{ master.network.get('default_domain', 'default-domain') }}
-    public-ip-range = {{ master.network.get('public_ip_range', '185.22.97.128/26') }}
-    cluster-service = {{ master.network.get('cluster_service', 'kube-system/default') }}
-    api-server = {{ master.network.config.api.host }}
-    api-port = {{ master.network.get('port', 8082) }}
-    default = {{ master.network.get('default_project', 'default-domain:default-project') }}
-    public-network = {{ master.network.get('public_network', 'default-domain:default-project:Public') }}
-    private-ip-range = {{ master.network.private_ip_range }}
-    network-label = {{ master.network.get('network_label', 'opencontrail.org/name') }}
-    service-label = {{ master.network.get('service_label', 'opencontrail.org/uses') }}
+    default-domain = {{ master.network.contrail.get('default_domain', 'default-domain') }}
+    public-ip-range = {{ master.network.contrail.get('public_ip_range', '185.22.97.128/26') }}
+    cluster-service = {{ master.network.contrail.get('cluster_service', 'kube-system/default') }}
+    api-server = {{ master.network.contrail.config.api.host }}
+    api-port = {{ master.network.contrail.get('port', 8082) }}
+    default = {{ master.network.contrail.get('default_project', 'default-domain:default-project') }}
+    public-network = {{ master.network.contrail.get('public_network', 'default-domain:default-project:Public') }}
+    private-ip-range = {{ master.network.contrail.private_ip_range }}
+    network-label = {{ master.network.contrail.get('network_label', 'opencontrail.org/name') }}
+    service-label = {{ master.network.contrail.get('service_label', 'opencontrail.org/uses') }}
     service-cluster-ip-range = {{ master.get('service_addresses', '10.254.0.0/16') }}
diff --git a/kubernetes/files/kube-addons/coredns/coredns-deploy.yml b/kubernetes/files/kube-addons/coredns/coredns-deploy.yml
index e1e2dd3..065b48c 100644
--- a/kubernetes/files/kube-addons/coredns/coredns-deploy.yml
+++ b/kubernetes/files/kube-addons/coredns/coredns-deploy.yml
@@ -22,6 +22,9 @@
       annotations:
         scheduler.alpha.kubernetes.io/critical-pod: ''
         scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'
+{%- if common.addons.coredns.cni is defined %}
+        cni: {{ common.addons.coredns.cni }}
+{%- endif %}
     spec:
       tolerations:
         - key: node-role.kubernetes.io/master
diff --git a/kubernetes/files/kube-addons/coredns/coredns-etcd-operator-deployment.yaml b/kubernetes/files/kube-addons/coredns/coredns-etcd-operator-deployment.yaml
index 0ec870d..ba981f4 100644
--- a/kubernetes/files/kube-addons/coredns/coredns-etcd-operator-deployment.yaml
+++ b/kubernetes/files/kube-addons/coredns/coredns-etcd-operator-deployment.yaml
@@ -19,6 +19,10 @@
     metadata:
       labels:
         name: coredns-etcd-operator
+      annotations:
+{%- if common.addons.coredns.cni is defined %}
+        cni: {{ common.addons.coredns.cni }}
+{%- endif %}
     spec:
       tolerations:
         - key: node-role.kubernetes.io/master
diff --git a/kubernetes/files/kube-addons/dashboard/dashboard-controller.yaml b/kubernetes/files/kube-addons/dashboard/dashboard-controller.yaml
index 371b4ca..c4b22ee 100644
--- a/kubernetes/files/kube-addons/dashboard/dashboard-controller.yaml
+++ b/kubernetes/files/kube-addons/dashboard/dashboard-controller.yaml
@@ -19,6 +19,9 @@
       annotations:
         scheduler.alpha.kubernetes.io/critical-pod: ''
         scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'
+{%- if common.addons.dashboard.cni is defined %}
+        cni: {{ common.addons.dashboard.cni }}
+{%- endif %}
     spec:
       tolerations:
         - key: node-role.kubernetes.io/master
diff --git a/kubernetes/files/kube-addons/dashboard/dashboard-service.yaml b/kubernetes/files/kube-addons/dashboard/dashboard-service.yaml
index 26deb7b..717010d 100644
--- a/kubernetes/files/kube-addons/dashboard/dashboard-service.yaml
+++ b/kubernetes/files/kube-addons/dashboard/dashboard-service.yaml
@@ -1,3 +1,4 @@
+{%- from "kubernetes/map.jinja" import common with context %}
 {%- from "kubernetes/map.jinja" import master with context %}
 apiVersion: v1
 kind: Service
@@ -9,9 +10,9 @@
     kubernetes.io/cluster-service: "true"
     addonmanager.kubernetes.io/mode: Reconcile
 spec:
-{%- if master.network.engine != 'opencontrail' %}
   selector:
     k8s-app: kubernetes-dashboard
+{%- if (common.addons.dashboard.cni is defined and common.addons.dashboard.cni != 'opencontrail') or 'opencontrail' not in master.network.cnis %}
   type: NodePort
 {%- endif %}
   ports:
diff --git a/kubernetes/files/kube-addons/dns/kubedns-autoscaler.yaml b/kubernetes/files/kube-addons/dns/kubedns-autoscaler.yaml
index d07f47b..2403540 100644
--- a/kubernetes/files/kube-addons/dns/kubedns-autoscaler.yaml
+++ b/kubernetes/files/kube-addons/dns/kubedns-autoscaler.yaml
@@ -12,6 +12,10 @@
     metadata:
       labels:
         k8s-app: kube-dns-autoscaler
+      annotations:
+{%- if common.addons.dns.cni is defined %}
+        cni: {{ common.addons.dns.cni }}
+{%- endif %}
     spec:
       tolerations:
         - key: node-role.kubernetes.io/master
diff --git a/kubernetes/files/kube-addons/dns/kubedns-rc.yaml b/kubernetes/files/kube-addons/dns/kubedns-rc.yaml
index 7a415b0..8090402 100644
--- a/kubernetes/files/kube-addons/dns/kubedns-rc.yaml
+++ b/kubernetes/files/kube-addons/dns/kubedns-rc.yaml
@@ -45,6 +45,9 @@
       annotations:
         scheduler.alpha.kubernetes.io/critical-pod: ''
         scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'
+{%- if common.addons.dns.cni is defined %}
+        cni: {{ common.addons.dns.cni }}
+{%- endif %}
     spec:
       tolerations:
         - key: node-role.kubernetes.io/master
diff --git a/kubernetes/files/kube-addons/externaldns/externaldns-deploy.yml b/kubernetes/files/kube-addons/externaldns/externaldns-deploy.yml
index a47d75e..4304de9 100644
--- a/kubernetes/files/kube-addons/externaldns/externaldns-deploy.yml
+++ b/kubernetes/files/kube-addons/externaldns/externaldns-deploy.yml
@@ -16,6 +16,10 @@
     metadata:
       labels:
         app: external-dns
+      annotations:
+{%- if common.addons.externaldns.cni is defined %}
+        cni: {{ common.addons.externaldns.cni }}
+{%- endif %}
     spec:
       tolerations:
         - key: node-role.kubernetes.io/master
diff --git a/kubernetes/files/kube-addons/flannel/flannel.yml b/kubernetes/files/kube-addons/flannel/flannel.yml
index 095dbe8..58d0217 100644
--- a/kubernetes/files/kube-addons/flannel/flannel.yml
+++ b/kubernetes/files/kube-addons/flannel/flannel.yml
@@ -63,7 +63,7 @@
 data:
   net-conf.json: |
     {
-      "Network": "{{ master.network.private_ip_range }}",
+      "Network": "{{ master.network.flannel.private_ip_range }}",
       "Backend": {
         "Type": "vxlan"
       }
diff --git a/kubernetes/files/kube-addons/helm/helm-tiller-deploy.yml b/kubernetes/files/kube-addons/helm/helm-tiller-deploy.yml
index cfbb823..ef8df02 100644
--- a/kubernetes/files/kube-addons/helm/helm-tiller-deploy.yml
+++ b/kubernetes/files/kube-addons/helm/helm-tiller-deploy.yml
@@ -21,6 +21,10 @@
       labels:
         app: helm
         name: tiller
+      annotations:
+{%- if common.addons.helm.cni is defined %}
+        cni: {{ common.addons.helm.cni }}
+{%- endif %}
     spec:
       {%- if 'RBAC' in master.auth.get('mode', "") %}
       serviceAccountName: tiller
diff --git a/kubernetes/files/kube-addons/netchecker/netchecker-agent.yml b/kubernetes/files/kube-addons/netchecker/netchecker-agent.yml
index 5ee722b..efcd2c1 100644
--- a/kubernetes/files/kube-addons/netchecker/netchecker-agent.yml
+++ b/kubernetes/files/kube-addons/netchecker/netchecker-agent.yml
@@ -13,6 +13,10 @@
       name: netchecker-agent
       labels:
         app: netchecker-agent
+      annotations:
+{%- if common.addons.netchecker.cni is defined %}
+        cni: {{ common.addons.netchecker.cni }}
+{%- endif %}
     spec:
       tolerations:
         - key: node-role.kubernetes.io/master
diff --git a/kubernetes/files/kube-addons/netchecker/netchecker-server.yml b/kubernetes/files/kube-addons/netchecker/netchecker-server.yml
index c72a771..7106d1a 100644
--- a/kubernetes/files/kube-addons/netchecker/netchecker-server.yml
+++ b/kubernetes/files/kube-addons/netchecker/netchecker-server.yml
@@ -18,6 +18,9 @@
       annotations:
         prometheus.io/scrape: "true"
         prometheus.io/port: "{{ common.addons.netchecker.port }}"
+{%- if common.addons.netchecker.cni is defined %}
+        cni: {{ common.addons.netchecker.cni }}
+{%- endif %}
     spec:
       serviceAccountName: netchecker
       tolerations:
diff --git a/kubernetes/files/kube-addons/registry/registry-rc.yaml b/kubernetes/files/kube-addons/registry/registry-rc.yaml
index bd2f50f..ba115c6 100644
--- a/kubernetes/files/kube-addons/registry/registry-rc.yaml
+++ b/kubernetes/files/kube-addons/registry/registry-rc.yaml
@@ -19,6 +19,10 @@
       labels:
         k8s-app: kube-registry
         version: v0
+      annotations:
+{%- if common.addons.registry.cni is defined %}
+        cni: {{ common.addons.registry.cni }}
+{%- endif %}
     spec:
       tolerations:
         - key: node-role.kubernetes.io/master
diff --git a/kubernetes/files/kube-addons/virtlet/virtlet-ds.yml b/kubernetes/files/kube-addons/virtlet/virtlet-ds.yml
index d68d31e..73a03fa 100644
--- a/kubernetes/files/kube-addons/virtlet/virtlet-ds.yml
+++ b/kubernetes/files/kube-addons/virtlet/virtlet-ds.yml
@@ -17,7 +17,7 @@
         runtime: virtlet
     spec:
       hostNetwork: true
-      {%- if master.network.engine != "opencontrail" %}
+      {%- if "opencontrail" not in master.network.cnis %}
       dnsPolicy: ClusterFirstWithHostNet
       {%- endif %}
       # hostPID is true to (1) enable VMs to survive virtlet container restart
@@ -148,7 +148,7 @@
           {%- endif %}
         - name: vms-log
           mountPath: /var/log/vms
-        {%- if master.network.engine == "opencontrail" %}
+        {%- if "opencontrail" in master.network.cnis %}
         - name: contrail-log
           mountPath: /var/log/contrail
         - name: contrail-data
@@ -277,7 +277,7 @@
       - configMap:
           name: virtlet-image-translations
         name: image-name-translations
-      {%- if master.network.engine == "opencontrail" %}
+      {%- if "opencontrail" in master.network.cnis %}
       - hostPath:
           path: /var/log/contrail
         name: contrail-log
@@ -439,4 +439,4 @@
   name: virtlet-image-translations
   namespace: {{ common.addons.virtlet.namespace }}
   labels:
-    addonmanager.kubernetes.io/mode: Reconcile
\ No newline at end of file
+    addonmanager.kubernetes.io/mode: Reconcile
diff --git a/kubernetes/files/kubelet/default.pool b/kubernetes/files/kubelet/default.pool
index 79586f3..7e2ce2f 100644
--- a/kubernetes/files/kubelet/default.pool
+++ b/kubernetes/files/kubelet/default.pool
@@ -26,12 +26,8 @@
 {%- else %}
 --node-labels=node-role.kubernetes.io/node=true \
 {%- endif %}
-{%- if pool.network.engine in ['calico', 'opencontrail', 'flannel'] %}
 --network-plugin=cni \
 --cni-bin-dir={{ pool.apiserver.get('cni_bin_dir', '/opt/cni/bin') }} \
-{%- else %}
---network-plugin-dir=/etc/cni/net.d \
-{%- endif %}
 --file-check-frequency={{ pool.kubelet.frequency }} \
 {%- if common.get('cloudprovider', {}).get('enabled') %}
 --cloud-provider={{ common.cloudprovider.provider }} \
diff --git a/kubernetes/files/manifest/kube-apiserver.manifest b/kubernetes/files/manifest/kube-apiserver.manifest
index 0d24f9a..d00f9eb 100644
--- a/kubernetes/files/manifest/kube-apiserver.manifest
+++ b/kubernetes/files/manifest/kube-apiserver.manifest
@@ -31,9 +31,7 @@
       --requestheader-extra-headers-prefix={{ master.auth.proxy.header.extra }}
       --requestheader-client-ca-file={{ master.auth.proxy.ca_file|default("/etc/kubernetes/ssl/ca-"+master.ca+".crt") }}
       {%- endif %}
-      {%- if master.auth.get('anonymous', False) %}
-      --anonymous-auth=true
-      {%- endif %}
+      --anonymous-auth={{ master.auth.get('anonymous', {}).enabled|default(False) }}
       {%- if master.auth.get('basic', {}).enabled|default(True) %}
       --basic-auth-file={{ master.auth.basic.file|default("/srv/kubernetes/basic_auth.csv") }}
       {%- endif %}
diff --git a/kubernetes/files/manifest/kube-proxy.manifest.pool b/kubernetes/files/manifest/kube-proxy.manifest.pool
index 15b943c..55912ad 100644
--- a/kubernetes/files/manifest/kube-proxy.manifest.pool
+++ b/kubernetes/files/manifest/kube-proxy.manifest.pool
@@ -21,7 +21,7 @@
       --kubeconfig=/etc/kubernetes/proxy.kubeconfig
       --master={%- if pool.apiserver.insecure.enabled %}http://{{
 pool.apiserver.host }}:{{ pool.apiserver.insecure_port }}{%- else %}https://{{ pool.apiserver.host }}:{{ pool.apiserver.secure_port }}{%- endif %}
-{%- if pool.network.engine == 'calico' %}
+{%- if 'calico' in pool.network.cnis %}
       --proxy-mode=iptables
 {%- endif %}
 {%- for key, value in pool.get('proxy', {}).get('daemon_opts', {}).items() %}
diff --git a/kubernetes/files/opencontrail/4.0/contrail-kubernetes.conf b/kubernetes/files/opencontrail/4.0/contrail-kubernetes.conf
index 83587bc..b7a22cd 100644
--- a/kubernetes/files/opencontrail/4.0/contrail-kubernetes.conf
+++ b/kubernetes/files/opencontrail/4.0/contrail-kubernetes.conf
@@ -3,47 +3,47 @@
 kubernetes_api_server={{ master.apiserver.insecure_address }}
 kubernetes_api_port={{ master.apiserver.insecure_port }}
 kubernetes_api_secure_port={{ master.apiserver.secure_port }}
-service_subnets={{ master.network.get('service_subnets', '10.96.0.0/12') }}
-pod_subnets={{ master.network.get('pod_subnets', '10.32.0.0/12') }}
-cluster_name={{ master.network.get('cluster_name', 'default') }}
-cluster_project={{ master.network.get('cluster_project', '{}') }}
-cluster_network={{ master.network.get('cluster_network', '') }}
-kubernetes_cluster_domain={{ master.network.get('cluster_domain', 'default-domain') }}
-kubernetes_cluster_name={{ master.network.get('cluster_name', 'kubernetes') }}
-kubernetes_cluster_owner={{ master.network.get('cluster_owner', 'k8s') }}
-kubernetes_service_name={{ master.network.get('service_name', 'kubernetes') }}
+service_subnets={{ master.network.contrail.get('service_subnets', '10.96.0.0/12') }}
+pod_subnets={{ master.network.contrail.get('pod_subnets', '10.32.0.0/12') }}
+cluster_name={{ master.network.contrail.get('cluster_name', 'default') }}
+cluster_project={{ master.network.contrail.get('cluster_project', '{}') }}
+cluster_network={{ master.network.contrail.get('cluster_network', '') }}
+kubernetes_cluster_domain={{ master.network.contrail.get('cluster_domain', 'default-domain') }}
+kubernetes_cluster_name={{ master.network.contrail.get('cluster_name', 'kubernetes') }}
+kubernetes_cluster_owner={{ master.network.contrail.get('cluster_owner', 'k8s') }}
+kubernetes_service_name={{ master.network.contrail.get('service_name', 'kubernetes') }}
 
 [VNC]
-vnc_endpoint_ip = {{ master.network.config.api.host }}
-vnc_endpoint_port = {{ master.network.config.api.get('port', 8082) }}
-admin_user = {{ master.network.identity.get('auth_user', 'admin') }}
-admin_password = {{ master.network.identity.get('auth_password', 'admin') }}
-admin_tenant = {{ master.network.identity.get('auth_tenant', 'admin') }}
-rabbit_server={{ master.network.message_queue.host }}
-rabbit_port={{ master.network.message_queue.get('port', 5672) }}
-rabbit_user={{ master.network.message_queue.get('user', 'guest') }}
-rabbit_password={{ master.network.message_queue.get('password', 'guest') }}
-rabbit_vhost={{ master.network.message_queue.get('vhost', '/') }}
-rabbit_ha_mode={{ master.network.message_queue.get('ha_mode', False) }}
-rabbit_use_ssl={{ master.network.message_queue.get('use_ssl', False) }}
-{%- if master.network.message_queue.get('use_ssl', False) == True %}
-kombu_ssl_version={{ master.network.message_queue.ssl_version }}
-kombu_ssl_keyfile={{ master.network.message_queue.ssl_keyfile }}
-kombu_ssl_certfile={{ master.network.message_queue.ssl_certfile }}
-kombu_ssl_ca_certs={{ master.network.message_queue.ssl_ca_certs }}
+vnc_endpoint_ip = {{ master.network.contrail.config.api.host }}
+vnc_endpoint_port = {{ master.network.contrail.config.api.get('port', 8082) }}
+admin_user = {{ master.network.contrail.identity.get('auth_user', 'admin') }}
+admin_password = {{ master.network.contrail.identity.get('auth_password', 'admin') }}
+admin_tenant = {{ master.network.contrail.identity.get('auth_tenant', 'admin') }}
+rabbit_server={{ master.network.contrail.message_queue.host }}
+rabbit_port={{ master.network.contrail.message_queue.get('port', 5672) }}
+rabbit_user={{ master.network.contrail.message_queue.get('user', 'guest') }}
+rabbit_password={{ master.network.contrail.message_queue.get('password', 'guest') }}
+rabbit_vhost={{ master.network.contrail.message_queue.get('vhost', '/') }}
+rabbit_ha_mode={{ master.network.contrail.message_queue.get('ha_mode', False) }}
+rabbit_use_ssl={{ master.network.contrail.message_queue.get('use_ssl', False) }}
+{%- if master.network.contrail.message_queue.get('use_ssl', False) == True %}
+kombu_ssl_version={{ master.network.contrail.message_queue.ssl_version }}
+kombu_ssl_keyfile={{ master.network.contrail.message_queue.ssl_keyfile }}
+kombu_ssl_certfile={{ master.network.contrail.message_queue.ssl_certfile }}
+kombu_ssl_ca_certs={{ master.network.contrail.message_queue.ssl_ca_certs }}
 {%- endif %}
-cassandra_server_list={% for member in master.network.database.members %}{{ member.host }}:{{ member.get('port', '9160')}} {% endfor %}
-cassandra_user={{ master.network.database.get('user', None) }}
-cassandra_password={{ master.network.database.get('password', None) }}
+cassandra_server_list={% for member in master.network.contrail.database.members %}{{ member.host }}:{{ member.get('port', '9160')}} {% endfor %}
+cassandra_user={{ master.network.contrail.database.get('user', None) }}
+cassandra_password={{ master.network.contrail.database.get('password', None) }}
 cluster_id=
-public_fip_pool={{ master.network.get('public_pool', '{}') }}
+public_fip_pool={{ master.network.contrail.get('public_pool', '{}') }}
 
 [DEFAULTS]
 log_local=1
 log_level=SYS_DEBUG
 log_file=/var/log/contrail/contrail-kube-manager.log
-collectors={% for member in master.network.collector.members %}{{ member.host }}:8086 {% endfor %}
-nested_mode={{ master.network.get('nested_mode', 0) }}
+collectors={% for member in master.network.contrail.collector.members %}{{ member.host }}:8086 {% endfor %}
+nested_mode={{ master.network.contrail.get('nested_mode', 0) }}
 
 [SANDESH]
 #sandesh_ssl_enable=False
@@ -53,7 +53,7 @@
 #sandesh_ca_cert=/etc/contrail/ssl/certs/ca-cert.pem
 
 [AUTH]
-auth_token_url={{ master.network.identity.get('auth_token_url', None) }}
-auth_user={{ master.network.identity.get('auth_user', 'admin') }}
-auth_password={{ master.network.identity.get('auth_token_url', 'admin') }}
-auth_tenant={{ master.network.identity.get('auth_token_url', 'admin') }}
+auth_token_url={{ master.network.contrail.identity.get('auth_token_url', None) }}
+auth_user={{ master.network.contrail.identity.get('auth_user', 'admin') }}
+auth_password={{ master.network.contrail.identity.get('auth_token_url', 'admin') }}
+auth_tenant={{ master.network.contrail.identity.get('auth_token_url', 'admin') }}
diff --git a/kubernetes/files/opencontrail/network.conf b/kubernetes/files/opencontrail/network.conf
index 5ea6398..db66c0d 100644
--- a/kubernetes/files/opencontrail/network.conf
+++ b/kubernetes/files/opencontrail/network.conf
@@ -3,13 +3,13 @@
 service-cluster-ip-range = {{ master.service_addresses }}
 
 [opencontrail]
-default-domain = {{ master.network.get('default_domain', 'default-domain') }}
-public-ip-range = {{ master.network.public_ip_range }}
-cluster-service = {{ master.network.get('cluster_service', 'kube-system/default') }}
-api-server = {{ master.network.config.api.host }}
-api-port = {{ master.network.get('port', '8082') }}
-default-project = {{ master.network.get('default_project','default-domain:default-project') }}
-public-network = {{ master.network.public_network }}
-private-ip-range = {{ master.network.private_ip_range }}
-network-label = {{ master.network.get('network_label','name') }}
-service-label = {{ master.network.get('service_label','uses') }}
+default-domain = {{ master.network.contrail.get('default_domain', 'default-domain') }}
+public-ip-range = {{ master.network.contrail.public_ip_range }}
+cluster-service = {{ master.network.contrail.get('cluster_service', 'kube-system/default') }}
+api-server = {{ master.network.contrail.config.api.host }}
+api-port = {{ master.network.contrail.get('port', '8082') }}
+default-project = {{ master.network.contrail.get('default_project','default-domain:default-project') }}
+public-network = {{ master.network.contrail.public_network }}
+private-ip-range = {{ master.network.contrail.private_ip_range }}
+network-label = {{ master.network.contrail.get('network_label','name') }}
+service-label = {{ master.network.contrail.get('service_label','uses') }}
diff --git a/kubernetes/files/opencontrail/opencontrail.conf b/kubernetes/files/opencontrail/opencontrail.conf
index d675318..de28481 100644
--- a/kubernetes/files/opencontrail/opencontrail.conf
+++ b/kubernetes/files/opencontrail/opencontrail.conf
@@ -1,8 +1,8 @@
 {%- from "kubernetes/map.jinja" import pool with context %}
 {
-    "cniVersion": "0.2.0",
+    "cniVersion": "0.3.0",
     "contrail" : {
-        "apiserver": {"address": "{{ pool.network.config.api.host }}", "port": {{ pool.network.config.api.get('port', 8082) }}, "default-domain": "default-domain"},
+        "apiserver": {"address": "{{ pool.network.contrail.config.api.host }}", "port": {{ pool.network.contrail.config.api.get('port', 8082) }}, "default-domain": "default-domain"},
         "vrouter" : {
             "ip" : "127.0.0.1",
             "port" : 9091
diff --git a/kubernetes/master/calico.sls b/kubernetes/master/calico.sls
index 3522fb3..4d0fb48 100644
--- a/kubernetes/master/calico.sls
+++ b/kubernetes/master/calico.sls
@@ -21,27 +21,33 @@
     - dir_mode: 755
     - template: jinja
 
-/tmp/calico/master/:
+/tmp/calico/:
   file.directory:
       - user: root
       - group: root
-      - makedirs: True
 
-download_calicoctl:
+copy-calico-ctl:
   cmd.run:
-     - name: wget -P /tmp/calico/master/ {{ master.network.get('source', 'https://github.com/projectcalico/calico-containers/releases/download/') }}{{ master.network.version }}/calicoctl
-     - require:
-       - file: /tmp/calico/master/
+    - name: docker run --rm -v /tmp/calico/:/tmp/calico/ --entrypoint cp {{ master.network.calico.calicoctl_image }} -v /calicoctl /tmp/calico/
+    - require:
+      - file: /tmp/calico/
+    {%- if grains.get('noservices') %}
+    - onlyif: /bin/false
+    {%- endif %}
 
 /usr/bin/calicoctl:
   file.managed:
-     - source: /tmp/calico/master/calicoctl
-     - source_hash: md5={{ master.network.hash }}
-     - mode: 751
-     - user: root
-     - group: root
+    - source: /tmp/calico/calicoctl
+    - mode: 751
+    - user: root
+    - group: root
+    - require:
+      - cmd: copy-calico-ctl
+    {%- if grains.get('noservices') %}
+    - onlyif: /bin/false
+    {%- endif %}
 
-{%- if master.network.get('systemd', true) %}
+{%- if master.network.calico.get('systemd', true) %}
 
 /etc/systemd/system/calico-node.service:
   file.managed:
diff --git a/kubernetes/master/controller.sls b/kubernetes/master/controller.sls
index f8ae0a2..697b039 100644
--- a/kubernetes/master/controller.sls
+++ b/kubernetes/master/controller.sls
@@ -112,9 +112,7 @@
         --requestheader-extra-headers-prefix={{ master.auth.proxy.header.extra }}
         --requestheader-client-ca-file={{ master.auth.proxy.ca_file|default("/etc/kubernetes/ssl/ca-"+master.ca+".crt") }}
         {%- endif %}
-        {%- if master.auth.get('anonymous', False) %}
-        --anonymous-auth=true
-        {%- endif %}
+        --anonymous-auth={{ master.auth.get('anonymous', {}).enabled|default(False) }}
         --etcd-quorum-read=true
         --insecure-bind-address={{ master.apiserver.insecure_address }}
         --insecure-port={{ master.apiserver.insecure_port }}
@@ -190,9 +188,9 @@
 {%- endif %}
 {%- endif %}
         --v={{ master.get('verbosity', 2) }}
-{%- if master.network.engine == 'flannel' %}
+{%- if 'flannel' in master.network.cnis %}
         --allocate-node-cidrs=true
-        --cluster-cidr={{ master.network.private_ip_range }}
+        --cluster-cidr={{ master.network.flannel.private_ip_range }}
 {%- endif %}
 {%- for key, value in master.get('controller_manager', {}).get('daemon_opts', {}).items() %}
         --{{ key }}={{ value }}
diff --git a/kubernetes/master/flannel.sls b/kubernetes/master/flannel.sls
index fa140eb..c11283d 100644
--- a/kubernetes/master/flannel.sls
+++ b/kubernetes/master/flannel.sls
@@ -3,7 +3,7 @@
 
 {%- if not pillar.kubernetes.pool is defined %}
 
-/etc/cni/net.d/11-flannel.conflist:
+/etc/cni/net.d/12-flannel.conflist:
   file.managed:
     - source: salt://kubernetes/files/flannel/flannel.conflist
     - user: root
diff --git a/kubernetes/master/genie.sls b/kubernetes/master/genie.sls
new file mode 100644
index 0000000..51c2139
--- /dev/null
+++ b/kubernetes/master/genie.sls
@@ -0,0 +1,46 @@
+{%- from "kubernetes/map.jinja" import master with context %}
+{%- if master.enabled %}
+
+{%- if not pillar.kubernetes.pool is defined %}
+
+/etc/cni/net.d/00-genie.conf:
+  file.managed:
+    - source: salt://kubernetes/files/genie/genie.conf
+    - user: root
+    - group: root
+    - mode: 644
+    - makedirs: true
+    - dir_mode: 755
+    - template: jinja
+    - default:
+        hostname: {{ master.host.name }}{% if master.host.get('domain') %}.{{ master.host.domain }}{%- endif %}
+
+/tmp/genie/:
+  file.directory:
+      - user: root
+      - group: root
+
+copy-genie-bin:
+  cmd.run:
+    - name: docker run --rm -v /tmp/genie/:/tmp/genie/ --entrypoint cp {{ master.network.genie.image }} -v /opt/cni/bin/genie /tmp/genie/
+    - require:
+      - file: /tmp/genie/
+    {%- if grains.get('noservices') %}
+    - onlyif: /bin/false
+    {%- endif %}
+
+/opt/cni/bin/genie:
+  file.managed:
+    - source: /tmp/genie/genie
+    - mode: 751
+    - user: root
+    - group: root
+    - require:
+      - cmd: copy-genie-bin
+    {%- if grains.get('noservices') %}
+    - onlyif: /bin/false
+    {%- endif %}
+
+{%- endif %}
+
+{%- endif %}
diff --git a/kubernetes/master/init.sls b/kubernetes/master/init.sls
index 7d00fd6..9994124 100644
--- a/kubernetes/master/init.sls
+++ b/kubernetes/master/init.sls
@@ -2,17 +2,22 @@
 include:
 - kubernetes.master.service
 - kubernetes.master.kube-addons
-{%- if master.network.engine == "flannel" %}
+{%- if "flannel" in master.network.cnis %}
 - kubernetes.master.flannel
 {%- endif %}
-{%- if master.network.engine == "opencontrail" %}
+{%- if "opencontrail" in master.network.cnis %}
 - kubernetes.master.opencontrail
 {%- endif %}
-{%- if master.network.engine == "calico" %}
+{%- if "calico" in master.network.cnis %}
 {%- if not pillar.kubernetes.pool is defined %}
 - kubernetes.master.calico
 {%- endif %}
 {%- endif %}
+{%- if "genie" in master.network.cnis %}
+{%- if not pillar.kubernetes.pool is defined %}
+- kubernetes.master.genie
+{%- endif %}
+{%- endif %}
 {%- if master.storage.get('engine', 'none') == 'glusterfs' %}
 - kubernetes.master.glusterfs
 {%- endif %}
diff --git a/kubernetes/master/kube-addons.sls b/kubernetes/master/kube-addons.sls
index 04f13ae..2bd2b90 100644
--- a/kubernetes/master/kube-addons.sls
+++ b/kubernetes/master/kube-addons.sls
@@ -9,7 +9,7 @@
     - group: root
     - mode: 0755
 
-{%- if master.network.engine == "flannel" %}
+{%- if "flannel" in master.network.cnis %}
 /etc/kubernetes/addons/flannel/flannel.yml:
   file.managed:
     - source: salt://kubernetes/files/kube-addons/flannel/flannel.yml
@@ -19,7 +19,7 @@
     - makedirs: True
 {% endif %}
 
-{%- if master.network.engine == "opencontrail" and master.network.get('version', 3.0) < 4.0 %}
+{%- if "opencontrail" in master.network.cnis and master.network.contrail.get('version', 3.0) < 4.0 %}
 /etc/kubernetes/addons/contrail-network-controller/contrail-network-controller-configmap.yml:
   file.managed:
     - source: salt://kubernetes/files/kube-addons/contrail-network-controller/contrail-network-controller-configmap.yml
@@ -36,7 +36,7 @@
     - dir_mode: 755
     - makedirs: True
 
-{%- elif master.network.engine == "opencontrail" and master.network.get('version', 3.0) > 3.0 %}
+{%- elif "opencontrail" in master.network.cnis and master.network.contrail.get('version', 3.0) > 3.0 %}
 
 /etc/kubernetes/addons/contrail/contrail.yaml:
   file.managed:
@@ -67,7 +67,7 @@
 
 {% endif %}
 
-{%- if common.addons.get('calico_policy', {}).get('enabled', False) and master.network.engine == "calico" %}
+{%- if common.addons.get('calico_policy', {}).get('enabled', False) and "calico" in master.network.cnis %}
 /etc/kubernetes/addons/calico_policy/calico-policy-controller.yml:
   file.managed:
     - source: salt://kubernetes/files/kube-addons/calico-policy/calico-policy-controller.yml
diff --git a/kubernetes/master/opencontrail.sls b/kubernetes/master/opencontrail.sls
index 462f992..05827fc 100644
--- a/kubernetes/master/opencontrail.sls
+++ b/kubernetes/master/opencontrail.sls
@@ -1,16 +1,16 @@
 {%- from "kubernetes/map.jinja" import master with context %}
 {%- if master.enabled %}
-{%- if master.network.get('version', 3.0) != 3.0 %}
+{%- if master.network.contrail.get('version', 3.0) != 3.0 %}
 
 /etc/contrail/contrail-kubernetes.conf:
   file.managed:
-  - source: salt://kubernetes/files/opencontrail/{{ master.network.version }}/contrail-kubernetes.conf
+  - source: salt://kubernetes/files/opencontrail/{{ master.network.contrail.version }}/contrail-kubernetes.conf
   - template: jinja
   - makedirs: True
 
-#/etc/kubernetes/opencontrail/contrail-{{ master.network.version }}.yaml:
+#/etc/kubernetes/opencontrail/contrail-{{ master.network.contrail.version }}.yaml:
 #  file.managed:
-#  - source: salt://kubernetes/files/manifest/contrail-{{ master.network.version }}.manifest
+#  - source: salt://kubernetes/files/manifest/contrail-{{ master.network.contrail.version }}.manifest
 #  - template: jinja
 #  - makedirs: True
 
diff --git a/kubernetes/meta/collectd.yml b/kubernetes/meta/collectd.yml
index 50ebbe9..e1089f4 100644
--- a/kubernetes/meta/collectd.yml
+++ b/kubernetes/meta/collectd.yml
@@ -11,7 +11,7 @@
 
 {%- if master.get('enabled', False) or pool.get('enabled', False) %}
 local_plugin:
-  {%- if network is defined and network.get('engine', None) == 'calico' %}
+  {%- if network.cnis is defined and 'calico' in network.cnis %}
   collectd_calico_felix:
    plugin: python
    template: kubernetes/files/collectd_calico_felix.conf
@@ -73,7 +73,7 @@
       k8s-proxy:
         match: hyperkube.*proxy
 {%- endif %}
-{%- if network is defined and network.get('engine', None) == 'calico' %}
+{%- if network.cnis is defined and 'calico' in network.cnis %}
       calico-docker:
         match: docker run .*projectcalico/calico/node
       calico-felix:
diff --git a/kubernetes/meta/fluentd.yml b/kubernetes/meta/fluentd.yml
index b2a27dc..84a82b2 100644
--- a/kubernetes/meta/fluentd.yml
+++ b/kubernetes/meta/fluentd.yml
@@ -36,7 +36,7 @@
               type: json
               time_format: '%Y-%m-%dT%H:%M:%S.%NZ'
               keep_time_key: false
-          {%- if network is defined and network.get('engine', None) == 'calico' %}
+          {%- if network.cnis is defined and 'calico' in network.cnis %}
           bird:
             type: tail
             tag: kubernetes.calico.bird
@@ -96,7 +96,7 @@
                 value: 6
               - name: programname
                 value: ${ record['kubernetes']['container_name'] }
-          {%- if network is defined and network.get('engine', None) == 'calico' %}
+          {%- if network.cnis is defined and 'calico' in network.cnis %}
           enrich_bird:
             tag: 'kubernetes.calico.bird'
             type: record_transformer
diff --git a/kubernetes/meta/grafana.yml b/kubernetes/meta/grafana.yml
index bf3667b..e91c594 100644
--- a/kubernetes/meta/grafana.yml
+++ b/kubernetes/meta/grafana.yml
@@ -10,7 +10,7 @@
     datasource: prometheus
     format: json
     template: kubernetes/files/grafana_dashboards/kubernetes_cluster_prometheus.json
-{%- if network is defined and network.get('engine') == 'calico' %}
+{%- if network.cnis is defined and 'calico' in network.cnis %}
   calico-prometheus:
     datasource: prometheus
     format: json
@@ -20,7 +20,7 @@
     datasource: influxdb
     format: json
     template: kubernetes/files/grafana_dashboards/kubernetes_influxdb.json
-{%- if network is defined and network.get('engine') == 'calico' %}
+{%- if network.cnis is defined and 'calico' in network.cnis %}
   calico:
     datasource: influxdb
     format: json
diff --git a/kubernetes/meta/heka.yml b/kubernetes/meta/heka.yml
index 21d85c5..1bd76d6 100644
--- a/kubernetes/meta/heka.yml
+++ b/kubernetes/meta/heka.yml
@@ -11,7 +11,7 @@
 {% endif %}
 {% endif %}
 
-{%- if network is defined and network.get('engine', None) == 'calico' %}
+{%- if network.cnis is defined and 'calico' in network.cnis %}
 log_collector:
   decoder:
     calico_felix:
@@ -106,7 +106,7 @@
         periods: 0
         function: last
 {%- endif %}
-{%- if network is defined and network.get('engine', None) == 'calico' %}
+{%- if network.cnis is defined and 'calico' in network.cnis %}
     calico_docker:
       description: "There is no docker calico-node process running"
       severity: down
@@ -194,7 +194,7 @@
       dimension:
         service: k8s-proxy-endpoint
 {%- endif %}
-{%- if network is defined and network.get('engine', None) == 'calico' %}
+{%- if network.cnis is defined and 'calico' in network.cnis %}
     calico_docker:
       alerting: enabled
       triggers:
@@ -381,7 +381,7 @@
       dimension:
         cluster_name: k8s-master
         nagios_host: 00-top-clusters
-{%- if master.get('network', []).get('engine', None) == 'calico' %}
+{%- if master.network.cnis is defined and 'calico' in master.network.cnis %}
     calico_docker:
       policy: availability_of_members
       alerting: enabled
diff --git a/kubernetes/meta/prometheus.yml b/kubernetes/meta/prometheus.yml
index f7a4c67..60813cb 100644
--- a/kubernetes/meta/prometheus.yml
+++ b/kubernetes/meta/prometheus.yml
@@ -15,16 +15,16 @@
       api_ip: {{ pool.apiserver.host }}
       cert_name: prometheus-server.crt
       key_name: prometheus-server.key
-{%- if network.get('engine', '') == 'calico' and network.get('prometheus', {}).get('enabled', False) %}
+{%- if network.cnis is defined and 'calico' in network.cnis and network.calico.get('prometheus', {}).get('enabled', False) %}
     static:
       calico:
         endpoint:
 {%- if pool.get('enabled', False) %}
-          - address: {{ network.prometheus.get('address', pool.address) }}
+          - address: {{ network.calico.prometheus.get('address', pool.address) }}
 {%- else %}
-          - address: {{ network.prometheus.get('address', master.address) }}
+          - address: {{ network.calico.prometheus.get('address', master.address) }}
 {%- endif %}
-            port: {{ network.prometheus.get('port', 9091) }}
+            port: {{ network.calico.prometheus.get('port', 9091) }}
 {%- endif %}
   recording:
     cluster_namespace_controller_pod_container:spec_memory_limit_bytes:
@@ -190,7 +190,7 @@
         summary: 'Kubernetes service {{ $labels.process_name }} is down'
         description: 'Kubernetes service {{ $labels.process_name }} is down on node {{ $labels.host }}'
       {% endraw %}
-{%- if network.get('engine', '') == 'calico' %}
+{%- if network.cnis is defined and 'calico' in network.cnis %}
     CalicoProcessDown:
       if: >-
         procstat_running{process_name=~"calico-felix|bird|bird6|confd"} == 0
diff --git a/kubernetes/meta/telegraf.yml b/kubernetes/meta/telegraf.yml
index 8be559f..5046918 100644
--- a/kubernetes/meta/telegraf.yml
+++ b/kubernetes/meta/telegraf.yml
@@ -26,7 +26,7 @@
         hyperkube-kubelet:
           pattern: "hyperkube.*kubelet"
   {%- endif %}
-  {%- if network is defined and network.get('engine', None) == 'calico' %}
+  {%- if network.cnis is defined and 'calico' in network.cnis %}
         hyperkube-proxy:
           pattern: "hyperkube.*proxy"
         calico-docker:
diff --git a/kubernetes/pool/calico.sls b/kubernetes/pool/calico.sls
index 4b1a8d1..ef47e2a 100644
--- a/kubernetes/pool/calico.sls
+++ b/kubernetes/pool/calico.sls
@@ -8,7 +8,7 @@
 
 copy-calico-ctl:
   cmd.run:
-    - name: docker run --rm -v /tmp/calico/:/tmp/calico/ --entrypoint cp {{ pool.network.calicoctl.image }} -v /calicoctl /tmp/calico/
+    - name: docker run --rm -v /tmp/calico/:/tmp/calico/ --entrypoint cp {{ pool.network.calico.calicoctl_image }} -v /calicoctl /tmp/calico/
     - require:
       - file: /tmp/calico/
     {%- if grains.get('noservices') %}
@@ -29,7 +29,7 @@
 
 copy-calico-node:
   cmd.run:
-    - name: docker run --rm -v /tmp/calico/:/tmp/calico/ --entrypoint cp {{ pool.network.get('image', 'calico/node') }} -v /bin/birdcl /tmp/calico/
+    - name: docker run --rm -v /tmp/calico/:/tmp/calico/ --entrypoint cp {{ pool.network.calico.get('image', 'calico/node') }} -v /bin/birdcl /tmp/calico/
     - require:
       - file: /tmp/calico/
     {%- if grains.get('noservices') %}
@@ -50,7 +50,7 @@
 
 copy-calico-cni:
   cmd.run:
-    - name: docker run --rm -v /tmp/calico/:/tmp/calico/ --entrypoint cp {{ pool.network.cni.image }} -vr /opt/cni/bin/ /tmp/calico/
+    - name: docker run --rm -v /tmp/calico/:/tmp/calico/ --entrypoint cp {{ pool.network.calico.cni_image }} -vr /opt/cni/bin/ /tmp/calico/
     - require:
       - file: /tmp/calico/
     {%- if grains.get('noservices') %}
@@ -106,7 +106,7 @@
     - dir_mode: 755
     - template: jinja
 
-{%- if pool.network.get('systemd', true) %}
+{%- if pool.network.calico.get('systemd', true) %}
 
 /etc/systemd/system/calico-node.service:
   file.managed:
diff --git a/kubernetes/pool/flannel.sls b/kubernetes/pool/flannel.sls
index 4f00759..416a107 100644
--- a/kubernetes/pool/flannel.sls
+++ b/kubernetes/pool/flannel.sls
@@ -1,7 +1,7 @@
 {%- from "kubernetes/map.jinja" import pool with context %}
 {%- if pool.enabled %}
 
-/etc/cni/net.d/11-flannel.conflist:
+/etc/cni/net.d/12-flannel.conflist:
   file.managed:
     - source: salt://kubernetes/files/flannel/flannel.conflist
     - user: root
diff --git a/kubernetes/pool/genie.sls b/kubernetes/pool/genie.sls
new file mode 100644
index 0000000..4bba5cc
--- /dev/null
+++ b/kubernetes/pool/genie.sls
@@ -0,0 +1,42 @@
+{%- from "kubernetes/map.jinja" import pool with context %}
+{%- if pool.enabled %}
+
+/etc/cni/net.d/00-genie.conf:
+  file.managed:
+    - source: salt://kubernetes/files/genie/genie.conf
+    - user: root
+    - group: root
+    - mode: 644
+    - makedirs: true
+    - dir_mode: 755
+    - template: jinja
+    - default:
+        hostname: {{ pool.host.name }}{% if pool.host.get('domain') %}.{{ pool.host.domain }}{%- endif %}
+
+/tmp/genie/:
+  file.directory:
+      - user: root
+      - group: root
+
+copy-genie-bin:
+  cmd.run:
+    - name: docker run --rm -v /tmp/genie/:/tmp/genie/ --entrypoint cp {{ pool.network.genie.image }} -v /opt/cni/bin/genie /tmp/genie/
+    - require:
+      - file: /tmp/genie/
+    {%- if grains.get('noservices') %}
+    - onlyif: /bin/false
+    {%- endif %}
+
+/opt/cni/bin/genie:
+  file.managed:
+    - source: /tmp/genie/genie
+    - mode: 751
+    - user: root
+    - group: root
+    - require:
+      - cmd: copy-genie-bin
+    {%- if grains.get('noservices') %}
+    - onlyif: /bin/false
+    {%- endif %}
+
+{%- endif %}
diff --git a/kubernetes/pool/init.sls b/kubernetes/pool/init.sls
index b23da8c..3acb6f8 100644
--- a/kubernetes/pool/init.sls
+++ b/kubernetes/pool/init.sls
@@ -1,14 +1,17 @@
 {%- from "kubernetes/map.jinja" import pool with context %}
 include:
 - kubernetes.pool.cni
-{%- if pool.network.engine == "calico" %}
+{%- if "calico" in pool.network.cnis %}
 - kubernetes.pool.calico
 {%- endif %}
-{%- if pool.network.engine == "opencontrail" %}
+{%- if "opencontrail" in pool.network.cnis %}
 - kubernetes.pool.opencontrail
 {%- endif %}
 - kubernetes.pool.service
-{%- if pool.network.engine == "flannel" %}
+{%- if "flannel" in pool.network.cnis %}
 - kubernetes.pool.flannel
 {%- endif %}
+{%- if "genie" in pool.network.cnis %}
+- kubernetes.pool.genie
+{%- endif %}
 - kubernetes.pool.kube-proxy
diff --git a/kubernetes/pool/kube-proxy.sls b/kubernetes/pool/kube-proxy.sls
index a420c56..efadc34 100644
--- a/kubernetes/pool/kube-proxy.sls
+++ b/kubernetes/pool/kube-proxy.sls
@@ -1,5 +1,4 @@
 {%- from "kubernetes/map.jinja" import pool with context %}
-{%- if pool.enabled and pool.network.engine != 'opencontrail' %}
 
 {%- if pool.get('container', 'true') %}
 
@@ -37,7 +36,7 @@
     - user: root
     - group: root
     - mode: 644
-    - contents: DAEMON_ARGS=" --logtostderr=true --v={{ pool.get('verbosity', 2) }} --kubeconfig=/etc/kubernetes/proxy.kubeconfig {%- if pool.network.engine == 'calico' %} --proxy-mode=iptables{% endif %}{%- for key, value in pool.get('proxy', {}).get('daemon_opts', {}).items() %} --{{ key }}={{ value }}{%- endfor %}"
+    - contents: DAEMON_ARGS=" --logtostderr=true --v={{ pool.get('verbosity', 2) }} --kubeconfig=/etc/kubernetes/proxy.kubeconfig {%- if 'calico' in pool.network.cnis %} --proxy-mode=iptables{% endif %}{%- for key, value in pool.get('proxy', {}).get('daemon_opts', {}).items() %} --{{ key }}={{ value }}{%- endfor %}"
 
 pool_services:
   service.running:
@@ -52,5 +51,3 @@
   {%- endif %}
 
 {%- endif %}
-
-{%- endif %}
diff --git a/kubernetes/pool/opencontrail.sls b/kubernetes/pool/opencontrail.sls
index 6fc008d..419804a 100644
--- a/kubernetes/pool/opencontrail.sls
+++ b/kubernetes/pool/opencontrail.sls
@@ -11,7 +11,7 @@
     - dir_mode: 755
     - template: jinja
 
-{%- if pool.network.get('version', '3.0') == '3.0' %}
+{%- if pool.network.contrail.get('version', '3.0') == '3.0' %}
 
 /tmp/opencontrail:
   file.directory:
@@ -20,7 +20,7 @@
 
 copy-contrail-cni:
   cmd.run:
-    - name: docker cp $(docker create  {{ pool.network.contrail_cni.image }}):/opencontrail /tmp/opencontrail
+    - name: docker cp $(docker create  {{ pool.network.contrail.cni_image }}):/opencontrail /tmp/opencontrail
     - require:
       - file: /tmp/opencontrail
     {%- if grains.get('noservices') %}
diff --git a/metadata/service/common.yml b/metadata/service/common.yml
index bedb3b3..62669c8 100644
--- a/metadata/service/common.yml
+++ b/metadata/service/common.yml
@@ -69,6 +69,3 @@
           domain_name: default
       cluster_domain: ${_param:kubernetes_cluster_domain}
       cluster_name: ${_param:cluster_name}
-      network:
-        engine: none
-        mtu: 1500
diff --git a/metadata/service/master/cluster.yml b/metadata/service/master/cluster.yml
index 8088d33..afeb317 100644
--- a/metadata/service/master/cluster.yml
+++ b/metadata/service/master/cluster.yml
@@ -29,8 +29,6 @@
         insecure_address: 127.0.0.1
         insecure_port: 8080
         count: 3
-        daemon_opts:
-          anonymous-auth: false
       etcd:
         members:
           - host: ${_param:cluster_node01_address}
@@ -53,14 +51,15 @@
         kube-system:
           enabled: True
       network:
-        etcd:
-          members:
-          - host: ${_param:cluster_node01_address}
-            port: 4001
-          - host: ${_param:cluster_node02_address}
-            port: 4001
-          - host: ${_param:cluster_node03_address}
-            port: 4001
+        calico:
+          etcd:
+            members:
+            - host: ${_param:cluster_node01_address}
+              port: 4001
+            - host: ${_param:cluster_node02_address}
+              port: 4001
+            - host: ${_param:cluster_node03_address}
+              port: 4001
       federation:
         enabled: False
         name: federation
diff --git a/metadata/service/master/single.yml b/metadata/service/master/single.yml
index 80ad876..f2d119b 100644
--- a/metadata/service/master/single.yml
+++ b/metadata/service/master/single.yml
@@ -19,6 +19,7 @@
       kubelet:
         address: ${_param:cluster_local_address}
         allow_privileged: True
+        fail_on_swap: True
       apiserver:
         address: ${_param:single_address}
         bind_address: 0.0.0.0
@@ -26,8 +27,6 @@
         internal_address: ${_param:kubernetes_internal_api_address}
         insecure_address: 127.0.0.1
         insecure_port: 8080
-        daemon_opts:
-          anonymous-auth: false
       etcd:
         members:
           - host: ${_param:single_address}
@@ -78,10 +77,11 @@
         kube-system:
           enabled: True
       network:
-        etcd:
-          members:
-            - host: ${_param:single_address}
-              port: 4001
+        calico:
+          etcd:
+            members:
+              - host: ${_param:single_address}
+                port: 4001
       federation:
         enabled: False
         name: federation
diff --git a/metadata/service/pool/cluster.yml b/metadata/service/pool/cluster.yml
index 173690c..cc5bec7 100644
--- a/metadata/service/pool/cluster.yml
+++ b/metadata/service/pool/cluster.yml
@@ -37,12 +37,12 @@
         kube_proxy: ${_param:kubernetes_kube-proxy_token}
       ca: kubernetes
       network:
-        hash: 77169cdadb80a5e33e9d9fe093ed0d99
-        etcd:
-          members:
-          - host: ${_param:cluster_node01_address}
-            port: 4001
-          - host: ${_param:cluster_node02_address}
-            port: 4001
-          - host: ${_param:cluster_node03_address}
-            port: 4001
+        calico:
+          etcd:
+            members:
+            - host: ${_param:cluster_node01_address}
+              port: 4001
+            - host: ${_param:cluster_node02_address}
+              port: 4001
+            - host: ${_param:cluster_node03_address}
+              port: 4001
diff --git a/metadata/service/pool/single.yml b/metadata/service/pool/single.yml
index eefb9ce..28c61fb 100644
--- a/metadata/service/pool/single.yml
+++ b/metadata/service/pool/single.yml
@@ -28,13 +28,14 @@
         config: /etc/kubernetes/manifests
         allow_privileged: True
         frequency: 5s
+        fail_on_swap: True
       token:
         kubelet: ${_param:kubernetes_kubelet_token}
         kube_proxy: ${_param:kubernetes_kube-proxy_token}
       ca: kubernetes
       network:
-        hash: 77169cdadb80a5e33e9d9fe093ed0d99
-        etcd:
-          members:
-          - host: ${_param:master_address}
-            port: 4001
+        calico:
+          etcd:
+            members:
+            - host: ${_param:master_address}
+              port: 4001
diff --git a/tests/pillar/common_storageclass.sls b/tests/pillar/common_storageclass.sls
index 6050fe9..613cc13 100644
--- a/tests/pillar/common_storageclass.sls
+++ b/tests/pillar/common_storageclass.sls
@@ -15,18 +15,19 @@
       kube-system:
         enabled: true
     network:
-      engine: calico
-      hash: fb5e30ebe6154911a66ec3fb5f1195b2
-      private_ip_range: 10.150.0.0/16
-      version: v0.19.0
-      etcd:
-        members:
-        - host: 127.0.0.1
-          port: 4001
-        - host: 127.0.0.1
-          port: 4001
-        - host: 127.0.0.1
-          port: 4001
+      cnis:
+      - calico
+      calico:
+        calicoctl_image: calico/ctl
+        cni_image: calico/cni
+        etcd:
+          members:
+          - host: 127.0.0.1
+            port: 4001
+          - host: 127.0.0.1
+            port: 4001
+          - host: 127.0.0.1
+            port: 4001
     service_addresses: 10.254.0.0/16
     storage:
       engine: glusterfs
@@ -41,8 +42,6 @@
     registry:
         host: tcpcloud
   common:
-    network:
-      engine: none
     addons:
       storageclass:
         nfs_elastic_1:
diff --git a/tests/pillar/master_cluster.sls b/tests/pillar/master_cluster.sls
index a0c2a2c..06dcace 100644
--- a/tests/pillar/master_cluster.sls
+++ b/tests/pillar/master_cluster.sls
@@ -2,8 +2,6 @@
   common:
     cluster_domain: cluster.local
     cluster_name: cluster
-    network:
-      engine: none
     hyperkube:
       image: hyperkube-amd64:v1.6.4-3
       hash: hnsj0XqABgrSww7Nqo7UVTSZLJUt2XRd
@@ -70,18 +68,19 @@
       address: 10.0.175.100
       allow_privileged: true
     network:
-      engine: calico
-      hash: 9D8F997FEE542420B15986FEA0EDF253
-      private_ip_range: 10.150.0.0/16
-      version: v1.6.3
-      etcd:
-        members:
-        - host: 127.0.0.1
-          port: 4001
-        - host: 127.0.0.1
-          port: 4001
-        - host: 127.0.0.1
-          port: 4001
+      cnis:
+      - calico
+      calico:
+        calicoctl_image: calico/ctl
+        cni_image: calico/cni
+        etcd:
+          members:
+          - host: 127.0.0.1
+            port: 4001
+          - host: 127.0.0.1
+            port: 4001
+          - host: 127.0.0.1
+            port: 4001
     service_addresses: 10.254.0.0/16
     storage:
       engine: glusterfs
diff --git a/tests/pillar/master_contrail.sls b/tests/pillar/master_contrail.sls
index c9b2ab3..627b032 100644
--- a/tests/pillar/master_contrail.sls
+++ b/tests/pillar/master_contrail.sls
@@ -3,7 +3,8 @@
     cluster_domain: cluster.local
     cluster_name: cluster
     network:
-      engine: opencontrail
+      cnis:
+      - opencontrail
     hyperkube:
       image: hyperkube-amd64:v1.6.4-3
       hash: hnsj0XqABgrSww7Nqo7UVTSZLJUt2XRd
@@ -74,21 +75,23 @@
       address: 10.0.175.100
       allow_privileged: true
     network:
-      engine: opencontrail
-      config:
-        api:
-          host: 10.0.170.70
-      port: 8082
-      default_domain: default-domain
-      default_project: default-domain:default-project
-      public_network: default-domain:default-project:Public
-      public_ip_range: 185.22.97.128/26
-      private_ip_range: 10.150.0.0/16
-      service_cluster_ip_range: 10.254.0.0/16
-      network_label: name
-      service_label: uses
-      cluster_service: kube-system/default
-      image: tianon/true
+      cnis:
+      - opencontrail
+      contrail:
+        config:
+          api:
+            host: 10.0.170.70
+        port: 8082
+        default_domain: default-domain
+        default_project: default-domain:default-project
+        public_network: default-domain:default-project:Public
+        public_ip_range: 185.22.97.128/26
+        private_ip_range: 10.150.0.0/16
+        service_cluster_ip_range: 10.254.0.0/16
+        network_label: name
+        service_label: uses
+        cluster_service: kube-system/default
+        image: tianon/true
     service_addresses: 10.254.0.0/16
     storage:
       engine: glusterfs
diff --git a/tests/pillar/master_contrail4_0.sls b/tests/pillar/master_contrail4_0.sls
index dbf8e87..e703b2e 100644
--- a/tests/pillar/master_contrail4_0.sls
+++ b/tests/pillar/master_contrail4_0.sls
@@ -3,7 +3,8 @@
     cluster_domain: cluster.local
     cluster_name: cluster
     network:
-      engine: opencontrail
+      cnis:
+      - opencontrail
     hyperkube:
       image: hyperkube-amd64:v1.6.4-3
       hash: hnsj0XqABgrSww7Nqo7UVTSZLJUt2XRd
@@ -71,26 +72,28 @@
       address: 10.0.175.100
       allow_privileged: true
     network:
-      engine: opencontrail
-      version: 4.0
-      private_ip_range: 10.150.0.0/16
-      config:
-        api:
+      cnis:
+      - opencontrail
+      contrail:
+        version: 4.0
+        private_ip_range: 10.150.0.0/16
+        config:
+          api:
+            host: 127.0.0.1
+        message_queue:
           host: 127.0.0.1
-      message_queue:
-        host: 127.0.0.1
-      identity:
-        password: password
-      database:
-        members:
-        - host: 127.0.0.1
-        - host: 127.0.0.1
-        - host: 127.0.0.1
-      collector:
-        members:
-        - host: 127.0.0.1
-        - host: 127.0.0.1
-        - host: 127.0.0.1
+        identity:
+          password: password
+        database:
+          members:
+          - host: 127.0.0.1
+          - host: 127.0.0.1
+          - host: 127.0.0.1
+        collector:
+          members:
+          - host: 127.0.0.1
+          - host: 127.0.0.1
+          - host: 127.0.0.1
     storage:
       engine: glusterfs
       members:
diff --git a/tests/pillar/pool_cluster.sls b/tests/pillar/pool_cluster.sls
index 1dc2f0b..21c8448 100644
--- a/tests/pillar/pool_cluster.sls
+++ b/tests/pillar/pool_cluster.sls
@@ -2,8 +2,6 @@
   common:
     cluster_domain: cluster.local
     cluster_name: cluster
-    network:
-      engine: none
     hyperkube:
       image: hyperkube-amd64:v1.6.4-3
       hash: hnsj0XqABgrSww7Nqo7UVTSZLJUt2XRd
@@ -50,21 +48,16 @@
       kube_proxy: DFvQ8GelB7afH3wClC9romaMPhquyyEe
     ca: kubernetes
     network:
-      calicoctl:
-        image: calico/ctl
-      cni:
-        image: calico/cni
-      engine: calico
-      hash: c15ae251b633109e63bf128c2fbbc34a
-      ipam:
-        hash: 6e6d7fac0567a8d90a334dcbfd019a99
-        version: v1.3.1
-      version: v0.20.0
-      etcd:
-        members:
-        - host: 127.0.0.1
-          port: 4001
-        - host: 127.0.0.1
-          port: 4001
-        - host: 127.0.0.1
-          port: 4001
+      cnis:
+      - calico
+      calico:
+        calicoctl_image: calico/ctl
+        cni_image: calico/cni
+        etcd:
+          members:
+          - host: 127.0.0.1
+            port: 4001
+          - host: 127.0.0.1
+            port: 4001
+          - host: 127.0.0.1
+            port: 4001
diff --git a/tests/pillar/pool_cluster_with_domain.sls b/tests/pillar/pool_cluster_with_domain.sls
index f756dd4..9ad7f69 100644
--- a/tests/pillar/pool_cluster_with_domain.sls
+++ b/tests/pillar/pool_cluster_with_domain.sls
@@ -2,8 +2,6 @@
   common:
     cluster_domain: cluster.local
     cluster_name: cluster
-    network:
-      engine: none
     hyperkube:
       image: hyperkube-amd64:v1.6.4-3
       hash: hnsj0XqABgrSww7Nqo7UVTSZLJUt2XRd
@@ -51,21 +49,16 @@
       kube_proxy: DFvQ8GelB7afH3wClC9romaMPhquyyEe
     ca: kubernetes
     network:
-      calicoctl:
-        image: calico/ctl
-      cni:
-        image: calico/cni
-      engine: calico
-      hash: c15ae251b633109e63bf128c2fbbc34a
-      ipam:
-        hash: 6e6d7fac0567a8d90a334dcbfd019a99
-        version: v1.3.1
-      version: v0.20.0
-      etcd:
-        members:
-        - host: 127.0.0.1
-          port: 4001
-        - host: 127.0.0.1
-          port: 4001
-        - host: 127.0.0.1
-          port: 4001
+      cnis:
+      - calico
+      calico:
+        calicoctl_image: calico/ctl
+        cni_image: calico/cni
+        etcd:
+          members:
+          - host: 127.0.0.1
+            port: 4001
+          - host: 127.0.0.1
+            port: 4001
+          - host: 127.0.0.1
+            port: 4001
diff --git a/tests/pillar/pool_contrail4_0.sls b/tests/pillar/pool_contrail4_0.sls
index da58e06..3b0595c 100644
--- a/tests/pillar/pool_contrail4_0.sls
+++ b/tests/pillar/pool_contrail4_0.sls
@@ -2,8 +2,6 @@
   common:
     cluster_domain: cluster.local
     cluster_name: cluster
-    network:
-      engine: none
     hyperkube:
       image: hyperkube-amd64:v1.6.4-3
       hash: hnsj0XqABgrSww7Nqo7UVTSZLJUt2XRd
@@ -50,8 +48,10 @@
       kube_proxy: DFvQ8GelB7afH3wClC9romaMPhquyyEe
     ca: kubernetes
     network:
-      engine: opencontrail
-      version: 4.0
-      config:
-        api:
-          host: 127.0.0.1
+      cnis:
+      - opencontrail
+      contrail:
+        version: 4.0
+        config:
+          api:
+            host: 127.0.0.1