Skip to content

Commit

Permalink
Port molecule v1 host/group vars handling (#712)
Browse files Browse the repository at this point in the history
Fixes: #693
  • Loading branch information
retr0h committed Jan 12, 2017
1 parent 0420108 commit 4a820cc
Show file tree
Hide file tree
Showing 12 changed files with 211 additions and 0 deletions.
2 changes: 2 additions & 0 deletions molecule/config.py
Expand Up @@ -152,6 +152,8 @@ def _get_defaults(self):
'name': 'ansible',
'config_options': {},
'options': {},
'host_vars': {},
'group_vars': {},
},
'scenario': {
'name': 'default',
Expand Down
36 changes: 36 additions & 0 deletions molecule/provisioner/ansible.py
Expand Up @@ -103,6 +103,14 @@ def options(self):
self.default_options,
self._config.config['provisioner']['options'])

@property
def host_vars(self):
return self._config.config['provisioner']['host_vars']

@property
def group_vars(self):
return self._config.config['provisioner']['group_vars']

@property
def inventory(self):
# ungrouped:
Expand Down Expand Up @@ -196,6 +204,32 @@ def write_config(self):
template = template.render(config_options=self.config_options)
util.write_file(self.config_file, template)

def _add_or_update_vars(self, target):
"""
Creates host and/or group vars and returns None.
:param target: A string containing either `host_vars` or `group_vars`.
:returns: None
"""
if target == 'host_vars':
vars_target = self.host_vars
elif target == 'group_vars':
vars_target = self.group_vars

if not vars_target:
return

ephemeral_directory = self._config.ephemeral_directory
target_vars_directory = os.path.join(ephemeral_directory, target)

if not os.path.isdir(os.path.abspath(target_vars_directory)):
os.mkdir(os.path.abspath(target_vars_directory))

for target in vars_target.keys():
target_var_content = vars_target[target][0]
path = os.path.join(os.path.abspath(target_vars_directory), target)
util.write_file(path, util.safe_dump(target_var_content))

def _get_ansible_playbook(self, playbook, **kwargs):
"""
Get an instance of AnsiblePlaybook and returns it.
Expand All @@ -216,6 +250,8 @@ def _setup(self):
"""
self.write_inventory()
self.write_config()
self._add_or_update_vars('host_vars')
self._add_or_update_vars('group_vars')

def _verify_inventory(self):
"""
Expand Down
6 changes: 6 additions & 0 deletions test/functional/test_docker.py
Expand Up @@ -124,6 +124,12 @@ def test_command_test(with_scenario):
sh.molecule('test')


@pytest.mark.parametrize(
'with_scenario', ['host_group_vars'], indirect=['with_scenario'])
def test_command_test_with_host_group_vars(with_scenario):
sh.molecule('test')


@pytest.mark.parametrize(
'with_scenario', ['docker'], indirect=['with_scenario'])
def test_command_verify(with_scenario):
Expand Down
3 changes: 3 additions & 0 deletions test/scenarios/host_group_vars/molecule/default/Dockerfile
@@ -0,0 +1,3 @@
FROM centos:7

RUN yum makecache fast && yum update -y && yum install -y python sudo yum-plugin-ovl && sed -i 's/plugins=0/plugins=1/g' /etc/yum.conf
27 changes: 27 additions & 0 deletions test/scenarios/host_group_vars/molecule/default/create.yml
@@ -0,0 +1,27 @@
---
- hosts: localhost
connection: local
vars:
molecule_yml: "{{ lookup('file','molecule.yml') | from_yaml }}"
tasks:
- name: Build an Ansible compatible image
docker_image:
path: .
name: molecule_local/centos:7

# - name: Pull CentOS image
# docker_image:
# name: centos:7
# tag: latest

- name: Create molecule instance(s)
docker_container:
name: "{{ item.name | instance_with_scenario_name(molecule_yml.scenario.name) }}"
hostname: "{{ item.name }}"
image: molecule_local/centos:7
state: started
recreate: no
log_driver: syslog
command: sleep infinity

with_items: "{{ molecule_yml.platforms }}"
11 changes: 11 additions & 0 deletions test/scenarios/host_group_vars/molecule/default/destroy.yml
@@ -0,0 +1,11 @@
---
- hosts: localhost
connection: local
vars:
molecule_yml: "{{ lookup('file','molecule.yml') | from_yaml }}"
tasks:
- name: Destroy molecule instance(s)
docker_container:
name: "{{ item.name | instance_with_scenario_name(molecule_yml.scenario.name) }}"
state: absent
with_items: "{{ molecule_yml.platforms }}"
@@ -0,0 +1,2 @@
---
host_group_vars_group_vars_dir: True
@@ -0,0 +1,2 @@
---
host_group_vars_host_vars_dir: True
24 changes: 24 additions & 0 deletions test/scenarios/host_group_vars/molecule/default/molecule.yml
@@ -0,0 +1,24 @@
---
dependency:
name: galaxy
driver:
name: docker
lint:
name: ansible-lint
platforms:
- name: host-group-vars
groups:
- example
provisioner:
name: ansible
host_vars:
# TODO(retr0h): We may wish to handle the scenario_name appended.
host-group-vars-default:
- host_group_vars_host_molecule_yml: True
group_vars:
example:
- host_group_vars_example_group_molecule_yml: True
scenario:
name: default
verifier:
name: testinfra
23 changes: 23 additions & 0 deletions test/scenarios/host_group_vars/molecule/default/playbook.yml
@@ -0,0 +1,23 @@
---
- hosts: all
tasks:
- name: Host vars host_var for host host-group-vars from molecule.yml
command: echo "{{ host_group_vars_host_molecule_yml }}"
changed_when: False

- name: Host vars from host_vars existing directory
command: echo "{{ host_group_vars_host_vars_dir }}"
changed_when: False

- name: Group vars group_var for group example from molecule.yml
command: echo "{{ host_group_vars_example_group_molecule_yml }}"
changed_when: False

- name: Group vars from group_vars existing directory
command: echo "{{ host_group_vars_group_vars_dir }}"
changed_when: False

# TODO(retr0h): Implement children functionality.
# - name: Group host vars scenario test example2:children group vars from molecule.yml
# command: echo "{{ group_host_vars_example2_group_molecule_yml }}"
# changed_when: False
2 changes: 2 additions & 0 deletions test/scenarios/host_group_vars/tasks/main.yml
@@ -0,0 +1,2 @@
---
# tasks file for docker
73 changes: 73 additions & 0 deletions test/unit/provisioner/test_ansible.py
Expand Up @@ -39,6 +39,19 @@ def ansible_data():
},
'options': {
'foo': 'bar'
},
'host_vars': {
'instance-1-default': [{
'foo': 'bar'
}],
},
'group_vars': {
'example_group1': [{
'foo': 'bar'
}],
'example_group2': [{
'foo': 'bar'
}],
}
}
}
Expand Down Expand Up @@ -97,6 +110,25 @@ def test_options_property_handles_cli_args(molecule_file, platforms_data,
assert p.options['debug']


def test_host_vars_property(ansible_instance):
x = {'instance-1-default': [{'foo': 'bar'}]}

assert x == ansible_instance.host_vars


def test_group_vars_property(ansible_instance):
x = {
'example_group1': [{
'foo': 'bar'
}],
'example_group2': [{
'foo': 'bar'
}]
}

assert x == ansible_instance.group_vars


def test_inventory_property(ansible_instance):
x = {
'bar': {
Expand Down Expand Up @@ -162,6 +194,42 @@ def test_config_file_property(ansible_instance):
assert x == ansible_instance.config_file


def test_add_or_update_vars(ansible_instance):
ephemeral_directory = ansible_instance._config.ephemeral_directory

host_vars_directory = os.path.join(ephemeral_directory, 'host_vars')
host_vars = os.path.join(host_vars_directory, 'instance-1-default')

ansible_instance._add_or_update_vars('host_vars')
assert os.path.isdir(host_vars_directory)
assert os.path.isfile(host_vars)

group_vars_directory = os.path.join(ephemeral_directory, 'group_vars')
group_vars_1 = os.path.join(group_vars_directory, 'example_group1')
group_vars_2 = os.path.join(group_vars_directory, 'example_group2')

ansible_instance._add_or_update_vars('group_vars')
assert os.path.isdir(group_vars_directory)
assert os.path.isfile(group_vars_1)
assert os.path.isfile(group_vars_2)


def test_add_or_update_vars_does_not_create_vars(platforms_data,
molecule_file):
c = config.Config(molecule_file, configs=[platforms_data])
a = ansible.Ansible(c)
ephemeral_directory = c.ephemeral_directory

host_vars_directory = os.path.join(ephemeral_directory, 'host_vars')
group_vars_directory = os.path.join(ephemeral_directory, 'group_vars')

a._add_or_update_vars('host_vars')
a._add_or_update_vars('group_vars')

assert not os.path.isdir(host_vars_directory)
assert not os.path.isdir(group_vars_directory)


def test_init_calls_setup(mocker, molecule_file, platforms_data, ansible_data):
m = mocker.patch('molecule.provisioner.ansible.Ansible._setup')
c = config.Config(
Expand Down Expand Up @@ -254,13 +322,18 @@ def test_setup(mocker, temp_dir, ansible_instance):
'molecule.provisioner.ansible.Ansible.write_inventory')
patched_provisioner_write_config = mocker.patch(
'molecule.provisioner.ansible.Ansible.write_config')
patched_provisioner_add_or_update_vars = mocker.patch(
'molecule.provisioner.ansible.Ansible._add_or_update_vars')
ansible_instance._setup()

assert os.path.isdir(os.path.dirname(ansible_instance.inventory_file))

patched_provisioner_write_inventory.assert_called_once_with()
patched_provisioner_write_config.assert_called_once_with()

x = [mocker.call('host_vars'), mocker.call('group_vars')]
assert x == patched_provisioner_add_or_update_vars.mock_calls


def test_verify_inventory(ansible_instance):
ansible_instance._verify_inventory()
Expand Down

0 comments on commit 4a820cc

Please sign in to comment.