From 72d4d64609030201ccdc753b98091552638b03e5 Mon Sep 17 00:00:00 2001
From: Doug Szumski <doug@stackhpc.com>
Date: Fri, 13 Dec 2019 09:49:33 +0000
Subject: [PATCH] Support custom Kolla group_vars

In Kayobe hosts which are part of a Nova cell can be managed via the
existing controller and compute groups. However, since Nova Cells are
configured via group vars in Kolla Ansible we need some way of setting
these. We could pass vars through to Kolla Ansible host vars using
`kolla_overcloud_inventory_pass_through_host_vars` but the list of
variables which may be set on a per cell basis is large and undefined.

This change allows the user to directly specify Kolla Ansible group vars
as part of Kayobe config, allowing the deployment of Nova Cells by
Kayobe to be largely unchanged from the procedure documented in Kolla
Ansible.

Change-Id: I2695034d36936fcc77a4828c67f9552155781dd6
Story: 2004291
Task: 37804
---
 ansible/kolla-ansible.yml                     |  1 +
 ansible/roles/kolla-ansible/defaults/main.yml |  3 +
 ansible/roles/kolla-ansible/tasks/config.yml  | 12 ++++
 .../kolla-ansible/tests/test-defaults.yml     | 16 +++++
 .../roles/kolla-ansible/tests/test-extras.yml | 60 +++++++++++++++++++
 doc/source/configuration/kolla-ansible.rst    | 28 +++++++++
 ...or-custom-group-vars-3760547c3505487d.yaml |  4 ++
 7 files changed, 124 insertions(+)
 create mode 100644 releasenotes/notes/add-support-for-custom-group-vars-3760547c3505487d.yaml

diff --git a/ansible/kolla-ansible.yml b/ansible/kolla-ansible.yml
index 854fdd30..cc7fcd1d 100644
--- a/ansible/kolla-ansible.yml
+++ b/ansible/kolla-ansible.yml
@@ -290,6 +290,7 @@
         kolla_external_fqdn_cert: "{{ kolla_config_path }}/certificates/haproxy.pem"
         kolla_internal_fqdn_cert: "{{ kolla_config_path }}/certificates/haproxy-internal.pem"
         kolla_ansible_passwords_path: "{{ kayobe_config_path }}/kolla/passwords.yml"
+        kolla_overcloud_group_vars_path: "{{ kayobe_config_path }}/kolla/inventory/group_vars"
         # NOTE: This differs from the default SELinux mode in kolla ansible,
         # which is permissive. The justification for using this mode is twofold:
         # 1. it avoids filling up the audit log
diff --git a/ansible/roles/kolla-ansible/defaults/main.yml b/ansible/roles/kolla-ansible/defaults/main.yml
index 2294dc67..e49ce365 100644
--- a/ansible/roles/kolla-ansible/defaults/main.yml
+++ b/ansible/roles/kolla-ansible/defaults/main.yml
@@ -54,6 +54,9 @@ kolla_ansible_become: true
 # Full custom seed inventory contents.
 kolla_seed_inventory_custom:
 
+# Directory containing custom Kolla-Ansible group vars.
+kolla_overcloud_group_vars_path:
+
 # List of names of host variables to pass through from kayobe hosts to
 # the kolla-ansible seed host, if set. See also
 # kolla_seed_inventory_pass_through_host_vars_map.
diff --git a/ansible/roles/kolla-ansible/tasks/config.yml b/ansible/roles/kolla-ansible/tasks/config.yml
index 57b73065..151c1dd9 100644
--- a/ansible/roles/kolla-ansible/tasks/config.yml
+++ b/ansible/roles/kolla-ansible/tasks/config.yml
@@ -38,6 +38,7 @@
     - "{{ kolla_config_path }}"
     - "{{ kolla_seed_inventory_path }}/host_vars"
     - "{{ kolla_overcloud_inventory_path }}/host_vars"
+    - "{{ kolla_overcloud_inventory_path }}/group_vars"
     - "{{ kolla_node_custom_config_path }}"
 
 - name: Ensure the Kolla global configuration file exists
@@ -72,6 +73,17 @@
     dest: "{{ kolla_overcloud_inventory_path }}/hosts"
     mode: 0640
 
+- name: Look for custom Kolla overcloud group vars
+  stat:
+    path: "{{ kolla_overcloud_group_vars_path }}"
+  register: kolla_ansible_custom_overcloud_group_vars
+
+- name: Copy over custom Kolla overcloud group vars
+  copy:
+    src: "{{ kolla_overcloud_group_vars_path }}"
+    dest: "{{ kolla_overcloud_inventory_path }}/"
+  when: kolla_ansible_custom_overcloud_group_vars.stat.exists
+
 - name: Ensure the Kolla overcloud host vars files exist
   template:
     src: host-vars.j2
diff --git a/ansible/roles/kolla-ansible/tests/test-defaults.yml b/ansible/roles/kolla-ansible/tests/test-defaults.yml
index c3f2c5ca..a438506e 100644
--- a/ansible/roles/kolla-ansible/tests/test-defaults.yml
+++ b/ansible/roles/kolla-ansible/tests/test-defaults.yml
@@ -19,6 +19,9 @@
             kolla_ansible_venv: "{{ temp_path }}/venv"
             kolla_config_path: "{{ temp_path }}/etc/kolla"
             kolla_node_custom_config_path: "{{ temp_path }}/etc/kolla/config"
+            # Purposely does not exist to simulate the case when no group vars
+            # are provided
+            kolla_overcloud_group_vars_path: "{{ temp_path }}/etc/kayobe/kolla/inventory/group_vars"
             kolla_ansible_passwords_path: "{{ temp_path }}/passwords.yml"
             # Required config.
             kolla_base_distro: "fake-distro"
@@ -131,6 +134,7 @@
             - seed/host_vars
             - overcloud
             - overcloud/host_vars
+            - overcloud/group_vars
           register: inventory_stat
 
         - name: Validate inventory files
@@ -142,6 +146,18 @@
               Inventory file {{ item.item }} was not found.
           with_items: "{{ inventory_stat.results }}"
 
+        - name: Look for custom overcloud group vars
+          find:
+            paths: "{{ temp_path ~ '/etc/kolla/inventory/group_vars' }}"
+          register: kolla_ansible_overcloud_group_vars
+
+        - name: Check that no overcloud group vars are set
+          assert:
+            that:
+              - kolla_ansible_overcloud_group_vars.matched == 0
+            msg: >
+              Overcloud group vars were found when they should not be set.
+
         - name: Validate passwords.yml contents
           assert:
             that: item in passwords_yml
diff --git a/ansible/roles/kolla-ansible/tests/test-extras.yml b/ansible/roles/kolla-ansible/tests/test-extras.yml
index 9ee12d08..f3671e0d 100644
--- a/ansible/roles/kolla-ansible/tests/test-extras.yml
+++ b/ansible/roles/kolla-ansible/tests/test-extras.yml
@@ -49,6 +49,25 @@
         state: directory
       register: tempfile_result
 
+    - name: Create directory for custom overcloud foo group vars
+      file:
+        path: "{{ tempfile_result.path ~ '/etc/kayobe/kolla/inventory/group_vars/foo_group' }}"
+        state: directory
+
+    - name: Create custom overcloud foo group vars
+      copy:
+        dest: "{{ tempfile_result.path ~ '/etc/kayobe/kolla/inventory/group_vars/foo_group/all' }}"
+        content: |
+          ---
+          foo_port: "1234"
+
+    - name: Create custom overcloud bar group vars
+      copy:
+        dest: "{{ tempfile_result.path ~ '/etc/kayobe/kolla/inventory/group_vars/bar_group' }}"
+        content: |
+          ---
+          bar_port: "4567"
+
     - block:
         - name: Test the kolla-ansible role with default values
           include_role:
@@ -61,6 +80,7 @@
             kolla_ansible_venv: "{{ temp_path }}/venv"
             kolla_ansible_vault_password: "fake-password"
             kolla_config_path: "{{ temp_path }}/etc/kolla"
+            kolla_overcloud_group_vars_path: "{{ temp_path }}/etc/kayobe/kolla/inventory/group_vars"
             kolla_node_custom_config_path: "{{ temp_path }}/etc/kolla/config"
             kolla_ansible_passwords_path: "{{ temp_path }}/passwords.yml"
             # Config.
@@ -496,6 +516,46 @@
                 neutron_external_interface: "eth4,eth5"
                 neutron_bridge_name: "br0,br1"
 
+        - name: Check whether inventory group vars files exist
+          stat:
+            path: "{{ temp_path ~ '/etc/kolla/inventory/overcloud/group_vars/' ~ item }}"
+          with_items:
+            - foo_group/all
+            - bar_group
+          register: group_vars_stat
+
+        - name: Validate inventory group vars files
+          assert:
+            that:
+              - item.stat.exists
+              - item.stat.size > 0
+            msg: >
+              Inventory file {{ item.item }} was not found.
+          with_items: "{{ group_vars_stat.results }}"
+
+        - name: Read inventory group vars files
+          slurp:
+            src: "{{ item.stat.path }}"
+          with_items: "{{ group_vars_stat.results }}"
+          register: group_vars_slurp
+
+        - name: Validate inventory group vars file contents
+          assert:
+            that:
+              - group_vars_content is defined
+              - group_vars_content == item.1
+          with_together:
+            - "{{ group_vars_slurp.results }}"
+            - "{{ expected_contents }}"
+          vars:
+            group_vars_content: "{{ item.0.content | b64decode }}"
+            expected_contents:
+              - |
+                ---
+                foo_port: "1234"
+              - |
+                ---
+                bar_port: "4567"
       always:
         - name: Ensure the temporary directory is removed
           file:
diff --git a/doc/source/configuration/kolla-ansible.rst b/doc/source/configuration/kolla-ansible.rst
index a2907340..c413243a 100644
--- a/doc/source/configuration/kolla-ansible.rst
+++ b/doc/source/configuration/kolla-ansible.rst
@@ -299,6 +299,34 @@ to enable debug logging for Nova services:
    ---
    nova_logging_debug: true
 
+Custom Group Variables
+----------------------
+
+Group variables can be used to set configuration for all hosts in a group. They
+can be set in Kolla Ansible by placing files in
+``${KAYOBE_CONFIG_PATH}/kolla/inventory/group_vars/*``. Since this
+directory is copied directly into the Kolla Ansible inventory, Kolla
+Ansible group names should be used. It should be noted that
+``extra-vars`` and ``host_vars`` take precedence over ``group_vars``. For
+more information on variable precedence see the Ansible `documentation
+<http://docs.ansible.com/ansible/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable>`_.
+
+Example: configure a Nova cell
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In Kolla Ansible, :kolla-ansible-doc:`Nova cells are configured
+<reference/compute/nova-cells-guide>` via group variables. For example, to
+configure ``cell0001`` the following file could be created:
+
+.. code-block:: yaml
+   :caption: ``$KAYOBE_CONFIG_PATH/kolla/inventory/group_vars/cell0001/all``
+
+   ---
+   nova_cell_name: cell0001
+   nova_cell_novncproxy_group: cell0001-vnc
+   nova_cell_conductor_group: cell0001-control
+   nova_cell_compute_group: cell0001-compute
+
 Passwords
 ---------
 
diff --git a/releasenotes/notes/add-support-for-custom-group-vars-3760547c3505487d.yaml b/releasenotes/notes/add-support-for-custom-group-vars-3760547c3505487d.yaml
new file mode 100644
index 00000000..6633f7fb
--- /dev/null
+++ b/releasenotes/notes/add-support-for-custom-group-vars-3760547c3505487d.yaml
@@ -0,0 +1,4 @@
+---
+features:
+  - |
+    Adds support for passing through group vars to Kolla Ansible.
-- 
GitLab