From e37805bda96bd54a6c0108e6fb2e67298bbda280 Mon Sep 17 00:00:00 2001 From: zhihui wu Date: Thu, 20 Apr 2017 09:57:06 +0800 Subject: fix apex integration I didnot find a right way to source Openstack rc file via ansible module python api. Without openstack rc fiel, openstack cli command can not be executed. So I move this part to ansible playbook. Change-Id: I44439560f8ffa1b41890c4e94c9657ab2cc43241 Signed-off-by: zhihui wu --- qtip/ansible_library/modules/apex.py | 133 --------------------- .../modules/apex_generate_inventory.py | 109 +++++++++++++++++ tests/integration/setup.yaml | 21 ++++ .../modules/apex_generate_inventory_test.py | 30 +++++ tests/unit/ansible_library/modules/apex_test.py | 30 ----- 5 files changed, 160 insertions(+), 163 deletions(-) delete mode 100644 qtip/ansible_library/modules/apex.py create mode 100644 qtip/ansible_library/modules/apex_generate_inventory.py create mode 100644 tests/unit/ansible_library/modules/apex_generate_inventory_test.py delete mode 100644 tests/unit/ansible_library/modules/apex_test.py diff --git a/qtip/ansible_library/modules/apex.py b/qtip/ansible_library/modules/apex.py deleted file mode 100644 index 218440b2..00000000 --- a/qtip/ansible_library/modules/apex.py +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/python - -############################################################### -# Copyright (c) 2017 ZTE Corporation -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - -from collections import defaultdict -import json -import re - -from ansible.module_utils.basic import AnsibleModule - - -ANSIBLE_METADATA = {'metadata_version': '1.0', - 'status': ['preview'], - 'supported_by': 'community'} - -DOCUMENTATION = ''' ---- -module: apex -short_description: collecting facts from apex environments -description: - - Use this module to create a dynamic inventory from apex undercloud. -version_added: "2.2" -author: "Zhihui Wu" -options: -notes: -requirements: - - Host 'apex-undercloud' is in ~/.ssh/config -''' - -RETURN = ''' -ansible_facts: - description: facts collected for ansible - returned: success - type: dictionary - contains: - hosts: - description: host grouped by hostname, cluster, role and manufacture - type: dict - hosts_meta: - description: hosts meta data indexed by hostname - type: dict -''' - -EXAMPLES = ''' ---- -- hosts: apex-undercloud - tasks: - - name: collect facts of apex hosts - apex: - - debug: var=hostvarsi - - name: add compute node to ansible inventory - add_host: - name: "{{ hosts_meta[item]['ip'] }}" - groups: compute - ansible_user: root - ansible_ssh_common_args: '-o StrictHostKeyChecking=No -o ProxyJump=apex-master' - with_items: "{{ hosts.compute }}" -- hosts: compute - tasks: - - name: check ssh connection - ping: -''' - - -def generate_inventory(baremetal_info, server_info): - """Generate ansible inventory from node list in json format - - Modified from https://github.com/martineg/ansible-apex-inventory/blob/master/apex.py - """ - - hosts = defaultdict(list) - hosts_meta = {} - - for node in baremetal_info: - if node['Provisioning State'].lower() == 'active': - role = re.findall('.+profile:(\w+)$', node['Properties']['capabilities'])[0] - for server in server_info: - if server['ID'] == node['Instance UUID']: - node_ip = re.findall('.+=(\d+.\d+.\d+.\d+)$', server['Networks'])[0] - hosts[role].append(node_ip) - # To match ssh.cfg.j2 template - hosts_meta[node_ip] = {'ansible_ssh_host': node_ip} - - for host in hosts: - hosts[host].sort() - - return {'hosts': hosts, 'hosts_meta': hosts_meta} - - -def main(): - module = AnsibleModule(argument_spec=dict()) - - (rc, out, err) = module.run_command(['source ~/stackrc']) - - if rc is not None and rc != 0: - return module.fail_json(msg=err) - - cmd = [module.get_bin_path('openstack', True), - 'baremetal', - 'list', - '--fields instance_uuid properties provision_state', - '--format json'] - (rc, out, err) = module.run_command(cmd) - - if rc is not None and rc != 0: - return module.fail_json(msg=err) - - baremetal_info = json.loads(out) - - cmd = [module.get_bin_path('openstack', True), - 'server', - 'list', - '--format json'] - (rc, out, err) = module.run_command(cmd) - - if rc is not None and rc != 0: - return module.fail_json(msg=err) - - server_info = json.loads(out) - - module.exit_json(changed=False, - ansible_facts=generate_inventory(baremetal_info, server_info)) - - -if __name__ == '__main__': - main() diff --git a/qtip/ansible_library/modules/apex_generate_inventory.py b/qtip/ansible_library/modules/apex_generate_inventory.py new file mode 100644 index 00000000..9621ba6e --- /dev/null +++ b/qtip/ansible_library/modules/apex_generate_inventory.py @@ -0,0 +1,109 @@ +#!/usr/bin/python + +############################################################### +# Copyright (c) 2017 ZTE Corporation +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +from collections import defaultdict +import re + +from ansible.module_utils.basic import AnsibleModule + + +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = ''' +--- +module: apex +short_description: collecting facts from apex environments +description: + - Use this module to create a dynamic inventory from apex undercloud. +version_added: "2.2" +author: "Zhihui Wu" +options: +notes: +requirements: + - Host 'apex-undercloud' is in ~/.ssh/config +''' + +RETURN = ''' +ansible_facts: + description: facts collected for ansible + returned: success + type: dictionary + contains: + hosts: + description: host grouped by hostname, cluster, role and manufacture + type: dict + hosts_meta: + description: hosts meta data indexed by hostname + type: dict +''' + +EXAMPLES = ''' +--- +- hosts: apex-undercloud + tasks: + - name: collect facts of apex hosts + apex: + - debug: var=hostvarsi + - name: add compute node to ansible inventory + add_host: + name: "{{ hosts_meta[item]['ip'] }}" + groups: compute + ansible_user: root + ansible_ssh_common_args: '-o StrictHostKeyChecking=No -o ProxyJump=apex-master' + with_items: "{{ hosts.compute }}" +- hosts: compute + tasks: + - name: check ssh connection + ping: +''' + + +def generate_inventory(baremetal_info, server_info): + """Generate ansible inventory in json format""" + + hosts = defaultdict(list) + hosts_meta = {} + + for node in baremetal_info: + if node['Provisioning State'].lower() == 'active': + role = re.findall('.+profile:(\w+)$', node['Properties']['capabilities'])[0] + for server in server_info: + if server['ID'] == node['Instance UUID']: + node_ip = re.findall('.+=(\d+.\d+.\d+.\d+)$', server['Networks'])[0] + hosts[role].append(node_ip) + # To match ssh.cfg.j2 template + hosts_meta[node_ip] = {'ansible_ssh_host': node_ip} + + for host in hosts: + hosts[host].sort() + + return {'hosts': hosts, 'hosts_meta': hosts_meta} + + +def main(): + module = AnsibleModule( + argument_spec=dict( + baremetal_info=dict(type='list'), + server_info=dict(type='list') + ) + ) + + baremetal_info = module.params['baremetal_info'] + server_info = module.params['server_info'] + + module.exit_json(changed=True, + ansible_facts=generate_inventory(baremetal_info, server_info)) + + +if __name__ == '__main__': + main() diff --git a/tests/integration/setup.yaml b/tests/integration/setup.yaml index 8d055c23..fed5e9d9 100644 --- a/tests/integration/setup.yaml +++ b/tests/integration/setup.yaml @@ -20,6 +20,27 @@ template: src={{ qtip_resources }}/template/ssh.cfg.j2 dest=./ssh.cfg delegate_to: localhost +- hosts: apex-undercloud + gather_facts: no + + tasks: + - name: collect overcloud baremetal info + shell: . /root/stackrc && openstack baremetal list --fields instance_uuid properties provision_state --format json + register: baremetal_info + - name: collect overcloud server info + shell: . /root/stackrc && openstack server list --format json + register: server_info + - name: generate inventory + apex_generate_inventory: + baremetal_info: "{{ baremetal_info.stdout | from_json }}" + server_info: "{{ server_info.stdout | from_json }}" + - name: update inventory file + template: src={{ qtip_resources }}/template/hosts.j2 dest=./hosts + delegate_to: localhost + - name: update ssh.cfg file + template: src={{ qtip_resources }}/template/ssh.cfg.j2 dest=./ssh.cfg + delegate_to: localhost + # Initialize testapi database - hosts: localhost tasks: diff --git a/tests/unit/ansible_library/modules/apex_generate_inventory_test.py b/tests/unit/ansible_library/modules/apex_generate_inventory_test.py new file mode 100644 index 00000000..7df9d35c --- /dev/null +++ b/tests/unit/ansible_library/modules/apex_generate_inventory_test.py @@ -0,0 +1,30 @@ +############################################################### +# Copyright (c) 2017 ZTE Corporation +# +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Apache License, Version 2.0 +# which accompanies this distribution, and is available at +# http://www.apache.org/licenses/LICENSE-2.0 +############################################################################## + +import json +import os + +from qtip.ansible_library.modules import apex_generate_inventory + + +def test_generate_inventory(data_root): + baremetal_info = json.load(open(os.path.join(data_root, 'external', + 'apex', 'baremetal_info.json'))) + server_info = json.load(open(os.path.join(data_root, 'external', + 'apex', 'server_info.json'))) + inventory = apex_generate_inventory.generate_inventory(baremetal_info, server_info) + assert dict(inventory['hosts']) == { + u'compute': [u'192.0.2.5', u'192.0.2.6'], + u'control': [u'192.0.2.7', u'192.0.2.8', u'192.0.2.9']} + assert dict(inventory['hosts_meta']) == { + u'192.0.2.5': {'ansible_ssh_host': u'192.0.2.5'}, + u'192.0.2.6': {'ansible_ssh_host': u'192.0.2.6'}, + u'192.0.2.7': {'ansible_ssh_host': u'192.0.2.7'}, + u'192.0.2.8': {'ansible_ssh_host': u'192.0.2.8'}, + u'192.0.2.9': {'ansible_ssh_host': u'192.0.2.9'}} diff --git a/tests/unit/ansible_library/modules/apex_test.py b/tests/unit/ansible_library/modules/apex_test.py deleted file mode 100644 index 8a1d0673..00000000 --- a/tests/unit/ansible_library/modules/apex_test.py +++ /dev/null @@ -1,30 +0,0 @@ -############################################################### -# Copyright (c) 2017 ZTE Corporation -# -# All rights reserved. This program and the accompanying materials -# are made available under the terms of the Apache License, Version 2.0 -# which accompanies this distribution, and is available at -# http://www.apache.org/licenses/LICENSE-2.0 -############################################################################## - -import json -import os - -from qtip.ansible_library.modules import apex - - -def test_generate_inventory(data_root): - baremetal_info = json.load(open(os.path.join(data_root, 'external', - 'apex', 'baremetal_info.json'))) - server_info = json.load(open(os.path.join(data_root, 'external', - 'apex', 'server_info.json'))) - inventory = apex.generate_inventory(baremetal_info, server_info) - assert dict(inventory['hosts']) == { - u'compute': [u'192.0.2.5', u'192.0.2.6'], - u'control': [u'192.0.2.7', u'192.0.2.8', u'192.0.2.9']} - assert dict(inventory['hosts_meta']) == { - u'192.0.2.5': {'ansible_ssh_host': u'192.0.2.5'}, - u'192.0.2.6': {'ansible_ssh_host': u'192.0.2.6'}, - u'192.0.2.7': {'ansible_ssh_host': u'192.0.2.7'}, - u'192.0.2.8': {'ansible_ssh_host': u'192.0.2.8'}, - u'192.0.2.9': {'ansible_ssh_host': u'192.0.2.9'}} -- cgit 1.2.3-korg