Ssh config other options (#9684)
* Add other_options support to ssh_config module * Changelog fragment * Fix missing and modified stuff * Minor changes * Update fragment with PR URL * Fix PEP8 issue * Fix idempotency issue * Update changelogs/fragments/ssh_config_add_other_options.yml Co-authored-by: Felix Fontein <felix@fontein.de> * Update plugins/modules/ssh_config.py Co-authored-by: Felix Fontein <felix@fontein.de> * Update plugins/modules/ssh_config.py Co-authored-by: Felix Fontein <felix@fontein.de> * Incorporate suggestions * Missed removing str conversion * PEP8 * Update plugins/modules/ssh_config.py Co-authored-by: Felix Fontein <felix@fontein.de> * Add fail condition, fix codestyle * Force lower case key values only --------- Co-authored-by: Felix Fontein <felix@fontein.de>pull/9735/merge
parent
bb2c45b5bb
commit
961c9b7f4c
|
@ -0,0 +1,2 @@
|
||||||
|
minor_changes:
|
||||||
|
- ssh_config - add ``other_options`` option (https://github.com/ansible-collections/community.general/issues/8053, https://github.com/ansible-collections/community.general/pull/9684).
|
|
@ -139,6 +139,13 @@ options:
|
||||||
- Sets the C(DynamicForward) option.
|
- Sets the C(DynamicForward) option.
|
||||||
type: str
|
type: str
|
||||||
version_added: 10.1.0
|
version_added: 10.1.0
|
||||||
|
other_options:
|
||||||
|
description:
|
||||||
|
- Provides the option to specify arbitrary SSH config entry options via a dictionary.
|
||||||
|
- The key names must be lower case. Keys with upper case values are rejected.
|
||||||
|
- The values must be strings. Other values are rejected.
|
||||||
|
type: dict
|
||||||
|
version_added: 10.4.0
|
||||||
requirements:
|
requirements:
|
||||||
- paramiko
|
- paramiko
|
||||||
"""
|
"""
|
||||||
|
@ -152,6 +159,8 @@ EXAMPLES = r"""
|
||||||
identity_file: "/home/akasurde/.ssh/id_rsa"
|
identity_file: "/home/akasurde/.ssh/id_rsa"
|
||||||
port: '2223'
|
port: '2223'
|
||||||
state: present
|
state: present
|
||||||
|
other_options:
|
||||||
|
serveraliveinterval: '30'
|
||||||
|
|
||||||
- name: Delete a host from the configuration
|
- name: Delete a host from the configuration
|
||||||
community.general.ssh_config:
|
community.general.ssh_config:
|
||||||
|
@ -204,6 +213,7 @@ from copy import deepcopy
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
from ansible.module_utils.basic import AnsibleModule, missing_required_lib
|
||||||
from ansible.module_utils.common.text.converters import to_native
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
|
from ansible.module_utils.six import string_types
|
||||||
from ansible_collections.community.general.plugins.module_utils._stormssh import ConfigParser, HAS_PARAMIKO, PARAMIKO_IMPORT_ERROR
|
from ansible_collections.community.general.plugins.module_utils._stormssh import ConfigParser, HAS_PARAMIKO, PARAMIKO_IMPORT_ERROR
|
||||||
from ansible_collections.community.general.plugins.module_utils.ssh import determine_config_file
|
from ansible_collections.community.general.plugins.module_utils.ssh import determine_config_file
|
||||||
|
|
||||||
|
@ -274,6 +284,17 @@ class SSHConfig(object):
|
||||||
controlpersist=fix_bool_str(self.params.get('controlpersist')),
|
controlpersist=fix_bool_str(self.params.get('controlpersist')),
|
||||||
dynamicforward=self.params.get('dynamicforward'),
|
dynamicforward=self.params.get('dynamicforward'),
|
||||||
)
|
)
|
||||||
|
if self.params.get('other_options'):
|
||||||
|
for key, value in self.params.get('other_options').items():
|
||||||
|
if key.lower() != key:
|
||||||
|
self.module.fail_json(msg="The other_options key {key!r} must be lower case".format(key=key))
|
||||||
|
if key not in args:
|
||||||
|
if not isinstance(value, string_types):
|
||||||
|
self.module.fail_json(msg="The other_options value provided for key {key!r} must be a string, got {type}".format(key=key,
|
||||||
|
type=type(value)))
|
||||||
|
args[key] = value
|
||||||
|
else:
|
||||||
|
self.module.fail_json(msg="Multiple values provided for key {key!r}".format(key=key))
|
||||||
|
|
||||||
config_changed = False
|
config_changed = False
|
||||||
hosts_changed = []
|
hosts_changed = []
|
||||||
|
@ -361,6 +382,7 @@ def main():
|
||||||
host_key_algorithms=dict(type='str', no_log=False),
|
host_key_algorithms=dict(type='str', no_log=False),
|
||||||
identity_file=dict(type='path'),
|
identity_file=dict(type='path'),
|
||||||
identities_only=dict(type='bool'),
|
identities_only=dict(type='bool'),
|
||||||
|
other_options=dict(type='dict'),
|
||||||
port=dict(type='str'),
|
port=dict(type='str'),
|
||||||
proxycommand=dict(type='str', default=None),
|
proxycommand=dict(type='str', default=None),
|
||||||
proxyjump=dict(type='str', default=None),
|
proxyjump=dict(type='str', default=None),
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
controlpath: "~/.ssh/sockets/%r@%h-%p"
|
controlpath: "~/.ssh/sockets/%r@%h-%p"
|
||||||
controlpersist: yes
|
controlpersist: yes
|
||||||
dynamicforward: '10080'
|
dynamicforward: '10080'
|
||||||
|
other_options:
|
||||||
|
serveraliveinterval: '30'
|
||||||
state: present
|
state: present
|
||||||
register: options_add
|
register: options_add
|
||||||
check_mode: true
|
check_mode: true
|
||||||
|
@ -57,6 +59,8 @@
|
||||||
controlpath: "~/.ssh/sockets/%r@%h-%p"
|
controlpath: "~/.ssh/sockets/%r@%h-%p"
|
||||||
controlpersist: yes
|
controlpersist: yes
|
||||||
dynamicforward: '10080'
|
dynamicforward: '10080'
|
||||||
|
other_options:
|
||||||
|
serveraliveinterval: '30'
|
||||||
state: present
|
state: present
|
||||||
register: options_add
|
register: options_add
|
||||||
|
|
||||||
|
@ -81,6 +85,8 @@
|
||||||
controlpath: "~/.ssh/sockets/%r@%h-%p"
|
controlpath: "~/.ssh/sockets/%r@%h-%p"
|
||||||
controlpersist: yes
|
controlpersist: yes
|
||||||
dynamicforward: '10080'
|
dynamicforward: '10080'
|
||||||
|
other_options:
|
||||||
|
serveraliveinterval: '30'
|
||||||
state: present
|
state: present
|
||||||
register: options_add_again
|
register: options_add_again
|
||||||
|
|
||||||
|
@ -109,6 +115,7 @@
|
||||||
- "'controlpath ~/.ssh/sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
|
- "'controlpath ~/.ssh/sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'controlpersist yes' in slurp_ssh_config['content'] | b64decode"
|
- "'controlpersist yes' in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'dynamicforward 10080' in slurp_ssh_config['content'] | b64decode"
|
- "'dynamicforward 10080' in slurp_ssh_config['content'] | b64decode"
|
||||||
|
- "'serveraliveinterval 30' in slurp_ssh_config['content'] | b64decode"
|
||||||
|
|
||||||
- name: Options - Update host
|
- name: Options - Update host
|
||||||
community.general.ssh_config:
|
community.general.ssh_config:
|
||||||
|
@ -123,6 +130,8 @@
|
||||||
controlpath: "~/.ssh/new-sockets/%r@%h-%p"
|
controlpath: "~/.ssh/new-sockets/%r@%h-%p"
|
||||||
controlpersist: "600"
|
controlpersist: "600"
|
||||||
dynamicforward: '11080'
|
dynamicforward: '11080'
|
||||||
|
other_options:
|
||||||
|
serveraliveinterval: '30'
|
||||||
state: present
|
state: present
|
||||||
register: options_update
|
register: options_update
|
||||||
|
|
||||||
|
@ -149,6 +158,8 @@
|
||||||
controlpath: "~/.ssh/new-sockets/%r@%h-%p"
|
controlpath: "~/.ssh/new-sockets/%r@%h-%p"
|
||||||
controlpersist: "600"
|
controlpersist: "600"
|
||||||
dynamicforward: '11080'
|
dynamicforward: '11080'
|
||||||
|
other_options:
|
||||||
|
serveraliveinterval: '30'
|
||||||
state: present
|
state: present
|
||||||
register: options_update
|
register: options_update
|
||||||
|
|
||||||
|
@ -178,6 +189,7 @@
|
||||||
- "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
|
- "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'controlpersist 600' in slurp_ssh_config['content'] | b64decode"
|
- "'controlpersist 600' in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'dynamicforward 11080' in slurp_ssh_config['content'] | b64decode"
|
- "'dynamicforward 11080' in slurp_ssh_config['content'] | b64decode"
|
||||||
|
- "'serveraliveinterval 30' in slurp_ssh_config['content'] | b64decode"
|
||||||
|
|
||||||
- name: Options - Ensure no update in case option exist in ssh_config file but wasn't defined in playbook
|
- name: Options - Ensure no update in case option exist in ssh_config file but wasn't defined in playbook
|
||||||
community.general.ssh_config:
|
community.general.ssh_config:
|
||||||
|
@ -212,6 +224,7 @@
|
||||||
- "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
|
- "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'controlpersist 600' in slurp_ssh_config['content'] | b64decode"
|
- "'controlpersist 600' in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'dynamicforward 11080' in slurp_ssh_config['content'] | b64decode"
|
- "'dynamicforward 11080' in slurp_ssh_config['content'] | b64decode"
|
||||||
|
- "'serveraliveinterval 30' in slurp_ssh_config['content'] | b64decode"
|
||||||
|
|
||||||
- name: Debug
|
- name: Debug
|
||||||
debug:
|
debug:
|
||||||
|
@ -264,6 +277,7 @@
|
||||||
- "'controlpath ~/.ssh/sockets/%r@%h-%p' not in slurp_ssh_config['content'] | b64decode"
|
- "'controlpath ~/.ssh/sockets/%r@%h-%p' not in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'controlpersist yes' not in slurp_ssh_config['content'] | b64decode"
|
- "'controlpersist yes' not in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'dynamicforward 10080' not in slurp_ssh_config['content'] | b64decode"
|
- "'dynamicforward 10080' not in slurp_ssh_config['content'] | b64decode"
|
||||||
|
- "'serveraliveinterval 30' not in slurp_ssh_config['content'] | b64decode"
|
||||||
|
|
||||||
# Proxycommand and ProxyJump are mutually exclusive.
|
# Proxycommand and ProxyJump are mutually exclusive.
|
||||||
# Reset ssh_config before testing options with proxyjump
|
# Reset ssh_config before testing options with proxyjump
|
||||||
|
@ -286,6 +300,8 @@
|
||||||
controlpath: "~/.ssh/sockets/%r@%h-%p"
|
controlpath: "~/.ssh/sockets/%r@%h-%p"
|
||||||
controlpersist: yes
|
controlpersist: yes
|
||||||
dynamicforward: '10080'
|
dynamicforward: '10080'
|
||||||
|
other_options:
|
||||||
|
serveraliveinterval: '30'
|
||||||
state: present
|
state: present
|
||||||
register: options_add
|
register: options_add
|
||||||
check_mode: true
|
check_mode: true
|
||||||
|
@ -321,6 +337,8 @@
|
||||||
controlpath: "~/.ssh/sockets/%r@%h-%p"
|
controlpath: "~/.ssh/sockets/%r@%h-%p"
|
||||||
controlpersist: yes
|
controlpersist: yes
|
||||||
dynamicforward: '10080'
|
dynamicforward: '10080'
|
||||||
|
other_options:
|
||||||
|
serveraliveinterval: '30'
|
||||||
state: present
|
state: present
|
||||||
register: options_add
|
register: options_add
|
||||||
|
|
||||||
|
@ -345,6 +363,8 @@
|
||||||
controlpath: "~/.ssh/sockets/%r@%h-%p"
|
controlpath: "~/.ssh/sockets/%r@%h-%p"
|
||||||
controlpersist: yes
|
controlpersist: yes
|
||||||
dynamicforward: '10080'
|
dynamicforward: '10080'
|
||||||
|
other_options:
|
||||||
|
serveraliveinterval: '30'
|
||||||
state: present
|
state: present
|
||||||
register: options_add_again
|
register: options_add_again
|
||||||
|
|
||||||
|
@ -373,6 +393,7 @@
|
||||||
- "'controlpath ~/.ssh/sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
|
- "'controlpath ~/.ssh/sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'controlpersist yes' in slurp_ssh_config['content'] | b64decode"
|
- "'controlpersist yes' in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'dynamicforward 10080' in slurp_ssh_config['content'] | b64decode"
|
- "'dynamicforward 10080' in slurp_ssh_config['content'] | b64decode"
|
||||||
|
- "'serveraliveinterval 30' in slurp_ssh_config['content'] | b64decode"
|
||||||
|
|
||||||
- name: Options - Update host
|
- name: Options - Update host
|
||||||
community.general.ssh_config:
|
community.general.ssh_config:
|
||||||
|
@ -387,6 +408,8 @@
|
||||||
controlpath: "~/.ssh/new-sockets/%r@%h-%p"
|
controlpath: "~/.ssh/new-sockets/%r@%h-%p"
|
||||||
controlpersist: "600"
|
controlpersist: "600"
|
||||||
dynamicforward: '11080'
|
dynamicforward: '11080'
|
||||||
|
other_options:
|
||||||
|
serveraliveinterval: '30'
|
||||||
state: present
|
state: present
|
||||||
register: options_update
|
register: options_update
|
||||||
|
|
||||||
|
@ -413,6 +436,8 @@
|
||||||
controlpath: "~/.ssh/new-sockets/%r@%h-%p"
|
controlpath: "~/.ssh/new-sockets/%r@%h-%p"
|
||||||
controlpersist: "600"
|
controlpersist: "600"
|
||||||
dynamicforward: '11080'
|
dynamicforward: '11080'
|
||||||
|
other_options:
|
||||||
|
serveraliveinterval: '30'
|
||||||
state: present
|
state: present
|
||||||
register: options_update
|
register: options_update
|
||||||
|
|
||||||
|
@ -442,6 +467,7 @@
|
||||||
- "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
|
- "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'controlpersist 600' in slurp_ssh_config['content'] | b64decode"
|
- "'controlpersist 600' in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'dynamicforward 11080' in slurp_ssh_config['content'] | b64decode"
|
- "'dynamicforward 11080' in slurp_ssh_config['content'] | b64decode"
|
||||||
|
- "'serveraliveinterval 30' in slurp_ssh_config['content'] | b64decode"
|
||||||
|
|
||||||
- name: Options - Ensure no update in case option exist in ssh_config file but wasn't defined in playbook
|
- name: Options - Ensure no update in case option exist in ssh_config file but wasn't defined in playbook
|
||||||
community.general.ssh_config:
|
community.general.ssh_config:
|
||||||
|
@ -476,6 +502,7 @@
|
||||||
- "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
|
- "'controlpath ~/.ssh/new-sockets/%r@%h-%p' in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'controlpersist 600' in slurp_ssh_config['content'] | b64decode"
|
- "'controlpersist 600' in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'dynamicforward 11080' in slurp_ssh_config['content'] | b64decode"
|
- "'dynamicforward 11080' in slurp_ssh_config['content'] | b64decode"
|
||||||
|
- "'serveraliveinterval 30' in slurp_ssh_config['content'] | b64decode"
|
||||||
|
|
||||||
- name: Debug
|
- name: Debug
|
||||||
debug:
|
debug:
|
||||||
|
@ -528,3 +555,4 @@
|
||||||
- "'controlpath ~/.ssh/sockets/%r@%h-%p' not in slurp_ssh_config['content'] | b64decode"
|
- "'controlpath ~/.ssh/sockets/%r@%h-%p' not in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'controlpersist yes' not in slurp_ssh_config['content'] | b64decode"
|
- "'controlpersist yes' not in slurp_ssh_config['content'] | b64decode"
|
||||||
- "'dynamicforward 10080' not in slurp_ssh_config['content'] | b64decode"
|
- "'dynamicforward 10080' not in slurp_ssh_config['content'] | b64decode"
|
||||||
|
- "'serveraliveinterval 30' not in slurp_ssh_config['content'] | b64decode"
|
||||||
|
|
Loading…
Reference in New Issue