From 8a59c00f051af12f10d9681be3e3603c1b354549 Mon Sep 17 00:00:00 2001 From: Alvaro Aleman Date: Thu, 12 Jan 2017 20:36:18 +0100 Subject: [PATCH] Make ansible.cfg settings configurable (#643) * Make ansible.cfg defaults section configurable * Disable retry_files by default * Add docs for ansiblecfg_defaults * Make ansible.cfg ssh_connection section configurable * Add docs for ansiblecfg_ssh_connection --- doc/source/configuration.rst | 8 ++++++++ molecule/ansible_playbook.py | 5 ++++- molecule/config.py | 4 ++++ .../cookiecutter/molecule/cookiecutter.json | 2 ++ .../{{cookiecutter.repo_name}}/ansible.cfg | 4 ++++ molecule/core.py | 20 +++++++++++++++++++ 6 files changed, 42 insertions(+), 1 deletion(-) diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst index 7f6c205bc..87b00bb8f 100644 --- a/doc/source/configuration.rst +++ b/doc/source/configuration.rst @@ -71,11 +71,19 @@ variables. There are only a few currently in use. - -o ControlPersist=60s raw_env_vars: ANSIBLE_ACTION_PLUGINS: ../plugins + ansiblecfg_defaults: + retry_files_enabled: False + ansiblecfg_ssh_connection: + pipelining: True The `raw_env_vars` section allows you to pass arbitrary environment variables to ``ansible-playbook``. This can be useful, for example, if you want to do a role level override of a value normally found in ``ansible.cfg``. +The `ansiblecfg_defaults` and `ansiblecfg_ssh_connection`` sections both take +arbitrary key value pairs. Those key value pairs will then be written to the +`defaults` and `ssh_connection` section of ``ansible.cfg``, respectively. + Host/Group Vars ^^^^^^^^^^^^^^^ diff --git a/molecule/ansible_playbook.py b/molecule/ansible_playbook.py index 3a0d3aa8c..2c72ce628 100644 --- a/molecule/ansible_playbook.py +++ b/molecule/ansible_playbook.py @@ -116,7 +116,10 @@ def parse_arg(self, name, value): self._playbook = value return - if name == 'host_vars' or name == 'group_vars': + if name in [ + 'host_vars', 'group_vars', 'ansiblecfg_defaults', + 'ansiblecfg_ssh_connection' + ]: return # verbose is weird, must be -vvvv not verbose=vvvv diff --git a/molecule/config.py b/molecule/config.py index 71b0925f5..f5cd2bb49 100644 --- a/molecule/config.py +++ b/molecule/config.py @@ -111,6 +111,10 @@ def _get_defaults(self): 'become': True, 'become_user': False, 'config_file': 'ansible.cfg', + 'ansiblecfg_defaults': { + 'retry_files_enabled': False, + }, + 'ansiblecfg_ssh_connection': {}, 'diff': True, 'host_key_checking': False, 'inventory_file': 'ansible_inventory', diff --git a/molecule/cookiecutter/molecule/cookiecutter.json b/molecule/cookiecutter/molecule/cookiecutter.json index bd7ede99c..1e3c135d8 100644 --- a/molecule/cookiecutter/molecule/cookiecutter.json +++ b/molecule/cookiecutter/molecule/cookiecutter.json @@ -3,6 +3,8 @@ "ansiblecfg_molecule_dir": "OVERRIDEN", "ansiblecfg_ansible_library_path": "OVERRIDEN", "ansiblecfg_ansible_managed": "Ansible managed: Do NOT edit this file manually!", + "ansiblecfg_defaults": "OVERRIDDEN", + "ansiblecfg_ssh_connection": "OVERRIDDEN", "rakefile_state_file": "OVERRIDEN", "rakefile_serverspec_dir": "OVERRIDEN" } diff --git a/molecule/cookiecutter/molecule/{{cookiecutter.repo_name}}/ansible.cfg b/molecule/cookiecutter/molecule/{{cookiecutter.repo_name}}/ansible.cfg index 13894b5f5..ce0fee3f1 100644 --- a/molecule/cookiecutter/molecule/{{cookiecutter.repo_name}}/ansible.cfg +++ b/molecule/cookiecutter/molecule/{{cookiecutter.repo_name}}/ansible.cfg @@ -5,3 +5,7 @@ roles_path = {{ cookiecutter.ansiblecfg_molecule_dir }}/roles:{{ cookiecutter.ansiblecfg_molecule_dir }}/../roles:../:../../ library = {{ cookiecutter.ansiblecfg_ansible_library_path }} ansible_managed = {{ cookiecutter.ansiblecfg_ansible_managed }} +{{- cookiecutter.ansiblecfg_defaults }} + +[ssh_connection] +{{- cookiecutter.ansiblecfg_ssh_connection }} diff --git a/molecule/core.py b/molecule/core.py index 2c8b41c20..3f2ae29fa 100644 --- a/molecule/core.py +++ b/molecule/core.py @@ -372,9 +372,27 @@ def _get_disabled(self): # Ability to turn off features until we roll them out. return self.config.config.get('_disabled', []) + def _dict_to_inisection_string(self, data, padding=15): + result = '' + for key, value in data.iteritems(): + result += '\n%s = %s' % (key.ljust(padding), value) + + return result + def _get_cookiecutter_context(self, molecule_dir): state_file = self.config.config['molecule']['state_file'] serverspec_dir = self.config.config['molecule']['serverspec_dir'] + ansiblecfg_defaults = self.config.config['ansible'][ + 'ansiblecfg_defaults'] + ansiblecfg_ssh_connection = self.config.config['ansible'][ + 'ansiblecfg_ssh_connection'] + + # This is required because cookiecutter apparently casts all of its + # context to str, thus we can not do any looping in the template + ansiblecfg_defaults_string = self._dict_to_inisection_string( + ansiblecfg_defaults) + ansiblecfg_ssh_connection_string = self._dict_to_inisection_string( + ansiblecfg_ssh_connection) return { 'repo_name': molecule_dir, @@ -382,4 +400,6 @@ def _get_cookiecutter_context(self, molecule_dir): 'ansiblecfg_ansible_library_path': 'library', 'rakefile_state_file': state_file, 'rakefile_serverspec_dir': serverspec_dir, + 'ansiblecfg_defaults': ansiblecfg_defaults_string, + 'ansiblecfg_ssh_connection': ansiblecfg_ssh_connection_string }