Add support for openstack cloudprovider

Change-Id: I3e48afdedb90264f2354c818b20f0b4a0fe4b9d1
diff --git a/README.rst b/README.rst
index 0ec06d2..de35b08 100644
--- a/README.rst
+++ b/README.rst
@@ -126,6 +126,26 @@
                 domain: company.mydomain
                 provider: coredns
 
+Enable OpenStack cloud provider
+
+.. code-block:: yaml
+
+    parameters:
+      kubernetes:
+        common:
+          cloudprovider:
+            enabled: True
+            type: openstack
+            params:
+              auth_url: https://openstack.mydomain:5000/v3
+              username: nova
+              password: nova
+              region: RegionOne
+              tenant_id: 4bce4162d8744c599e350099cfa22a0a
+              domain_name: default
+              subnet_id: 72407854-aca6-4cf1-b873-e9affb09484b
+              lb_version: v2
+
 Configure service verbosity
 
 .. code-block:: yaml
diff --git a/kubernetes/_common.sls b/kubernetes/_common.sls
index 39a17dc..5e6576a 100644
--- a/kubernetes/_common.sls
+++ b/kubernetes/_common.sls
@@ -131,6 +131,17 @@
 /etc/kubernetes/config:
   file.absent
 
+{%- if common.get('cloudprovider', {}).get('enabled') and common.get('cloudprovider', {}).get('provider') == "openstack" %}
+/etc/kubernetes/cloud-config.conf:
+  file.managed:
+  - source: salt://kubernetes/files/cloudprovider/cloud-config.conf
+  - template: jinja
+  - user: root
+  - group: root
+  - mode: 600
+
+{% endif %}
+
 {%- if not pillar.kubernetes.pool is defined %}
 
 /etc/default/kubelet:
diff --git a/kubernetes/files/cloudprovider/cloud-config-openstack.conf b/kubernetes/files/cloudprovider/cloud-config-openstack.conf
new file mode 100644
index 0000000..0121a2b
--- /dev/null
+++ b/kubernetes/files/cloudprovider/cloud-config-openstack.conf
@@ -0,0 +1,25 @@
+{%- from "kubernetes/map.jinja" import common with context -%}
+[Global]
+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 %}
+{%- endif %}
+{%- if {{ common.cloudprovider.params.tenant_name is defined %}
+tenant-name={{ common.cloudprovider.params.tenant_name %}
+{%- endif %}
+{%- if {{ common.cloudprovider.params.domain_id is defined %}
+domain-id={{ common.cloudprovider.params.domain_id %}
+{%- endif %}
+{%- if {{ common.cloudprovider.params.tenant_name is defined %}
+domain-name={{ common.cloudprovider.params.domain_name %}
+{%- endif %}
+
+
+[LoadBalancer]
+subnet-id={{ common.cloudprovider.params.subnet_id }
+{%- if {{ common.cloudprovider.params.floating_network_id is defined %}
+floating-network-id={{ common.cloudprovider.params.floating_network_id }}
+lb-version=v2
diff --git a/kubernetes/files/kubelet/default.master b/kubernetes/files/kubelet/default.master
index 60d182f..b45dfa1 100644
--- a/kubernetes/files/kubelet/default.master
+++ b/kubernetes/files/kubelet/default.master
@@ -11,6 +11,12 @@
 --hostname-override={{ master.host.name }} \
 --v={{ master.get('verbosity', 2) }} \
 --node-labels=node-role.kubernetes.io/master=true \
+{%- 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 %}
 {%- for key, value in master.get('kubelet', {}).get('daemon_opts', {}).iteritems() %}
 --{{ key }}={{ value }} \
 {%- endfor %}
diff --git a/kubernetes/files/kubelet/default.pool b/kubernetes/files/kubelet/default.pool
index 2db32f8..2be3ed3 100644
--- a/kubernetes/files/kubelet/default.pool
+++ b/kubernetes/files/kubelet/default.pool
@@ -18,6 +18,12 @@
 --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 }} \
+{%- if common.get('cloudprovider', {}).get('provider') == "openstack" %}
+        --cloud-config=/etc/kubernetes/cloud-config.conf \
+{%- endif %}
+{%- endif %}
 {%- if common.addons.get('virtlet', {}).get('enabled') %}
 --container-runtime={{ pool.get('container-runtime', 'remote') }} \
 --container-runtime-endpoint={{ pool.get('container-runtime-endpoint', '/var/run/criproxy.sock') }} \
diff --git a/kubernetes/files/virtlet/kubelet.conf b/kubernetes/files/virtlet/kubelet.conf
index f8cf16d..189c559 100644
--- a/kubernetes/files/virtlet/kubelet.conf
+++ b/kubernetes/files/virtlet/kubelet.conf
@@ -27,8 +27,15 @@
     "cgroupDriver": "cgroupfs",
     "cgroupRoot": "",
     "cgroupsPerQOS": true,
-    "cloudConfigFile": "",
+{%- if common.get('cloudprovider', {}).get('enabled') %}
+    "cloudProvider": "{{ common.cloudprovider.provider }}"
+{%- if common.get('cloudprovider', {}).get('provider') == "openstack" %}
+    "cloudConfigFile": "/etc/kubernetes/cloud-config.conf",
+{%- endif %}
+{%- else %}
     "cloudProvider": "auto-detect",
+{%- endif %}
+
     "clusterDNS": [
         "10.254.0.10"
     ],
diff --git a/kubernetes/master/controller.sls b/kubernetes/master/controller.sls
index d57434e..b6ff495 100644
--- a/kubernetes/master/controller.sls
+++ b/kubernetes/master/controller.sls
@@ -103,10 +103,16 @@
         --etcd-certfile /var/lib/etcd/etcd-client.crt
         --etcd-keyfile /var/lib/etcd/etcd-client.key
 {%- endif %}
-{%- if master.apiserver.node_port_range is defined %} 
+{%- if master.apiserver.node_port_range is defined %}
         --service-node-port-range {{ master.apiserver.node_port_range }}
 {%- endif %}
-{%- for key, value in master.get('apiserver', {}).get('daemon_opts', {}).iteritems() %} 
+{%- 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 %}
+{%- for key, value in master.get('apiserver', {}).get('daemon_opts', {}).iteritems() %}
         --{{ key }}={{ value }}
 {%- endfor %}"
 
@@ -137,6 +143,12 @@
         --leader-elect=true
         --root-ca-file=/etc/kubernetes/ssl/ca-{{ master.ca }}.crt
         --service-account-private-key-file=/etc/kubernetes/ssl/kubernetes-server.key
+{%- 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) }}
 {%- for key, value in master.get('controller_manager', {}).get('daemon_opts', {}).iteritems() %}
         --{{ key }}={{ value }}
diff --git a/metadata/service/common.yml b/metadata/service/common.yml
index 3faf65f..b7884b4 100644
--- a/metadata/service/common.yml
+++ b/metadata/service/common.yml
@@ -56,6 +56,12 @@
           enabled: False
           namespace: kube-system
           image: mirantis/virtlet:v0.7.0
+      cloudprovider:
+        enabled: False
+        provider: openstack
+        params:
+          region: RegionOne
+          domain_name: default
       cluster_domain: ${_param:kubernetes_cluster_domain}
       cluster_name: ${_param:cluster_name}
       network: