From 65dfb2009feb298d131a52e10c29c36c0eb668bd Mon Sep 17 00:00:00 2001 From: Spyros Trigazis Date: Tue, 5 Dec 2017 15:19:01 +0000 Subject: [PATCH] Add openstack_ca_file configuration option In the drivers section of magnum.conf add openstack_ca_file. This file is expected to be a CA Certificate OR CA bundle which will be passed on every node and it will be installed on the host's CA bundle. Update devstack plugin to use the ssl bundle if tls-proxy is enabled. Install the CA for drivers: k8s_coreos_v1 k8s_fedora_atomic_v1 k8s_fedora_ironic_v1 mesos_ubuntu_v1 swarm_fedora_atomic_v1 swarm_fedora_atomic_v2 Add doc in troubleshooting-guide. Add release notes. Closes-Bug: #1580704 Partially-Implements: blueprint heat-agent Change-Id: Id48fbea187da667a5e7334694c3ec17c8e2504db --- devstack/lib/magnum | 3 ++ doc/source/admin/troubleshooting-guide.rst | 18 +++++++++++ magnum/common/utils.py | 10 ++++++ magnum/conf/drivers.py | 6 +++- .../fragments/atomic-install-openstack-ca.sh | 12 +++++++ .../fragments/write-kube-os-config.sh | 2 ++ magnum/drivers/heat/template_def.py | 2 ++ .../templates/fragments/add-ext-ca-certs.yaml | 32 +++++++++++++++++++ .../k8s_coreos_v1/templates/kubecluster.yaml | 7 ++++ .../k8s_coreos_v1/templates/kubemaster.yaml | 18 +++++++++++ .../k8s_coreos_v1/templates/kubeminion.yaml | 18 +++++++++++ .../templates/kubecluster.yaml | 7 ++++ .../templates/kubemaster.yaml | 15 +++++++++ .../templates/kubeminion.yaml | 15 +++++++++ .../templates/kubecluster.yaml | 7 ++++ .../templates/kubemaster.yaml | 15 +++++++++ .../kubeminion_software_configs.yaml | 15 +++++++++ .../templates/fragments/add-ext-ca-certs.sh | 27 ++++++++++++++++ .../mesos_slave_software_configs.yaml | 15 +++++++++ .../templates/mesoscluster.yaml | 7 ++++ .../templates/mesosmaster.yaml | 22 +++++++++++++ .../templates/cluster.yaml | 7 ++++ .../templates/swarmmaster.yaml | 15 +++++++++ .../templates/swarmnode.yaml | 15 +++++++++ .../templates/swarmcluster.yaml | 8 +++++ .../templates/swarmmaster.yaml | 15 +++++++++ .../templates/swarmnode.yaml | 15 +++++++++ magnum/tests/unit/common/test_utils.py | 21 ++++++++++++ .../handlers/test_k8s_cluster_conductor.py | 6 ++++ .../handlers/test_mesos_cluster_conductor.py | 4 +++ .../handlers/test_swarm_cluster_conductor.py | 5 +++ .../notes/bug-1580704-32a0e91e285792ea.yaml | 7 ++++ 32 files changed, 390 insertions(+), 1 deletion(-) create mode 100644 magnum/drivers/common/templates/fragments/atomic-install-openstack-ca.sh create mode 100644 magnum/drivers/k8s_coreos_v1/templates/fragments/add-ext-ca-certs.yaml create mode 100644 magnum/drivers/mesos_ubuntu_v1/templates/fragments/add-ext-ca-certs.sh create mode 100644 releasenotes/notes/bug-1580704-32a0e91e285792ea.yaml diff --git a/devstack/lib/magnum b/devstack/lib/magnum index 3d62b66020..110779ceab 100644 --- a/devstack/lib/magnum +++ b/devstack/lib/magnum @@ -132,8 +132,11 @@ function create_magnum_conf { iniset $MAGNUM_CONF api host "$MAGNUM_SERVICE_HOST" if is_service_enabled tls-proxy; then iniset $MAGNUM_CONF api port "$MAGNUM_SERVICE_PORT_INT" + iniset $MAGNUM_CONF drivers verify_ca true + iniset $MAGNUM_CONF drivers openstack_ca_file $SSL_BUNDLE_FILE else iniset $MAGNUM_CONF api port "$MAGNUM_SERVICE_PORT" + iniset $MAGNUM_CONF drivers verify_ca false fi iniset $MAGNUM_CONF oslo_policy policy_file $MAGNUM_POLICY diff --git a/doc/source/admin/troubleshooting-guide.rst b/doc/source/admin/troubleshooting-guide.rst index 64d28211b0..85c5268271 100644 --- a/doc/source/admin/troubleshooting-guide.rst +++ b/doc/source/admin/troubleshooting-guide.rst @@ -178,6 +178,24 @@ specified). If it fails, that means the credential you provided is invalid. TLS --- +In production deployments, operators run the OpenStack APIs using +ssl certificates and in private clouds it is common to use self-signed +or certificates signed from CAs that they are usually not included +in the systems' default CA-bundles. Magnum clusters with TLS enabled +have their own CA but they need to make requests to the OpenStack +APIs for several reasons. Eg Get the cluster CA and sign node +certificates (Keystone, Magnum), signal the Heat API for stack +completion, create resources (volumes, load balancers) or get +information for each node (Cinder, Neutron, Nova). In these cases, +the cluster nodes need the CA used for to run the APIs. + +To pass the OpenStack CA bundle to the nodes you can set the CA +using the `openstack_ca_file` option in the `drivers` section of +Magnum's configuration file (usually `/etc/magnum/magnum.conf`). +The default drivers in magnum install this CA in the system and +set it in all the places it might be needed (eg when configuring +the kubernetes cloud provider or for the heat-agents.) + The cluster nodes will validate the Certificate Authority by default when making requests to the OpenStack APIs (Keystone, Magnum, Heat). If you need to disable CA validation, the configuration parameter diff --git a/magnum/common/utils.py b/magnum/common/utils.py index 9063eae4d4..2588354dbc 100755 --- a/magnum/common/utils.py +++ b/magnum/common/utils.py @@ -278,3 +278,13 @@ def generate_password(length, symbolgroups=None): r.shuffle(password) return ''.join(password) + + +def get_openstack_ca(): + openstack_ca_file = CONF.drivers.openstack_ca_file + + if openstack_ca_file: + with open(openstack_ca_file) as fd: + return fd.read() + else: + return '' diff --git a/magnum/conf/drivers.py b/magnum/conf/drivers.py index 96eef3fc63..3bb9891b64 100644 --- a/magnum/conf/drivers.py +++ b/magnum/conf/drivers.py @@ -25,7 +25,11 @@ drivers_opts = [ 'you have your own Certificate Authority and you ' 'have not installed the Certificate Authority to all ' 'nodes, you may need to disable CA validation by ' - 'setting this flag to False.') + 'setting this flag to False.'), + cfg.StrOpt('openstack_ca_file', + default="", + help='Path to the OpenStack CA-bundle file to pass and ' + 'install in all cluster nodes.') ] diff --git a/magnum/drivers/common/templates/fragments/atomic-install-openstack-ca.sh b/magnum/drivers/common/templates/fragments/atomic-install-openstack-ca.sh new file mode 100644 index 0000000000..09daf357fe --- /dev/null +++ b/magnum/drivers/common/templates/fragments/atomic-install-openstack-ca.sh @@ -0,0 +1,12 @@ +#!/bin/sh -ux + +CA_FILE=/etc/pki/ca-trust/source/anchors/openstack-ca.pem + +if [ -n "$OPENSTACK_CA" ] ; then + cat >> $CA_FILE < domain name for cluster DNS + openstack_ca: + type: string + description: The OpenStack CA certificate to install on the node. + resources: master_wait_handle: @@ -311,6 +315,16 @@ resources: "$DNS_SERVICE_IP": {get_param: dns_service_ip} "$DNS_CLUSTER_DOMAIN": {get_param: dns_cluster_domain} + add_ext_ca_certs: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: + str_replace: + params: + $OPENSTACK_CA: {get_param: openstack_ca} + template: {get_file: fragments/add-ext-ca-certs.yaml} + configure_etcd: type: OS::Heat::SoftwareConfig properties: @@ -408,6 +422,7 @@ resources: config: str_replace: template: | + $add_ext_ca_certs $write_heat_params $make_cert $configure_docker @@ -426,6 +441,8 @@ resources: $wc_notify coreos: units: + - name: "add-ext-ca-certs.service" + command: "start" - name: "make-cert.service" command: "start" - name: "configure-docker.service" @@ -457,6 +474,7 @@ resources: - name: "wc-notify.service" command: "start" params: + "$add_ext_ca_certs": {get_attr: [add_ext_ca_certs, config]} "$write_heat_params": {get_attr: [write_heat_params, config]} "$make_cert": {get_attr: [make_cert, config]} "$configure_docker": {get_attr: [configure_docker, config]} diff --git a/magnum/drivers/k8s_coreos_v1/templates/kubeminion.yaml b/magnum/drivers/k8s_coreos_v1/templates/kubeminion.yaml index c138756136..26fcbac7f3 100644 --- a/magnum/drivers/k8s_coreos_v1/templates/kubeminion.yaml +++ b/magnum/drivers/k8s_coreos_v1/templates/kubeminion.yaml @@ -156,6 +156,10 @@ parameters: description: > domain name for cluster DNS + openstack_ca: + type: string + description: The OpenStack CA certificate to install on the node. + resources: minion_wait_handle: @@ -215,6 +219,16 @@ resources: "$DNS_SERVICE_IP": {get_param: dns_service_ip} "$DNS_CLUSTER_DOMAIN": {get_param: dns_cluster_domain} + add_ext_ca_certs: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: + str_replace: + params: + $OPENSTACK_CA: {get_param: openstack_ca} + template: {get_file: fragments/add-ext-ca-certs.yaml} + write_kubeconfig: type: OS::Heat::SoftwareConfig properties: @@ -270,6 +284,7 @@ resources: config: str_replace: template: | + $add_ext_ca_certs $write_heat_params $write_kubeconfig $make_cert @@ -281,6 +296,8 @@ resources: $wc_notify coreos: units: + - name: "add-ext-ca-certs.service" + command: "start" - name: "make-cert.service" command: "start" - name: "configure-docker.service" @@ -296,6 +313,7 @@ resources: - name: "wc-notify.service" command: "start" params: + "$add_ext_ca_certs": {get_attr: [add_ext_ca_certs, config]} "$write_heat_params": {get_attr: [write_heat_params, config]} "$write_kubeconfig": {get_attr: [write_kubeconfig, config]} "$make_cert": {get_attr: [make_cert, config]} diff --git a/magnum/drivers/k8s_fedora_atomic_v1/templates/kubecluster.yaml b/magnum/drivers/k8s_fedora_atomic_v1/templates/kubecluster.yaml index a87183b999..6793ecd114 100644 --- a/magnum/drivers/k8s_fedora_atomic_v1/templates/kubecluster.yaml +++ b/magnum/drivers/k8s_fedora_atomic_v1/templates/kubecluster.yaml @@ -351,6 +351,11 @@ parameters: domain name for cluster DNS default: "cluster.local" + openstack_ca: + type: string + hidden: true + description: The OpenStack CA certificate to install on the node. + resources: ###################################################################### @@ -531,6 +536,7 @@ resources: etcd_lb_vip: {get_attr: [etcd_lb, address]} dns_service_ip: {get_param: dns_service_ip} dns_cluster_domain: {get_param: dns_cluster_domain} + openstack_ca: {get_param: openstack_ca} ###################################################################### # @@ -599,6 +605,7 @@ resources: container_infra_prefix: {get_param: container_infra_prefix} dns_service_ip: {get_param: dns_service_ip} dns_cluster_domain: {get_param: dns_cluster_domain} + openstack_ca: {get_param: openstack_ca} outputs: diff --git a/magnum/drivers/k8s_fedora_atomic_v1/templates/kubemaster.yaml b/magnum/drivers/k8s_fedora_atomic_v1/templates/kubemaster.yaml index b1b4a1f69d..2737270a7c 100644 --- a/magnum/drivers/k8s_fedora_atomic_v1/templates/kubemaster.yaml +++ b/magnum/drivers/k8s_fedora_atomic_v1/templates/kubemaster.yaml @@ -259,6 +259,10 @@ parameters: description: > domain name for cluster DNS + openstack_ca: + type: string + description: The OpenStack CA certificate to install on the node. + resources: master_wait_handle: @@ -346,6 +350,16 @@ resources: "$DNS_SERVICE_IP": {get_param: dns_service_ip} "$DNS_CLUSTER_DOMAIN": {get_param: dns_cluster_domain} + install_openstack_ca: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: + str_replace: + params: + $OPENSTACK_CA: {get_param: openstack_ca} + template: {get_file: ../../common/templates/fragments/atomic-install-openstack-ca.sh} + make_cert: type: OS::Heat::SoftwareConfig properties: @@ -450,6 +464,7 @@ resources: type: OS::Heat::MultipartMime properties: parts: + - config: {get_resource: install_openstack_ca} - config: {get_resource: disable_selinux} - config: {get_resource: write_heat_params} - config: {get_resource: configure_etcd} diff --git a/magnum/drivers/k8s_fedora_atomic_v1/templates/kubeminion.yaml b/magnum/drivers/k8s_fedora_atomic_v1/templates/kubeminion.yaml index 4a60703ed8..a03975624a 100644 --- a/magnum/drivers/k8s_fedora_atomic_v1/templates/kubeminion.yaml +++ b/magnum/drivers/k8s_fedora_atomic_v1/templates/kubeminion.yaml @@ -227,6 +227,10 @@ parameters: description: > domain name for cluster DNS + openstack_ca: + type: string + description: The OpenStack CA certificate to install on the node. + resources: minion_wait_handle: @@ -293,6 +297,16 @@ resources: $DNS_SERVICE_IP: {get_param: dns_service_ip} $DNS_CLUSTER_DOMAIN: {get_param: dns_cluster_domain} + install_openstack_ca: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: + str_replace: + params: + $OPENSTACK_CA: {get_param: openstack_ca} + template: {get_file: ../../common/templates/fragments/atomic-install-openstack-ca.sh} + write_kube_os_config: type: OS::Heat::SoftwareConfig properties: @@ -385,6 +399,7 @@ resources: type: OS::Heat::MultipartMime properties: parts: + - config: {get_resource: install_openstack_ca} - config: {get_resource: disable_selinux} - config: {get_resource: write_heat_params} - config: {get_resource: write_kube_os_config} diff --git a/magnum/drivers/k8s_fedora_ironic_v1/templates/kubecluster.yaml b/magnum/drivers/k8s_fedora_ironic_v1/templates/kubecluster.yaml index 736815903f..e94cf39b37 100644 --- a/magnum/drivers/k8s_fedora_ironic_v1/templates/kubecluster.yaml +++ b/magnum/drivers/k8s_fedora_ironic_v1/templates/kubecluster.yaml @@ -342,6 +342,11 @@ parameters: - allowed_pattern: "^$|.*/" default: "" + openstack_ca: + type: string + hidden: true + description: The OpenStack CA certificate to install on the node. + resources: api_lb: @@ -503,6 +508,7 @@ resources: container_infra_prefix: {get_param: container_infra_prefix} wc_curl_cli: {get_attr: [master_wait_handle, curl_cli]} etcd_lb_vip: {get_attr: [etcd_lb, address]} + openstack_ca: {get_param: openstack_ca} ###################################################################### # @@ -591,6 +597,7 @@ resources: insecure_registry_url: {get_param: insecure_registry_url} container_infra_prefix: {get_param: container_infra_prefix} wc_curl_cli: {get_attr: [minion_wait_handle, curl_cli]} + openstack_ca: {get_param: openstack_ca} ###################################################################### # diff --git a/magnum/drivers/k8s_fedora_ironic_v1/templates/kubemaster.yaml b/magnum/drivers/k8s_fedora_ironic_v1/templates/kubemaster.yaml index ce99133351..9db0bcd423 100644 --- a/magnum/drivers/k8s_fedora_ironic_v1/templates/kubemaster.yaml +++ b/magnum/drivers/k8s_fedora_ironic_v1/templates/kubemaster.yaml @@ -238,6 +238,10 @@ parameters: etcd lb vip private used to generate certs on master. default: "" + openstack_ca: + type: string + description: The OpenStack CA certificate to install on the node. + resources: ###################################################################### @@ -309,6 +313,16 @@ resources: "$ENABLE_CINDER": "False" "$ETCD_LB_VIP": {get_param: etcd_lb_vip} + install_openstack_ca: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: + str_replace: + params: + $OPENSTACK_CA: {get_param: openstack_ca} + template: {get_file: ../../common/templates/fragments/atomic-install-openstack-ca.sh} + make_cert: type: OS::Heat::SoftwareConfig properties: @@ -419,6 +433,7 @@ resources: type: OS::Heat::MultipartMime properties: parts: + - config: {get_resource: install_openstack_ca} - config: {get_resource: disable_selinux} - config: {get_resource: write_heat_params} - config: {get_resource: configure_etcd} diff --git a/magnum/drivers/k8s_fedora_ironic_v1/templates/kubeminion_software_configs.yaml b/magnum/drivers/k8s_fedora_ironic_v1/templates/kubeminion_software_configs.yaml index 858442c8b4..3c787e3125 100644 --- a/magnum/drivers/k8s_fedora_ironic_v1/templates/kubeminion_software_configs.yaml +++ b/magnum/drivers/k8s_fedora_ironic_v1/templates/kubeminion_software_configs.yaml @@ -173,6 +173,10 @@ parameters: description : > Wait condition notify command for Minion. + openstack_ca: + type: string + description: The OpenStack CA certificate to install on the node. + resources: ###################################################################### @@ -228,6 +232,16 @@ resources: $CONTAINER_INFRA_PREFIX: {get_param: container_infra_prefix} $ENABLE_CINDER: "False" + install_openstack_ca: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: + str_replace: + params: + $OPENSTACK_CA: {get_param: openstack_ca} + template: {get_file: ../../common/templates/fragments/atomic-install-openstack-ca.sh} + make_cert: type: OS::Heat::SoftwareConfig properties: @@ -320,6 +334,7 @@ resources: type: OS::Heat::MultipartMime properties: parts: + - config: {get_resource: install_openstack_ca} - config: {get_resource: disable_selinux} - config: {get_resource: write_heat_params} - config: {get_resource: make_cert} diff --git a/magnum/drivers/mesos_ubuntu_v1/templates/fragments/add-ext-ca-certs.sh b/magnum/drivers/mesos_ubuntu_v1/templates/fragments/add-ext-ca-certs.sh new file mode 100644 index 0000000000..34a524ac6c --- /dev/null +++ b/magnum/drivers/mesos_ubuntu_v1/templates/fragments/add-ext-ca-certs.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +CACERTS=$(cat <<-EOF +@@CACERTS_CONTENT@@ +EOF +) + +CA_FILE=/usr/local/share/ca-certificates/magnum-external.crt + +if [ -n "$CACERTS" ]; then + touch $CA_FILE + echo "$CACERTS" | tee -a $CA_FILE + chmod 0644 $CA_FILE + chown root:root $CA_FILE + update-ca-certificates + # Legacy versions of requests shipped with os-collect-config can have own CA cert database + for REQUESTS_LOCATION in \ + /opt/stack/venvs/os-collect-config/lib/python2.7/site-packages/requests \ + /usr/local/lib/python2.7/dist-packages/requests; do + if [ -f "${REQUESTS_LOCATION}/cacert.pem" ]; then + echo "$CACERTS" | tee -a "${REQUESTS_LOCATION}/cacert.pem" + fi + done + if [ -f /etc/init/os-collect-config.conf ]; then + service os-collect-config restart + fi +fi diff --git a/magnum/drivers/mesos_ubuntu_v1/templates/mesos_slave_software_configs.yaml b/magnum/drivers/mesos_ubuntu_v1/templates/mesos_slave_software_configs.yaml index e54037b36f..1b5293144e 100644 --- a/magnum/drivers/mesos_ubuntu_v1/templates/mesos_slave_software_configs.yaml +++ b/magnum/drivers/mesos_ubuntu_v1/templates/mesos_slave_software_configs.yaml @@ -104,6 +104,10 @@ parameters: type: string description: Wait condition notify command for slave. + openstack_ca: + type: string + description: The OpenStack CA certificate to install on the node. + resources: ###################################################################### @@ -138,6 +142,16 @@ resources: "$IMAGE_PROVIDERS": {get_param: mesos_slave_image_providers} "$EXECUTOR_ENVIRONMENT_VARIABLES": {get_param: mesos_slave_executor_env_variables} + add_ext_ca_certs: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: + str_replace: + template: {get_file: fragments/add-ext-ca-certs.sh} + params: + "@@CACERTS_CONTENT@@": {get_param: openstack_ca} + configure_mesos_slave: type: OS::Heat::SoftwareConfig properties: @@ -179,6 +193,7 @@ resources: type: OS::Heat::MultipartMime properties: parts: + - config: {get_resource: add_ext_ca_certs} - config: {get_resource: write_heat_params} - config: {get_resource: configure_mesos_slave} - config: {get_resource: add_proxy} diff --git a/magnum/drivers/mesos_ubuntu_v1/templates/mesoscluster.yaml b/magnum/drivers/mesos_ubuntu_v1/templates/mesoscluster.yaml index 3a9e65c6b2..b0e75b7fc7 100644 --- a/magnum/drivers/mesos_ubuntu_v1/templates/mesoscluster.yaml +++ b/magnum/drivers/mesos_ubuntu_v1/templates/mesoscluster.yaml @@ -211,6 +211,11 @@ parameters: type: boolean description: whether or not to validate certificate authority + openstack_ca: + type: string + hidden: true + description: The OpenStack CA certificate to install on the node. + resources: ###################################################################### @@ -391,6 +396,7 @@ resources: fixed_subnet: {get_attr: [network, fixed_subnet]} secgroup_mesos_id: {get_resource: secgroup_master} api_pool_id: {get_attr: [api_lb, pool_id]} + openstack_ca: {get_param: openstack_ca} ###################################################################### # @@ -463,6 +469,7 @@ resources: mesos_slave_executor_env_variables: {get_param: mesos_slave_executor_env_variables} mesos_slave_wc_curl_cli: {get_attr: [slave_wait_handle, curl_cli]} verify_ca: {get_param: verify_ca} + openstack_ca: {get_param: openstack_ca} outputs: diff --git a/magnum/drivers/mesos_ubuntu_v1/templates/mesosmaster.yaml b/magnum/drivers/mesos_ubuntu_v1/templates/mesosmaster.yaml index a383b7f0b0..c79233f5b3 100644 --- a/magnum/drivers/mesos_ubuntu_v1/templates/mesosmaster.yaml +++ b/magnum/drivers/mesos_ubuntu_v1/templates/mesosmaster.yaml @@ -43,8 +43,29 @@ parameters: type: string description: ID of the load balancer pool of Marathon. + openstack_ca: + type: string + hidden: true + description: The OpenStack CA certificate to install on the node. + resources: + add_ext_ca_certs: + type: OS::Heat::SoftwareConfig + properties: + group: script + config: + str_replace: + template: {get_file: fragments/add-ext-ca-certs.sh} + params: + "@@CACERTS_CONTENT@@": {get_param: openstack_ca} + + mesos_master_init: + type: OS::Heat::MultipartMime + properties: + parts: + - config: {get_resource: add_ext_ca_certs} + ###################################################################### # # Mesos master server. @@ -61,6 +82,7 @@ resources: flavor: {get_param: master_flavor} key_name: {get_param: ssh_key_name} user_data_format: SOFTWARE_CONFIG + user_data: {get_resource: mesos_master_init} networks: - port: {get_resource: mesos_master_eth0} diff --git a/magnum/drivers/swarm_fedora_atomic_v1/templates/cluster.yaml b/magnum/drivers/swarm_fedora_atomic_v1/templates/cluster.yaml index 103e8ef002..debd6c36df 100644 --- a/magnum/drivers/swarm_fedora_atomic_v1/templates/cluster.yaml +++ b/magnum/drivers/swarm_fedora_atomic_v1/templates/cluster.yaml @@ -250,6 +250,11 @@ parameters: other hosts are using the volume default: "false" + openstack_ca: + type: string + hidden: true + description: The OpenStack CA certificate to install on the node. + resources: @@ -395,6 +400,7 @@ resources: auth_url: {get_param: auth_url} volume_driver: {get_param: volume_driver} rexray_preempt: {get_param: rexray_preempt} + openstack_ca: {get_param: openstack_ca} swarm_nodes: type: "OS::Heat::ResourceGroup" @@ -446,6 +452,7 @@ resources: registry_chunksize: {get_param: registry_chunksize} volume_driver: {get_param: volume_driver} rexray_preempt: {get_param: rexray_preempt} + openstack_ca: {get_param: openstack_ca} outputs: diff --git a/magnum/drivers/swarm_fedora_atomic_v1/templates/swarmmaster.yaml b/magnum/drivers/swarm_fedora_atomic_v1/templates/swarmmaster.yaml index a8f040762f..41d989e421 100644 --- a/magnum/drivers/swarm_fedora_atomic_v1/templates/swarmmaster.yaml +++ b/magnum/drivers/swarm_fedora_atomic_v1/templates/swarmmaster.yaml @@ -174,6 +174,10 @@ parameters: other hosts are using the volume default: "false" + openstack_ca: + type: string + description: The OpenStack CA certificate to install on the node. + resources: master_wait_handle: @@ -260,6 +264,16 @@ resources: "$VOLUME_DRIVER": {get_param: volume_driver} "$REXRAY_PREEMPT": {get_param: rexray_preempt} + install_openstack_ca: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: + str_replace: + params: + $OPENSTACK_CA: {get_param: openstack_ca} + template: {get_file: ../../common/templates/fragments/atomic-install-openstack-ca.sh} + write_network_config: type: "OS::Heat::SoftwareConfig" properties: @@ -387,6 +401,7 @@ resources: type: "OS::Heat::MultipartMime" properties: parts: + - config: {get_resource: install_openstack_ca} - config: {get_resource: configure_selinux} - config: {get_resource: remove_docker_key} - config: {get_resource: write_heat_params} diff --git a/magnum/drivers/swarm_fedora_atomic_v1/templates/swarmnode.yaml b/magnum/drivers/swarm_fedora_atomic_v1/templates/swarmnode.yaml index 3d4dd64899..5460621d19 100644 --- a/magnum/drivers/swarm_fedora_atomic_v1/templates/swarmnode.yaml +++ b/magnum/drivers/swarm_fedora_atomic_v1/templates/swarmnode.yaml @@ -173,6 +173,10 @@ parameters: other hosts are using the volume default: "false" + openstack_ca: + type: string + description: The OpenStack CA certificate to install on the node. + resources: node_wait_handle: @@ -242,6 +246,16 @@ resources: "$VOLUME_DRIVER": {get_param: volume_driver} "$REXRAY_PREEMPT": {get_param: rexray_preempt} + install_openstack_ca: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: + str_replace: + params: + $OPENSTACK_CA: {get_param: openstack_ca} + template: {get_file: ../../common/templates/fragments/atomic-install-openstack-ca.sh} + remove_docker_key: type: "OS::Heat::SoftwareConfig" properties: @@ -350,6 +364,7 @@ resources: type: "OS::Heat::MultipartMime" properties: parts: + - config: {get_resource: install_openstack_ca} - config: {get_resource: configure_selinux} - config: {get_resource: remove_docker_key} - config: {get_resource: write_heat_params} diff --git a/magnum/drivers/swarm_fedora_atomic_v2/templates/swarmcluster.yaml b/magnum/drivers/swarm_fedora_atomic_v2/templates/swarmcluster.yaml index 55de3290d0..1a0bac1300 100644 --- a/magnum/drivers/swarm_fedora_atomic_v2/templates/swarmcluster.yaml +++ b/magnum/drivers/swarm_fedora_atomic_v2/templates/swarmcluster.yaml @@ -181,6 +181,11 @@ parameters: type: boolean description: whether or not to validate certificate authority + openstack_ca: + type: string + hidden: true + description: The OpenStack CA certificate to install on the node. + resources: ###################################################################### @@ -303,6 +308,7 @@ resources: volume_driver: {get_param: volume_driver} rexray_preempt: {get_param: rexray_preempt} verify_ca: {get_param: verify_ca} + openstack_ca: {get_param: openstack_ca} swarm_secondary_masters: type: "OS::Heat::ResourceGroup" @@ -345,6 +351,7 @@ resources: volume_driver: {get_param: volume_driver} rexray_preempt: {get_param: rexray_preempt} verify_ca: {get_param: verify_ca} + openstack_ca: {get_param: openstack_ca} swarm_nodes: type: "OS::Heat::ResourceGroup" @@ -387,6 +394,7 @@ resources: volume_driver: {get_param: volume_driver} rexray_preempt: {get_param: rexray_preempt} verify_ca: {get_param: verify_ca} + openstack_ca: {get_param: openstack_ca} outputs: diff --git a/magnum/drivers/swarm_fedora_atomic_v2/templates/swarmmaster.yaml b/magnum/drivers/swarm_fedora_atomic_v2/templates/swarmmaster.yaml index cd7e675c54..4a9e0cbe8f 100644 --- a/magnum/drivers/swarm_fedora_atomic_v2/templates/swarmmaster.yaml +++ b/magnum/drivers/swarm_fedora_atomic_v2/templates/swarmmaster.yaml @@ -137,6 +137,10 @@ parameters: type: boolean description: whether or not to validate certificate authority + openstack_ca: + type: string + description: The OpenStack CA certificate to install on the node. + resources: master_wait_handle: @@ -199,6 +203,16 @@ resources: "$REXRAY_PREEMPT": {get_param: rexray_preempt} "$VERIFY_CA": {get_param: verify_ca} + install_openstack_ca: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: + str_replace: + params: + $OPENSTACK_CA: {get_param: openstack_ca} + template: {get_file: ../../common/templates/fragments/atomic-install-openstack-ca.sh} + remove_docker_key: type: "OS::Heat::SoftwareConfig" properties: @@ -271,6 +285,7 @@ resources: type: "OS::Heat::MultipartMime" properties: parts: + - config: {get_resource: install_openstack_ca} - config: {get_resource: configure_selinux} - config: {get_resource: remove_docker_key} - config: {get_resource: write_heat_params} diff --git a/magnum/drivers/swarm_fedora_atomic_v2/templates/swarmnode.yaml b/magnum/drivers/swarm_fedora_atomic_v2/templates/swarmnode.yaml index a205833001..164ed28e04 100644 --- a/magnum/drivers/swarm_fedora_atomic_v2/templates/swarmnode.yaml +++ b/magnum/drivers/swarm_fedora_atomic_v2/templates/swarmnode.yaml @@ -129,6 +129,10 @@ parameters: type: boolean description: whether or not to validate certificate authority + openstack_ca: + type: string + description: The OpenStack CA certificate to install on the node. + resources: node_wait_handle: @@ -176,6 +180,16 @@ resources: "$REXRAY_PREEMPT": {get_param: rexray_preempt} "$VERIFY_CA": {get_param: verify_ca} + install_openstack_ca: + type: OS::Heat::SoftwareConfig + properties: + group: ungrouped + config: + str_replace: + params: + $OPENSTACK_CA: {get_param: openstack_ca} + template: {get_file: ../../common/templates/fragments/atomic-install-openstack-ca.sh} + remove_docker_key: type: "OS::Heat::SoftwareConfig" properties: @@ -248,6 +262,7 @@ resources: type: "OS::Heat::MultipartMime" properties: parts: + - config: {get_resource: install_openstack_ca} - config: {get_resource: configure_selinux} - config: {get_resource: remove_docker_key} - config: {get_resource: write_heat_params} diff --git a/magnum/tests/unit/common/test_utils.py b/magnum/tests/unit/common/test_utils.py index a864360fcb..8bfa726034 100644 --- a/magnum/tests/unit/common/test_utils.py +++ b/magnum/tests/unit/common/test_utils.py @@ -25,8 +25,11 @@ from oslo_utils import netutils from magnum.common import exception from magnum.common import utils +import magnum.conf from magnum.tests import base +CONF = magnum.conf.CONF + class UtilsTestCase(base.TestCase): @@ -52,6 +55,24 @@ class UtilsTestCase(base.TestCase): self.assertRaises(exception.UnsupportedDockerQuantityFormat, utils.get_docker_quantity, '512B') + def test_get_openstasck_ca(self): + # openstack_ca_file is empty + self.assertEqual('', utils.get_openstack_ca()) + + # openstack_ca_file is set but the file doesn't exist + CONF.set_override('openstack_ca_file', + '/tmp/invalid-ca.pem', + group='drivers') + self.assertRaises(IOError, utils.get_openstack_ca) + + # openstack_ca_file is set and the file exists + CONF.set_override('openstack_ca_file', + '/tmp/invalid-ca.pem', + group='drivers') + with mock.patch('magnum.common.utils.open', + mock.mock_open(read_data="CERT"), create=True): + self.assertEqual('CERT', utils.get_openstack_ca()) + class ExecuteTestCase(base.TestCase): diff --git a/magnum/tests/unit/conductor/handlers/test_k8s_cluster_conductor.py b/magnum/tests/unit/conductor/handlers/test_k8s_cluster_conductor.py index c18786bafa..9ea6ce724e 100644 --- a/magnum/tests/unit/conductor/handlers/test_k8s_cluster_conductor.py +++ b/magnum/tests/unit/conductor/handlers/test_k8s_cluster_conductor.py @@ -228,6 +228,7 @@ class TestClusterConductorWithK8s(base.TestCase): 'insecure_registry_url': '10.0.0.1:5000', 'kube_version': 'fake-version', 'verify_ca': True, + 'openstack_ca': '', } if missing_attr is not None: expected.pop(mapping[missing_attr], None) @@ -323,6 +324,7 @@ class TestClusterConductorWithK8s(base.TestCase): 'insecure_registry_url': '10.0.0.1:5000', 'kube_version': 'fake-version', 'verify_ca': True, + 'openstack_ca': '', } self.assertEqual(expected, definition) @@ -405,6 +407,7 @@ class TestClusterConductorWithK8s(base.TestCase): 'trustee_username': 'fake_trustee', 'username': 'fake_user', 'verify_ca': True, + 'openstack_ca': '', } self.assertEqual(expected, definition) self.assertEqual( @@ -482,6 +485,7 @@ class TestClusterConductorWithK8s(base.TestCase): 'insecure_registry_url': '10.0.0.1:5000', 'kube_version': 'fake-version', 'verify_ca': True, + 'openstack_ca': '', } self.assertEqual(expected, definition) self.assertEqual( @@ -554,6 +558,7 @@ class TestClusterConductorWithK8s(base.TestCase): 'insecure_registry_url': '10.0.0.1:5000', 'kube_version': 'fake-version', 'verify_ca': True, + 'openstack_ca': '', } self.assertEqual(expected, definition) self.assertEqual( @@ -725,6 +730,7 @@ class TestClusterConductorWithK8s(base.TestCase): 'insecure_registry_url': '10.0.0.1:5000', 'kube_version': 'fake-version', 'verify_ca': True, + 'openstack_ca': '', } self.assertEqual(expected, definition) self.assertEqual( diff --git a/magnum/tests/unit/conductor/handlers/test_mesos_cluster_conductor.py b/magnum/tests/unit/conductor/handlers/test_mesos_cluster_conductor.py index 19d04aabbd..dcd68ef7cc 100644 --- a/magnum/tests/unit/conductor/handlers/test_mesos_cluster_conductor.py +++ b/magnum/tests/unit/conductor/handlers/test_mesos_cluster_conductor.py @@ -140,6 +140,7 @@ class TestClusterConductorWithMesos(base.TestCase): 'mesos_slave_work_dir': '/tmp/mesos/slave', 'mesos_slave_image_providers': 'docker', 'verify_ca': True, + 'openstack_ca': '', } self.assertEqual(expected, definition) self.assertEqual( @@ -196,6 +197,7 @@ class TestClusterConductorWithMesos(base.TestCase): 'master_flavor': 'master_flavor_id', 'verify_ca': True, 'slave_flavor': 'flavor_id', + 'openstack_ca': '', } self.assertEqual(expected, definition) self.assertEqual( @@ -254,6 +256,7 @@ class TestClusterConductorWithMesos(base.TestCase): 'mesos_slave_work_dir': '/tmp/mesos/slave', 'mesos_slave_image_providers': 'docker', 'verify_ca': True, + 'openstack_ca': '', } self.assertEqual(expected, definition) self.assertEqual( @@ -313,6 +316,7 @@ class TestClusterConductorWithMesos(base.TestCase): 'mesos_slave_work_dir': '/tmp/mesos/slave', 'mesos_slave_image_providers': 'docker', 'verify_ca': True, + 'openstack_ca': '', } self.assertEqual(expected, definition) self.assertEqual( diff --git a/magnum/tests/unit/conductor/handlers/test_swarm_cluster_conductor.py b/magnum/tests/unit/conductor/handlers/test_swarm_cluster_conductor.py index 847ce4fec8..2d72b61f9f 100644 --- a/magnum/tests/unit/conductor/handlers/test_swarm_cluster_conductor.py +++ b/magnum/tests/unit/conductor/handlers/test_swarm_cluster_conductor.py @@ -163,6 +163,7 @@ class TestClusterConductorWithSwarm(base.TestCase): 'rexray_preempt': 'False', 'docker_volume_type': 'lvmdriver-1', 'verify_ca': True, + 'openstack_ca': '', } self.assertEqual(expected, definition) self.assertEqual( @@ -240,6 +241,7 @@ class TestClusterConductorWithSwarm(base.TestCase): 'rexray_preempt': 'False', 'docker_volume_type': 'lvmdriver-1', 'verify_ca': True, + 'openstack_ca': '', } self.assertEqual(expected, definition) self.assertEqual( @@ -311,6 +313,7 @@ class TestClusterConductorWithSwarm(base.TestCase): 'master_flavor': 'master_flavor_id', 'verify_ca': True, 'node_flavor': 'flavor_id', + 'openstack_ca': '', } self.assertEqual(expected, definition) self.assertEqual( @@ -382,6 +385,7 @@ class TestClusterConductorWithSwarm(base.TestCase): 'rexray_preempt': 'False', 'docker_volume_type': 'lvmdriver-1', 'verify_ca': True, + 'openstack_ca': '', } self.assertEqual(expected, definition) self.assertEqual( @@ -454,6 +458,7 @@ class TestClusterConductorWithSwarm(base.TestCase): 'rexray_preempt': 'False', 'docker_volume_type': 'lvmdriver-1', 'verify_ca': True, + 'openstack_ca': '', } self.assertEqual(expected, definition) self.assertEqual( diff --git a/releasenotes/notes/bug-1580704-32a0e91e285792ea.yaml b/releasenotes/notes/bug-1580704-32a0e91e285792ea.yaml new file mode 100644 index 0000000000..088feea1ef --- /dev/null +++ b/releasenotes/notes/bug-1580704-32a0e91e285792ea.yaml @@ -0,0 +1,7 @@ +--- +security: + - | + Add new configuration option `openstack_ca_file` in the `drivers` section + to pass the CA bundle used for the OpenStack API. Setting this file and + setting `verify_ca` to `true` will result to all requests from the cluster + nodes to the OpenStack APIs to be verified.