Skip to content

Commit

Permalink
ansible-test - More flexible become support.
Browse files Browse the repository at this point in the history
  • Loading branch information
mattclay committed Jun 18, 2022
1 parent 717f178 commit 5666c6d
Show file tree
Hide file tree
Showing 7 changed files with 51 additions and 23 deletions.
2 changes: 2 additions & 0 deletions changelogs/fragments/ansible-test-generalize-become.yml
@@ -0,0 +1,2 @@
minor_changes:
- ansible-test - Become support for remote instance provisioning is no longer tied to a fixed list of platforms.
26 changes: 13 additions & 13 deletions test/lib/ansible_test/_data/completion/remote.txt
@@ -1,13 +1,13 @@
freebsd/12.3 python=3.8 python_dir=/usr/local/bin provider=aws arch=x86_64
freebsd/13.0 python=3.7,3.8,3.9 python_dir=/usr/local/bin provider=aws arch=x86_64
freebsd/13.1 python=3.8,3.7,3.9,3.10 python_dir=/usr/local/bin provider=aws arch=x86_64
freebsd python_dir=/usr/local/bin provider=aws arch=x86_64
macos/12.0 python=3.10 python_dir=/usr/local/bin provider=parallels arch=x86_64
macos python_dir=/usr/local/bin provider=parallels arch=x86_64
rhel/7.9 python=2.7 provider=aws arch=x86_64
rhel/8.5 python=3.6,3.8,3.9 provider=aws arch=x86_64
rhel/8.6 python=3.6,3.8,3.9 provider=aws arch=x86_64
rhel/9.0 python=3.9 provider=aws arch=x86_64
rhel provider=aws arch=x86_64
ubuntu/22.04 python=3.10 provider=aws arch=x86_64
ubuntu provider=aws arch=x86_64
freebsd/12.3 python=3.8 python_dir=/usr/local/bin become=su provider=aws arch=x86_64
freebsd/13.0 python=3.7,3.8,3.9 python_dir=/usr/local/bin become=su provider=aws arch=x86_64
freebsd/13.1 python=3.8,3.7,3.9,3.10 python_dir=/usr/local/bin become=su provider=aws arch=x86_64
freebsd python_dir=/usr/local/bin become=su provider=aws arch=x86_64
macos/12.0 python=3.10 python_dir=/usr/local/bin become=sudo provider=parallels arch=x86_64
macos python_dir=/usr/local/bin become=sudo provider=parallels arch=x86_64
rhel/7.9 python=2.7 become=sudo provider=aws arch=x86_64
rhel/8.5 python=3.6,3.8,3.9 become=sudo provider=aws arch=x86_64
rhel/8.6 python=3.6,3.8,3.9 become=sudo provider=aws arch=x86_64
rhel/9.0 python=3.9 become=sudo provider=aws arch=x86_64
rhel become=sudo provider=aws arch=x86_64
ubuntu/22.04 python=3.10 become=sudo provider=aws arch=x86_64
ubuntu become=sudo provider=aws arch=x86_64
7 changes: 7 additions & 0 deletions test/lib/ansible_test/_internal/become.py
Expand Up @@ -5,6 +5,10 @@
import shlex
import typing as t

from .util import (
get_subclasses,
)


class Become(metaclass=abc.ABCMeta):
"""Base class for become implementations."""
Expand Down Expand Up @@ -50,3 +54,6 @@ def prepare_command(self, command): # type: (t.List[str]) -> t.List[str]
become.extend(['sh', '-c', ' '.join(shlex.quote(c) for c in command)])

return become


SUPPORTED_BECOME_METHODS = {cls.__name__.lower(): cls for cls in get_subclasses(Become)}
Expand Up @@ -18,6 +18,10 @@
OriginConfig,
)

from ...become import (
SUPPORTED_BECOME_METHODS,
)

from ..argparsing.parsers import (
AnyParser,
BooleanParser,
Expand Down Expand Up @@ -129,6 +133,7 @@ def __init__(self, name, controller):
def get_parsers(self, state): # type: (ParserState) -> t.Dict[str, Parser]
"""Return a dictionary of key names and value parsers."""
return dict(
become=ChoicesParser(list(SUPPORTED_BECOME_METHODS)),
provider=ChoicesParser(REMOTE_PROVIDERS),
arch=ChoicesParser(REMOTE_ARCHITECTURES),
python=PythonParser(versions=self.versions, allow_venv=False, allow_default=self.allow_default),
Expand All @@ -141,6 +146,7 @@ def document(self, state): # type: (DocumentationState) -> t.Optional[str]
section_name = 'remote options'

state.sections[f'{"controller" if self.controller else "target"} {section_name} (comma separated):'] = '\n'.join([
f' become={ChoicesParser(list(SUPPORTED_BECOME_METHODS)).document(state)}',
f' provider={ChoicesParser(REMOTE_PROVIDERS).document(state)}',
f' arch={ChoicesParser(REMOTE_ARCHITECTURES).document(state)}',
f' python={python_parser.document(state)}',
Expand Down
8 changes: 8 additions & 0 deletions test/lib/ansible_test/_internal/completion.py
Expand Up @@ -21,6 +21,10 @@
data_context,
)

from .become import (
SUPPORTED_BECOME_METHODS,
)


@dataclasses.dataclass(frozen=True)
class CompletionConfig(metaclass=abc.ABCMeta):
Expand Down Expand Up @@ -166,12 +170,16 @@ def __post_init__(self):
@dataclasses.dataclass(frozen=True)
class PosixRemoteCompletionConfig(RemoteCompletionConfig, PythonCompletionConfig):
"""Configuration for remote POSIX platforms."""
become: t.Optional[str] = None
placeholder: bool = False

def __post_init__(self):
if not self.placeholder:
super().__post_init__()

if self.become and self.become not in SUPPORTED_BECOME_METHODS:
raise Exception(f'POSIX remote completion entry "{self.name}" setting "become" must be omitted or one of: {", ".join(SUPPORTED_BECOME_METHODS)}')

if not self.supported_pythons:
if self.version and not self.placeholder:
raise Exception(f'POSIX remote completion entry "{self.name}" must provide a "python" setting.')
Expand Down
10 changes: 10 additions & 0 deletions test/lib/ansible_test/_internal/host_configs.py
Expand Up @@ -333,6 +333,8 @@ def have_root(self): # type: () -> bool
@dataclasses.dataclass
class PosixRemoteConfig(RemoteConfig, ControllerHostConfig, PosixConfig):
"""Configuration for a POSIX remote host."""
become: t.Optional[str] = None

def get_defaults(self, context): # type: (HostContext) -> PosixRemoteCompletionConfig
"""Return the default settings."""
return filter_completion(remote_completion()).get(self.name) or remote_completion().get(self.platform) or PosixRemoteCompletionConfig(
Expand All @@ -350,6 +352,14 @@ def get_default_targets(self, context): # type: (HostContext) -> t.List[Control

return [ControllerConfig(python=NativePythonConfig(version=version, path=path)) for version, path in pythons.items()]

def apply_defaults(self, context, defaults): # type: (HostContext, CompletionConfig) -> None
"""Apply default settings."""
assert isinstance(defaults, PosixRemoteCompletionConfig)

super().apply_defaults(context, defaults)

self.become = self.become or defaults.become

@property
def have_root(self): # type: () -> bool
"""True if root is available, otherwise False."""
Expand Down
15 changes: 5 additions & 10 deletions test/lib/ansible_test/_internal/host_profiles.py
Expand Up @@ -99,7 +99,7 @@

from .become import (
Become,
Su,
SUPPORTED_BECOME_METHODS,
Sudo,
)

Expand Down Expand Up @@ -573,16 +573,11 @@ def get_ssh_connection(self): # type: () -> SshConnection

if settings.user == 'root':
become = None # type: t.Optional[Become]
elif self.config.platform == 'freebsd':
become = Su()
elif self.config.platform == 'macos':
become = Sudo()
elif self.config.platform == 'rhel':
become = Sudo()
elif self.config.platform == 'ubuntu':
become = Sudo()
elif self.config.become:
become = SUPPORTED_BECOME_METHODS[self.config.become]()
else:
raise NotImplementedError(f'Become support has not been implemented for platform "{self.config.platform}" and user "{settings.user}" is not root.')
display.warning(f'Defaulting to "sudo" for platform "{self.config.platform}" become support.', unique=True)
become = Sudo()

return SshConnection(self.args, settings, become)

Expand Down

0 comments on commit 5666c6d

Please sign in to comment.