Merge "Add kubernetes addon manager manifest"
diff --git a/README.rst b/README.rst
index 77565ef..263d1a3 100644
--- a/README.rst
+++ b/README.rst
@@ -1191,37 +1191,3 @@
 * https://github.com/Juniper/kubernetes/blob
 /opencontrail-integration/docs /getting-started-guides/opencontrail.md
 * https://github.com/kubernetes/kubernetes/tree/master/cluster/saltbase
-
-
-Documentation and Bugs
-======================
-
-To learn how to install and update salt-formulas, consult the documentation
-available online at:
-
-    http://salt-formulas.readthedocs.io/
-
-In the unfortunate event that bugs are discovered, they should be reported to
-the appropriate issue tracker. Use Github issue tracker for specific salt
-formula:
-
-    https://github.com/salt-formulas/salt-formula-kubernetes/issues
-
-For feature requests, bug reports or blueprints affecting entire ecosystem,
-use Launchpad salt-formulas project:
-
-    https://launchpad.net/salt-formulas
-
-You can also join salt-formulas-users team and subscribe to mailing list:
-
-    https://launchpad.net/~salt-formulas-users
-
-Developers wishing to work on the salt-formulas projects should always base
-their work on master branch and submit pull request against specific formula.
-
-    https://github.com/salt-formulas/salt-formula-kubernetes
-
-Any questions or feedback is always welcome so feel free to join our IRC
-channel:
-
-    #salt-formulas @ irc.freenode.net
diff --git a/debian/control b/debian/control
index 4552eeb..1a1f570 100644
--- a/debian/control
+++ b/debian/control
@@ -1,5 +1,5 @@
 Source: salt-formula-kubernetes
-Maintainer: PKG OpenStack <openstack-devel@lists.alioth.debian.org>
+Maintainer: Mirantis Dev <dev@mirantis.com>
 Uploaders: Filip Pytloun <filip@pytloun.cz>,
            Ondřej Nový <onovy@debian.org>,
 Section: admin
@@ -9,7 +9,7 @@
 Build-Depends-Indep: python-all,
                      python-yaml,
 Standards-Version: 3.9.6
-Homepage: https://wiki.openstack.org/wiki/OpenStackSalt
+Homepage: https://www.mirantis.com
 Vcs-Browser: https://anonscm.debian.org/cgit/openstack/salt-formula-kubernetes.git/
 Vcs-Git: https://anonscm.debian.org/git/openstack/salt-formula-kubernetes.git
 
diff --git a/debian/copyright b/debian/copyright
index f0a544a..3cf1e55 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -3,15 +3,7 @@
 Source: https://github.com/openstack/salt-formula-kubernetes
 
 Files: *
-Copyright: (c) 2016 tcp cloud a.s.
-           (c) 2016 OpenStack Foundation
-License: Apache-2.0
-
-Files: debian/*
-Copyright: (c) 2016, Filip Pytloun <filip@pytloun.cz>
-           (c) 2016, Ondřej Nový <onovy@debian.org>
-License: Apache-2.0
-
+Copyright: 2014-2019 Mirantis Inc. et al
 License: Apache-2.0
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
diff --git a/kubernetes/_common.sls b/kubernetes/_common.sls
index 6827f11..88a9fcd 100644
--- a/kubernetes/_common.sls
+++ b/kubernetes/_common.sls
@@ -192,7 +192,7 @@
   file.absent
 
 {%- if common.get('cloudprovider', {}).get('enabled') and common.get('cloudprovider', {}).get('provider') == 'openstack' %}
-/etc/kubernetes/cloud-config.conf:
+/etc/kubernetes/cloud-config:
   file.managed:
   - source: salt://kubernetes/files/cloudprovider/cloud-config-openstack.conf
   - template: jinja
@@ -259,6 +259,11 @@
     - file: /usr/bin/hyperkube
     - file: /etc/kubernetes/kubelet.kubeconfig
     - file: manifest_dir_create
+    {%- if common.get('cloudprovider', {}).get('enabled') %}
+    {%- if common.get('cloudprovider', {}).get('provider') == 'openstack' and not pillar.get('kubernetes', {}).get('master', false) %}
+    - file: /etc/kubernetes/cloud-config
+    {%- endif %}
+    {%- endif %}
   {%- if grains.get('noservices') %}
   - onlyif: /bin/false
   {%- endif %}
diff --git a/kubernetes/files/cloudprovider/cloud-config-openstack.conf b/kubernetes/files/cloudprovider/cloud-config-openstack.conf
index 48d09e6..92a1cdd 100644
--- a/kubernetes/files/cloudprovider/cloud-config-openstack.conf
+++ b/kubernetes/files/cloudprovider/cloud-config-openstack.conf
@@ -3,13 +3,16 @@
 auth-url={{ common.cloudprovider.params.auth_url }}
 username={{ common.cloudprovider.params.username }}
 password={{ common.cloudprovider.params.password }}
-region={{ common.cloudprovider.params.region }}
-{%- if common.cloudprovider.params.tenant_id is defined %}
 tenant-id={{ common.cloudprovider.params.tenant_id }}
+{%- if common.cloudprovider.params.region is defined %}
+region={{ common.cloudprovider.params.region }}
 {%- endif %}
 {%- if common.cloudprovider.params.tenant_name is defined %}
 tenant-name={{ common.cloudprovider.params.tenant_name }}
 {%- endif %}
+{%- if common.cloudprovider.params.trust_id is defined %}
+trust-id={{ common.cloudprovider.params.trust_id }}
+{%- endif %}
 {%- if common.cloudprovider.params.domain_id is defined %}
 domain-id={{ common.cloudprovider.params.domain_id }}
 {%- endif %}
@@ -19,8 +22,27 @@
 
 
 [LoadBalancer]
+{%- if common.cloudprovider.params.subnet_id is defined %}
+use-octavia=true
 subnet-id={{ common.cloudprovider.params.subnet_id }}
+{%- endif %}
+{%- if common.cloudprovider.params.lb_method is defined %}
+lb-method={{ common.cloudprovider.params.lb_method }}
+{%- endif %}
 {%- if common.cloudprovider.params.floating_network_id is defined %}
 floating-network-id={{ common.cloudprovider.params.floating_network_id }}
 {%- endif %}
-lb-version=v2
+{%- if common.cloudprovider.params.create_monitor is defined %}
+create-monitor={{ common.cloudprovider.params.create_monitor }}
+monitor-delay={{ common.cloudprovider.params.monitor_delay }}
+monitor-timeout={{ common.cloudprovider.params.monitor_timeout }}
+monitor-max-retries={{ common.cloudprovider.params.monitor_max_retries }}
+{%- endif %}
+{%- if common.cloudprovider.params.manage_security_groups is defined %}
+manage-security-groups={{ common.cloudprovider.params.manage_security_groups }}
+node-security-group={{ common.cloudprovider.params.node_security_group }}
+{%- endif %}
+
+
+[BlockStorage]
+ignore-volume-az=true
diff --git a/kubernetes/files/dockershim/default.master b/kubernetes/files/dockershim/default.master
index f224475..6ce580e 100644
--- a/kubernetes/files/dockershim/default.master
+++ b/kubernetes/files/dockershim/default.master
@@ -11,7 +11,11 @@
 --cluster_dns={{ common.addons.dns.server }} \
 --cluster_domain={{ common.addons.dns.domain|replace('_', '-') }} \
 --cni-bin-dir={{ master.apiserver.get('cni_bin_dir', '/opt/cni/bin') }} \
+{%- if common.get('cloudprovider', {}).get('enabled') and common.get('cloudprovider', {}).get('provider') == 'openstack' %}
+--hostname-override={{ master.host.name }}.{{ common.cluster_domain }} \
+{%- else %}
 --hostname-override={{ master.host.name }} \
+{%- endif %}
 --v={{ master.get('verbosity', 2) }} \
 --node-labels=node-role.kubernetes.io/master=true \
 {%- if common.hyperkube.pause_image is defined %}
@@ -21,10 +25,7 @@
 --register-with-taints=node-role.kubernetes.io/master=:NoSchedule \
 {%- endif %}
 {%- if common.get('cloudprovider', {}).get('enabled') %}
---cloud-provider={{ common.cloudprovider.provider }} \
-{%- if common.get('cloudprovider', {}).get('provider') == 'openstack' %}
---cloud-config=/etc/kubernetes/cloud-config.conf \
-{%- endif %}
+--cloud-provider=external \
 {%- endif %}
 {%- for key, value in master.get('kubelet', {}).get('daemon_opts', {}).items() %}
 --{{ key }}={{ value }} \
diff --git a/kubernetes/files/dockershim/default.pool b/kubernetes/files/dockershim/default.pool
index 1cbbbd7..5c47d35 100644
--- a/kubernetes/files/dockershim/default.pool
+++ b/kubernetes/files/dockershim/default.pool
@@ -11,7 +11,11 @@
 --allow-privileged={{ pool.kubelet.allow_privileged }} \
 --cluster_dns={{ common.addons.dns.server }} \
 --cluster_domain={{ common.addons.dns.domain|replace('_', '-') }} \
+{%- if common.get('cloudprovider', {}).get('enabled') and common.get('cloudprovider', {}).get('provider') == 'openstack' %}
+--hostname-override={{ pool.host.name }}.{{ common.cluster_domain }} \
+{%- else %}
 --hostname-override={{ pool.host.name }} \
+{%- endif %}
 --v={{ pool.get('verbosity', 2) }} \
 {%- if common.hyperkube.pause_image is defined %}
 --pod-infra-container-image={{ common.hyperkube.pause_image }} \
@@ -28,9 +32,9 @@
 --cni-bin-dir={{ pool.apiserver.get('cni_bin_dir', '/opt/cni/bin') }} \
 --file-check-frequency={{ pool.kubelet.frequency }} \
 {%- if common.get('cloudprovider', {}).get('enabled') %}
---cloud-provider={{ common.cloudprovider.provider }} \
+--cloud-provider=external \
 {%- if common.get('cloudprovider', {}).get('provider') == 'openstack' %}
---cloud-config=/etc/kubernetes/cloud-config.conf \
+--cloud-config=/etc/kubernetes/cloud-config \
 {%- endif %}
 {%- endif %}
 --enable-controller-attach-detach={{ pool.get('enable-controller-attach-detach', 'false') }} \
diff --git a/kubernetes/files/kube-addon-manager/kube-addons.sh b/kubernetes/files/kube-addon-manager/kube-addons.sh
index 8aefacc..e09ab22 100644
--- a/kubernetes/files/kube-addon-manager/kube-addons.sh
+++ b/kubernetes/files/kube-addon-manager/kube-addons.sh
@@ -53,6 +53,7 @@
   extensions/v1beta1/ReplicaSet
   apps/v1beta1/StatefulSet
   apps/v1beta1/Deployment
+  storage.k8s.io/v1/StorageClass
 )
 
 ADDON_CHECK_INTERVAL_SEC=${TEST_ADDON_CHECK_INTERVAL_SEC:-60}
diff --git a/kubernetes/files/kube-addons/contrail/contrail.yaml b/kubernetes/files/kube-addons/contrail/contrail.yaml
index ac7bcf1..a3a263b 100644
--- a/kubernetes/files/kube-addons/contrail/contrail.yaml
+++ b/kubernetes/files/kube-addons/contrail/contrail.yaml
@@ -1,4 +1,5 @@
 {%- from "kubernetes/map.jinja" import common with context -%}
+{%- from "kubernetes/map.jinja" import master with context -%}
 ---
 
 apiVersion: apps/v1beta2
@@ -46,6 +47,10 @@
         env:
         - name: RABBITMQ_ERLANG_COOKIE
           value: {{ common.addons.get('contrail',{}).get('rabbitmq_erlang_cookie',"YTQMGYEHFATZPDKPOCXX") }}
+        - name: RABBITMQ_DEFAULT_USER
+          value: {{ master.network.get('opencontrail',{}).get('message_queue',{}).get('user',"guest") }}
+        - name: RABBITMQ_DEFAULT_PASS
+          value: {{ master.network.get('opencontrail',{}).get('message_queue',{}).get('password',"guest") }}
 
       - name: opencontrail-controller
         image: {{ common.addons.opencontrail.controller.image }}
diff --git a/kubernetes/files/kube-addons/coredns/coredns-cm.yml b/kubernetes/files/kube-addons/coredns/coredns-cm.yml
index c9ce8a5..e4e85c7 100644
--- a/kubernetes/files/kube-addons/coredns/coredns-cm.yml
+++ b/kubernetes/files/kube-addons/coredns/coredns-cm.yml
@@ -24,7 +24,7 @@
           pods insecure
           upstream
 {%- if common.addons.externaldns.enabled and common.addons.externaldns.domain == common.addons.coredns.domain %}
-          fallthrough {{ common.addons.coredns.domain }} in-addr.arpa ip6.arpa
+          fallthrough {{ common.addons.coredns.domain|replace('_', '-') }} in-addr.arpa ip6.arpa
 {%- else %}
           fallthrough in-addr.arpa ip6.arpa
 {%- endif %}
@@ -37,7 +37,7 @@
         }
 {%- endif %}
 {%- if common.addons.externaldns.enabled %}
-        etcd {{ common.addons.externaldns.domain }} {
+        etcd {{ common.addons.externaldns.domain|replace('_', '-') }} {
           stubzones
           path /skydns
           endpoint http://{{ common.addons.coredns.etcd.client_address }}:2379
diff --git a/kubernetes/files/kube-addons/externaldns/externaldns-deploy.yml b/kubernetes/files/kube-addons/externaldns/externaldns-deploy.yml
index b01b163..4eb1467 100644
--- a/kubernetes/files/kube-addons/externaldns/externaldns-deploy.yml
+++ b/kubernetes/files/kube-addons/externaldns/externaldns-deploy.yml
@@ -34,7 +34,7 @@
         args:
         - --source=service
         - --source=ingress
-        - --domain-filter={{ common.addons.externaldns.domain }} # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
+        - --domain-filter={{ common.addons.externaldns.domain|replace('_', '-') }} # will make ExternalDNS see only the hosted zones matching provided domain, omit to process all available hosted zones
         - --provider={{ common.addons.externaldns.provider }}
         {%- if common.addons.externaldns.provider == "google" %}
         - --google-project={{ common.addons.externaldns.google_options.project }}
diff --git a/kubernetes/files/kube-addons/openstack-cloud-provider/openstack-cloud-provider.yaml b/kubernetes/files/kube-addons/openstack-cloud-provider/openstack-cloud-provider.yaml
new file mode 100644
index 0000000..59a9755
--- /dev/null
+++ b/kubernetes/files/kube-addons/openstack-cloud-provider/openstack-cloud-provider.yaml
@@ -0,0 +1,41 @@
+---
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1
+metadata:
+  name: openstack-cloud-controller-manager
+  labels:
+    addonmanager.kubernetes.io/mode: Reconcile
+subjects:
+- kind: User
+  name: system:kube-controller-manager
+  apiGroup: rbac.authorization.k8s.io
+roleRef:
+  kind: ClusterRole
+  name: cluster-admin
+  apiGroup: rbac.authorization.k8s.io
+
+---
+kind: InitializerConfiguration
+apiVersion: admissionregistration.k8s.io/v1alpha1
+metadata:
+  name: pvlabel.kubernetes.io
+  labels:
+    addonmanager.kubernetes.io/mode: Reconcile
+initializers:
+  - name: pvlabel.kubernetes.io
+    rules:
+    - apiGroups:
+      - ""
+      apiVersions:
+      - "*"
+      resources:
+      - persistentvolumes
+
+---
+kind: StorageClass
+apiVersion: storage.k8s.io/v1
+metadata:
+  name: cinder
+  labels:
+    addonmanager.kubernetes.io/mode: Reconcile
+provisioner: kubernetes.io/cinder
diff --git a/kubernetes/files/kubeconfig.sh b/kubernetes/files/kubeconfig.sh
index cfdc79b..a88aa93 100644
--- a/kubernetes/files/kubeconfig.sh
+++ b/kubernetes/files/kubeconfig.sh
@@ -5,8 +5,13 @@
 server="$(awk '/server/ { print $2 }' /etc/kubernetes/kubelet.kubeconfig)"
 
 # certificates
+{%- if common.get('cloudprovider', {}).get('enabled') and common.get('cloudprovider', {}).get('provider') == 'openstack' %}
 cert="$(base64 --wrap=0 /etc/kubernetes/ssl/kubelet-client.crt)"
 key="$(base64 --wrap=0 /etc/kubernetes/ssl/kubelet-client.key)"
+{%- else %}
+cert="$(base64 --wrap=0 /etc/kubernetes/ssl/kubelet-client-fqdn.crt)"
+key="$(base64 --wrap=0 /etc/kubernetes/ssl/kubelet-client-fqdn.key)"
+{%- endif %}
 ca="$(base64 --wrap=0 /etc/kubernetes/ssl/ca-kubernetes.crt )"
 cluster="{{ common.cluster_name }}"
 
diff --git a/kubernetes/files/kubelet/default.master b/kubernetes/files/kubelet/default.master
index 3cdb8bf..5436140 100644
--- a/kubernetes/files/kubelet/default.master
+++ b/kubernetes/files/kubelet/default.master
@@ -25,7 +25,11 @@
 --allow-privileged={{ master.kubelet.allow_privileged }} \
 --cluster_dns={{ common.addons.dns.server }} \
 --cluster_domain={{ common.addons.dns.domain|replace('_', '-') }} \
+{%- if common.get('cloudprovider', {}).get('enabled') and common.get('cloudprovider', {}).get('provider') == 'openstack' %}
+--hostname-override={{ master.host.name }}.{{ common.cluster_domain }} \
+{%- else %}
 --hostname-override={{ master.host.name }} \
+{%- endif %}
 --v={{ master.get('verbosity', 2) }} \
 --node-labels=node-role.kubernetes.io/master=true \
 {%- if common.hyperkube.pause_image is defined %}
@@ -45,10 +49,7 @@
 --register-with-taints=node-role.kubernetes.io/master=:NoSchedule \
 {%- endif %}
 {%- if common.get('cloudprovider', {}).get('enabled') %}
---cloud-provider={{ common.cloudprovider.provider }} \
-{%- if common.get('cloudprovider', {}).get('provider') == 'openstack' %}
---cloud-config=/etc/kubernetes/cloud-config.conf \
-{%- endif %}
+--cloud-provider=external \
 {%- endif %}
 {%- if common.get('containerd', {}).get('enabled') %}
 --container-runtime={{ master.get('container-runtime', 'remote') }} \
diff --git a/kubernetes/files/kubelet/default.pool b/kubernetes/files/kubelet/default.pool
index ee1a5a9..0774eee 100644
--- a/kubernetes/files/kubelet/default.pool
+++ b/kubernetes/files/kubelet/default.pool
@@ -25,7 +25,11 @@
 --allow-privileged={{ pool.kubelet.allow_privileged }} \
 --cluster_dns={{ common.addons.dns.server }} \
 --cluster_domain={{ common.addons.dns.domain|replace('_', '-') }} \
+{%- if common.get('cloudprovider', {}).get('enabled') and common.get('cloudprovider', {}).get('provider') == 'openstack' %}
+--hostname-override={{ pool.host.name }}.{{ common.cluster_domain }} \
+{%- else %}
 --hostname-override={{ pool.host.name }} \
+{%- endif %}
 --v={{ pool.get('verbosity', 2) }} \
 {%- if common.hyperkube.pause_image is defined %}
 --pod-infra-container-image={{ common.hyperkube.pause_image }} \
@@ -51,9 +55,9 @@
 {%- endif %}
 --file-check-frequency={{ pool.kubelet.frequency }} \
 {%- if common.get('cloudprovider', {}).get('enabled') %}
---cloud-provider={{ common.cloudprovider.provider }} \
+--cloud-provider=external \
 {%- if common.get('cloudprovider', {}).get('provider') == 'openstack' %}
---cloud-config=/etc/kubernetes/cloud-config.conf \
+--cloud-config=/etc/kubernetes/cloud-config \
 {%- endif %}
 {%- endif %}
 {%- if common.addons.get('virtlet', {}).get('enabled') %}
diff --git a/kubernetes/files/kubelet/kubelet.kubeconfig.master b/kubernetes/files/kubelet/kubelet.kubeconfig.master
index 3c70ded..810a129 100644
--- a/kubernetes/files/kubelet/kubelet.kubeconfig.master
+++ b/kubernetes/files/kubelet/kubelet.kubeconfig.master
@@ -17,5 +17,10 @@
 users:
 - name: kubelet-{{ common.cluster_name }}
   user:
+{%- if common.get('cloudprovider', {}).get('enabled') and common.get('cloudprovider', {}).get('provider') == 'openstack' %}
+    client-certificate: /etc/kubernetes/ssl/kubelet-client-fqdn.crt
+    client-key: /etc/kubernetes/ssl/kubelet-client-fqdn.key
+{%- else %}
     client-certificate: /etc/kubernetes/ssl/kubelet-client.crt
     client-key: /etc/kubernetes/ssl/kubelet-client.key
+{%- endif %}
diff --git a/kubernetes/files/kubelet/kubelet.kubeconfig.pool b/kubernetes/files/kubelet/kubelet.kubeconfig.pool
index 3228ea6..927d419 100644
--- a/kubernetes/files/kubelet/kubelet.kubeconfig.pool
+++ b/kubernetes/files/kubelet/kubelet.kubeconfig.pool
@@ -17,5 +17,10 @@
 users:
 - name: kubelet-{{ common.cluster_name }}
   user:
+{%- if common.get('cloudprovider', {}).get('enabled') and common.get('cloudprovider', {}).get('provider') == 'openstack' %}
+    client-certificate: /etc/kubernetes/ssl/kubelet-client-fqdn.crt
+    client-key: /etc/kubernetes/ssl/kubelet-client-fqdn.key
+{%- else %}
     client-certificate: /etc/kubernetes/ssl/kubelet-client.crt
     client-key: /etc/kubernetes/ssl/kubelet-client.key
+{%- endif %}
diff --git a/kubernetes/files/systemd/openstack-cloud-controller-manager.service b/kubernetes/files/systemd/openstack-cloud-controller-manager.service
new file mode 100644
index 0000000..98b54db
--- /dev/null
+++ b/kubernetes/files/systemd/openstack-cloud-controller-manager.service
@@ -0,0 +1,20 @@
+[Unit]
+Description=OpenStack Cloud Controller Manager
+Documentation=https://github.com/kubernetes/cloud-provider-openstack
+Documentation=man:openstack-cloud-controller-manager
+After=network.target
+
+[Service]
+SyslogIdentifier=openstack-cloud-controller-manager
+EnvironmentFile=-/etc/kubernetes/config
+EnvironmentFile=-/etc/default/%p
+User=root
+ExecStart=/usr/bin/openstack-cloud-controller-manager \
+    $KUBE_LOGTOSTDERR \
+    $KUBE_LOG_LEVEL \
+        $DAEMON_ARGS
+Restart=on-failure
+LimitNOFILE=65536
+
+[Install]
+WantedBy=multi-user.target
diff --git a/kubernetes/master/controller.sls b/kubernetes/master/controller.sls
index 83f752d..54bcf34 100644
--- a/kubernetes/master/controller.sls
+++ b/kubernetes/master/controller.sls
@@ -88,6 +88,42 @@
 
 {%- else %}
 
+
+{%- if common.get('cloudprovider', {}).get('enabled') %}
+{%- if common.get('cloudprovider', {}).get('provider') == 'openstack' %}
+/usr/bin/openstack-cloud-controller-manager:
+  file.managed:
+    - source: {{ common.cloudprovider.params.binary }}
+    - mode: 751
+    - makedirs: true
+    - user: root
+    - group: root
+    - source_hash: {{ common.cloudprovider.params.binary_hash }}
+
+/etc/default/openstack-cloud-controller-manager:
+  file.managed:
+    - user: root
+    - group: root
+    - mode: 644
+    - contents: >-
+        DAEMON_ARGS="
+        --cloud-provider=openstack
+        --cloud-config /etc/kubernetes/cloud-config
+        --cluster-name=kubernetes
+        --kubeconfig /etc/kubernetes/controller-manager.kubeconfig
+        --leader-elect=true
+        --v={{ master.get('verbosity', 2) }}"
+
+/etc/systemd/system/openstack-cloud-controller-manager.service:
+  file.managed:
+  - source: salt://kubernetes/files/systemd/openstack-cloud-controller-manager.service
+  - template: jinja
+  - user: root
+  - group: root
+  - mode: 644
+{%- endif %}
+{%- endif %}
+
 /etc/default/kube-apiserver:
   file.managed:
     - user: root
@@ -97,7 +133,15 @@
         # Using hyperkube version v{{ full_version }}
 
         DAEMON_ARGS="
-        --admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,DefaultStorageClass
+        {%- if common.get('cloudprovider', {}).get('enabled') %}
+        {%- if common.get('cloudprovider', {}).get('provider') == 'openstack' %}
+        --runtime-config=admissionregistration.k8s.io/v1alpha1
+        --enable-admission-plugins=Initializers,NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,DefaultStorageClass
+        --disable-admission-plugins=PersistentVolumeLabel
+        {%- endif %}
+        {%- else %}
+        --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,DefaultStorageClass
+        {%- endif %}
         --allow-privileged=True
         {%- if master.auth.get('mode') %}
         --authorization-mode={{ master.auth.mode }}
@@ -140,12 +184,6 @@
 {%- if master.apiserver.node_port_range is defined %}
         --service-node-port-range {{ master.apiserver.node_port_range }}
 {%- endif %}
-{%- if common.get('cloudprovider', {}).get('enabled') %}
-        --cloud-provider={{ common.cloudprovider.provider }}
-{%- if common.get('cloudprovider', {}).get('provider') == 'openstack' %}
-        --cloud-config=/etc/kubernetes/cloud-config.conf
-{%- endif %}
-{%- endif %}
 {%- if common.addons.get('virtlet', {}).get('enabled') %}
 {%- if salt['pkg.version_cmp'](version,'1.8') >= 0 %}
         --feature-gates=MountPropagation=true
@@ -191,12 +229,6 @@
         --root-ca-file=/etc/kubernetes/ssl/ca-{{ master.ca }}.crt
         --service-account-private-key-file=/etc/kubernetes/ssl/kubernetes-server.key
         --use-service-account-credentials
-{%- if common.get('cloudprovider', {}).get('enabled') %}
-        --cloud-provider={{ common.cloudprovider.provider }}
-{%- if common.get('cloudprovider', {}).get('provider') == 'openstack' %}
-        --cloud-config=/etc/kubernetes/cloud-config.conf
-{%- endif %}
-{%- endif %}
         --v={{ master.get('verbosity', 2) }}
 {%- if master.network.get('flannel', {}).get('enabled', False) %}
         --allocate-node-cidrs=true
@@ -273,6 +305,19 @@
     - file: /etc/default/kube-controller-manager
     - file: /usr/bin/hyperkube
 
+{%- if common.get('cloudprovider', {}).get('enabled') %}
+{%- if common.get('cloudprovider', {}).get('provider') == 'openstack' %}
+openstack_cloud_controller_service:
+  service.running:
+  - name: openstack-cloud-controller-manager
+  - enable: True
+  - watch:
+    - file: /etc/kubernetes/cloud-config
+    - file: /etc/default/openstack-cloud-controller-manager
+    - file: /etc/kubernetes/controller-manager.kubeconfig
+{%- endif %}
+{%- endif %}
+
 {%- endif %}
 
 
diff --git a/kubernetes/master/kube-addons.sls b/kubernetes/master/kube-addons.sls
index 493576b..2d5dc1b 100644
--- a/kubernetes/master/kube-addons.sls
+++ b/kubernetes/master/kube-addons.sls
@@ -497,4 +497,16 @@
     - makedirs: True
 {% endif %}
 
+{%- if common.get('cloudprovider', {}).get('enabled') %}
+{%- if common.get('cloudprovider', {}).get('provider') == 'openstack' %}
+/etc/kubernetes/addons/openstack-cloud-provider/openstack-cloud-provider.yaml:
+  file.managed:
+    - source: salt://kubernetes/files/kube-addons/openstack-cloud-provider/openstack-cloud-provider.yaml
+    - template: jinja
+    - group: root
+    - dir_mode: 755
+    - makedirs: True
+{% endif %}
+{% endif %}
+
 {% endif %}
diff --git a/kubernetes/meta/collectd.yml b/kubernetes/meta/collectd.yml
index 8237e25..0972dcb 100644
--- a/kubernetes/meta/collectd.yml
+++ b/kubernetes/meta/collectd.yml
@@ -1,4 +1,5 @@
 {%- from "kubernetes/map.jinja" import master with context %}
+{%- from "kubernetes/map.jinja" import common with context -%}
 {%- from "kubernetes/map.jinja" import pool with context %}
 
 {%- if pool.get('enabled', False) %}
@@ -99,8 +100,13 @@
        # alternative names DNS entries.
        # https://github.com/shazow/urllib3/issues/258
        verify: false
+{%- if common.get('cloudprovider', {}).get('enabled') and common.get('cloudprovider', {}).get('provider') == 'openstack' %}
+       client_cert: /etc/kubernetes/ssl/kubelet-client-fqdn.crt
+       client_key: /etc/kubernetes/ssl/kubelet-client-fqdn.key
+{%- else %}
        client_cert: /etc/kubernetes/ssl/kubelet-client.crt
        client_key: /etc/kubernetes/ssl/kubelet-client.key
+{%- endif %}
        url: https://{{ pool.apiserver.host }}:{{ pool.apiserver.secure_port }}/healthz
        metric_name: k8s_service_health_vip
   collectd_k8s_get:
@@ -109,7 +115,12 @@
    polling_interval: 60
    interval: 30
    verify: false
+{%- if common.get('cloudprovider', {}).get('enabled') and common.get('cloudprovider', {}).get('provider') == 'openstack' %}
+   client_cert: /etc/kubernetes/ssl/kubelet-client-fqdn.crt
+   client_key: /etc/kubernetes/ssl/kubelet-client-fqdn.key
+{%- else %}
    client_cert: /etc/kubernetes/ssl/kubelet-client.crt
    client_key: /etc/kubernetes/ssl/kubelet-client.key
+{%- endif %}
    endpoint: https://{{ pool.apiserver.host }}:{{ pool.apiserver.secure_port }}
 {%- endif %}
diff --git a/kubernetes/meta/fluentd.yml b/kubernetes/meta/fluentd.yml
index 9c66b75..3a38245 100644
--- a/kubernetes/meta/fluentd.yml
+++ b/kubernetes/meta/fluentd.yml
@@ -1,3 +1,4 @@
+{%- from "kubernetes/map.jinja" import common with context -%}
 {%- if pillar.get('fluentd', {}).get('agent', {}).get('enabled', False) %}
 {%- from "kubernetes/map.jinja" import pool, master %}
 {%- if pool.get('enabled', False) %}
@@ -79,8 +80,13 @@
             tag: 'temp.kubernetes.container.**'
             type: kubernetes_metadata
             kubernetes_url: https://{{ pool.apiserver.host }}:{{ pool.apiserver.secure_port }}
+            {%- if common.get('cloudprovider', {}).get('enabled') and common.get('cloudprovider', {}).get('provider') == 'openstack' %}
+            client_cert: /etc/kubernetes/ssl/kubelet-client-fqdn.crt
+            client_key: /etc/kubernetes/ssl/kubelet-client-fqdn.key
+            {%- else %}
             client_cert: /etc/kubernetes/ssl/kubelet-client.crt
             client_key: /etc/kubernetes/ssl/kubelet-client.key
+            {%- endif %}
             ca_file: /etc/kubernetes/ssl/ca-kubernetes.crt
             verify_ssl: True
           enrich_container:
diff --git a/kubernetes/meta/prometheus.yml b/kubernetes/meta/prometheus.yml
index 0715367..6a19156 100644
--- a/kubernetes/meta/prometheus.yml
+++ b/kubernetes/meta/prometheus.yml
@@ -9,14 +9,20 @@
   {%- set network = master.get('network', {}) %}
 {%- endif %}
 
-
 {%- set apiServerPoint = {} %}
 {%- if pool.get('enabled', False) %}
   {%- set apiServerPoint = pool.get('apiserver', {}).get('host') %}
+  {%- if network.get('calico', {}).get('enabled', False) and network.calico.get('prometheus', {}).get('enabled', False) %}
+    {%- set calico_address = network.calico.prometheus.get('address', pool.address) %}
+  {%- endif %}
 {%- elif master.get('enabled', False) %}
   {%- set apiServerPoint = master.get('apiserver', {}).get('address') %}
+  {%- if network.get('calico', {}).get('enabled', False) and network.calico.get('prometheus', {}).get('enabled', False) %}
+    {%- set calico_address = network.calico.prometheus.get('address', master.address) %}
+  {%- endif %}
 {%- endif %}
 
+
 server:
   target:
     kubernetes:
@@ -24,16 +30,17 @@
       api_ip: {{ apiServerPoint }}
       cert_name: prometheus-server.crt
       key_name: prometheus-server.key
-{%- if network.get('calico', {}).get('enabled', False) and network.calico.get('prometheus', {}).get('enabled', False) %}
+{%- if calico_address is defined %}
     static:
       calico:
         endpoint:
-  {%- if pool.get('enabled', False) %}
-          - address: {{ network.calico.prometheus.get('address', pool.address) }}
-  {%- else %}
-          - address: {{ network.calico.prometheus.get('address', master.address) }}
-  {%- endif %}
+          - address: {{ calico_address }}
             port: {{ network.calico.prometheus.get('port', 9091) }}
+        relabel_configs:
+          - regex: {{ calico_address }}:{{ network.calico.prometheus.get('port', 9091) }}
+            replacement: {{ grains['host'] }}
+            source_labels: "__address__"
+            target_label: "host"
 {%- endif %}
   recording:
     cluster_namespace_controller_pod_container:spec_memory_limit_bytes:
diff --git a/metadata/service/common.yml b/metadata/service/common.yml
index d44b098..aabc8a4 100644
--- a/metadata/service/common.yml
+++ b/metadata/service/common.yml
@@ -140,6 +140,6 @@
         provider: openstack
         params:
           region: RegionOne
-          domain_name: default
+          domain_id: default
       cluster_domain: ${_param:kubernetes_cluster_domain}
       cluster_name: ${_param:cluster_name}