Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PR #7456/c2f08c57 backport][stable-8] [ssh_config] Add support for ControlMaster #7510

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelogs/fragments/7456-add-ssh-control-master.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
minor_changes:
- ssh_config - adds ``controlmaster``, ``controlpath`` and ``controlpersist`` parameters (https://github.com/ansible-collections/community.general/pull/7456).
46 changes: 40 additions & 6 deletions plugins/modules/ssh_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,22 @@
- Sets the C(HostKeyAlgorithms) option.
type: str
version_added: 6.1.0
controlmaster:
description:
- Sets the C(ControlMaster) option.
choices: [ 'yes', 'no', 'ask', 'auto', 'autoask' ]
type: str
version_added: 8.1.0
controlpath:
description:
- Sets the C(ControlPath) option.
type: str
version_added: 8.1.0
controlpersist:
description:
- Sets the C(ControlPersist) option.
type: str
version_added: 8.1.0
requirements:
- paramiko
'''
Expand Down Expand Up @@ -177,6 +193,22 @@
from ansible_collections.community.general.plugins.module_utils.ssh import determine_config_file


def convert_bool(value):
if value is True:
return 'yes'
if value is False:
return 'no'
return None


def fix_bool_str(value):
if value == 'True':
return 'yes'
if value == 'False':
return 'no'
return value


class SSHConfig(object):
def __init__(self, module):
self.module = module
Expand Down Expand Up @@ -219,14 +251,12 @@ def ensure_state(self):
proxycommand=self.params.get('proxycommand'),
proxyjump=self.params.get('proxyjump'),
host_key_algorithms=self.params.get('host_key_algorithms'),
forward_agent=convert_bool(self.params.get('forward_agent')),
controlmaster=self.params.get('controlmaster'),
controlpath=self.params.get('controlpath'),
controlpersist=fix_bool_str(self.params.get('controlpersist')),
)

# Convert True / False to 'yes' / 'no' for usage in ssh_config
if self.params['forward_agent'] is True:
args['forward_agent'] = 'yes'
if self.params['forward_agent'] is False:
args['forward_agent'] = 'no'

config_changed = False
hosts_changed = []
hosts_change_diff = []
Expand Down Expand Up @@ -320,9 +350,13 @@ def main():
ssh_config_file=dict(default=None, type='path'),
state=dict(type='str', default='present', choices=['present', 'absent']),
strict_host_key_checking=dict(
type='str',
default=None,
choices=['yes', 'no', 'ask']
),
controlmaster=dict(type='str', default=None, choices=['yes', 'no', 'ask', 'auto', 'autoask']),
controlpath=dict(type='str', default=None),
controlpersist=dict(type='str', default=None),
user=dict(default=None, type='str'),
user_known_hosts_file=dict(type='str', default=None),
),
Expand Down
54 changes: 54 additions & 0 deletions tests/integration/targets/ssh_config/tasks/options.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
proxycommand: "ssh jumphost.example.com -W %h:%p"
forward_agent: true
host_key_algorithms: "+ssh-rsa"
controlmaster: "auto"
controlpath: "~/.ssh/sockets/%r@%h-%p"
controlpersist: yes
state: present
register: options_add
check_mode: true
Expand Down Expand Up @@ -45,6 +48,9 @@
proxycommand: "ssh jumphost.example.com -W %h:%p"
forward_agent: true
host_key_algorithms: "+ssh-rsa"
controlmaster: "auto"
controlpath: "~/.ssh/sockets/%r@%h-%p"
controlpersist: yes
state: present
register: options_add

Expand All @@ -63,6 +69,9 @@
proxycommand: "ssh jumphost.example.com -W %h:%p"
forward_agent: true
host_key_algorithms: "+ssh-rsa"
controlmaster: "auto"
controlpath: "~/.ssh/sockets/%r@%h-%p"
controlpersist: yes
state: present
register: options_add_again

Expand All @@ -85,6 +94,9 @@
- "'proxycommand ssh jumphost.example.com -W %h:%p' in slurp_ssh_config['content'] | b64decode"
- "'forwardagent yes' in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-rsa' in slurp_ssh_config['content'] | b64decode"
- "'controlmaster auto' 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"

- name: Options - Update host
community.general.ssh_config:
Expand All @@ -93,6 +105,9 @@
proxycommand: "ssh new-jumphost.example.com -W %h:%p"
forward_agent: false
host_key_algorithms: "+ssh-ed25519"
controlmaster: no
controlpath: "~/.ssh/new-sockets/%r@%h-%p"
controlpersist: "600"
state: present
register: options_update

Expand All @@ -113,6 +128,9 @@
proxycommand: "ssh new-jumphost.example.com -W %h:%p"
forward_agent: false
host_key_algorithms: "+ssh-ed25519"
controlmaster: no
controlpath: "~/.ssh/new-sockets/%r@%h-%p"
controlpersist: "600"
state: present
register: options_update

Expand All @@ -136,6 +154,9 @@
- "'proxycommand ssh new-jumphost.example.com -W %h:%p' in slurp_ssh_config['content'] | b64decode"
- "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
- "'controlmaster no' 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"

- name: Options - Ensure no update in case option exist in ssh_config file but wasn't defined in playbook
community.general.ssh_config:
Expand Down Expand Up @@ -164,6 +185,9 @@
- "'proxycommand ssh new-jumphost.example.com -W %h:%p' in slurp_ssh_config['content'] | b64decode"
- "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
- "'controlmaster no' 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"

- name: Debug
debug:
Expand Down Expand Up @@ -210,6 +234,9 @@
- "'proxycommand ssh new-jumphost.example.com -W %h:%p' not in slurp_ssh_config['content'] | b64decode"
- "'forwardagent no' not in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-ed25519' not in slurp_ssh_config['content'] | b64decode"
- "'controlmaster auto' 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"

# Proxycommand and ProxyJump are mutually exclusive.
# Reset ssh_config before testing options with proxyjump
Expand All @@ -226,6 +253,9 @@
proxyjump: "jumphost.example.com"
forward_agent: true
host_key_algorithms: "+ssh-rsa"
controlmaster: "auto"
controlpath: "~/.ssh/sockets/%r@%h-%p"
controlpersist: yes
state: present
register: options_add
check_mode: true
Expand Down Expand Up @@ -255,6 +285,9 @@
proxyjump: "jumphost.example.com"
forward_agent: true
host_key_algorithms: "+ssh-rsa"
controlmaster: "auto"
controlpath: "~/.ssh/sockets/%r@%h-%p"
controlpersist: yes
state: present
register: options_add

Expand All @@ -273,6 +306,9 @@
proxyjump: "jumphost.example.com"
forward_agent: true
host_key_algorithms: "+ssh-rsa"
controlmaster: "auto"
controlpath: "~/.ssh/sockets/%r@%h-%p"
controlpersist: yes
state: present
register: options_add_again

Expand All @@ -295,6 +331,9 @@
- "'proxyjump jumphost.example.com' in slurp_ssh_config['content'] | b64decode"
- "'forwardagent yes' in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-rsa' in slurp_ssh_config['content'] | b64decode"
- "'controlmaster auto' 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"

- name: Options - Update host
community.general.ssh_config:
Expand All @@ -303,6 +342,9 @@
proxyjump: "new-jumphost.example.com"
forward_agent: false
host_key_algorithms: "+ssh-ed25519"
controlmaster: no
controlpath: "~/.ssh/new-sockets/%r@%h-%p"
controlpersist: "600"
state: present
register: options_update

Expand All @@ -323,6 +365,9 @@
proxyjump: "new-jumphost.example.com"
forward_agent: false
host_key_algorithms: "+ssh-ed25519"
controlmaster: no
controlpath: "~/.ssh/new-sockets/%r@%h-%p"
controlpersist: "600"
state: present
register: options_update

Expand All @@ -346,6 +391,9 @@
- "'proxyjump new-jumphost.example.com' in slurp_ssh_config['content'] | b64decode"
- "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
- "'controlmaster no' 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"

- name: Options - Ensure no update in case option exist in ssh_config file but wasn't defined in playbook
community.general.ssh_config:
Expand Down Expand Up @@ -374,6 +422,9 @@
- "'proxyjump new-jumphost.example.com' in slurp_ssh_config['content'] | b64decode"
- "'forwardagent no' in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-ed25519' in slurp_ssh_config['content'] | b64decode"
- "'controlmaster no' 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"

- name: Debug
debug:
Expand Down Expand Up @@ -420,3 +471,6 @@
- "'proxyjump new-jumphost.example.com' not in slurp_ssh_config['content'] | b64decode"
- "'forwardagent no' not in slurp_ssh_config['content'] | b64decode"
- "'hostkeyalgorithms +ssh-ed25519' not in slurp_ssh_config['content'] | b64decode"
- "'controlmaster auto' 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"