mirror of
https://github.com/ansible-collections/community.general.git
synced 2025-08-03 20:54:24 -07:00
added docs to CLI docstringsadded
removed 'now intermediate build files' from repo adjusted gitignore
This commit is contained in:
parent
424e1946f4
commit
18a7a1ec31
21 changed files with 269 additions and 1803 deletions
|
@ -93,7 +93,7 @@ class InvalidOptsParser(SortedOptParser):
|
|||
class CLI(with_metaclass(ABCMeta, object)):
|
||||
''' code behind bin/ansible* programs '''
|
||||
|
||||
VALID_ACTIONS = ['No Actions']
|
||||
VALID_ACTIONS = []
|
||||
|
||||
_ITALIC = re.compile(r"I\(([^)]+)\)")
|
||||
_BOLD = re.compile(r"B\(([^)]+)\)")
|
||||
|
@ -283,7 +283,8 @@ class CLI(with_metaclass(ABCMeta, object)):
|
|||
|
||||
@staticmethod
|
||||
def base_parser(usage="", output_opts=False, runas_opts=False, meta_opts=False, runtask_opts=False, vault_opts=False, module_opts=False,
|
||||
async_opts=False, connect_opts=False, subset_opts=False, check_opts=False, inventory_opts=False, epilog=None, fork_opts=False, runas_prompt_opts=False, desc=None):
|
||||
async_opts=False, connect_opts=False, subset_opts=False, check_opts=False, inventory_opts=False, epilog=None, fork_opts=False,
|
||||
runas_prompt_opts=False, desc=None):
|
||||
''' create an options parser for most ansible scripts '''
|
||||
|
||||
# base opts
|
||||
|
@ -665,51 +666,3 @@ class CLI(with_metaclass(ABCMeta, object)):
|
|||
data = data.split(os.pathsep)[0]
|
||||
return data
|
||||
|
||||
def _opt_doc_list(self, action=None):
|
||||
''' generate options docs '''
|
||||
|
||||
if action:
|
||||
self.args.append(action)
|
||||
self.set_action()
|
||||
|
||||
results = []
|
||||
for opt in self.parser.option_list:
|
||||
res = {
|
||||
'desc': opt.help,
|
||||
'options': opt._short_opts + opt._long_opts
|
||||
}
|
||||
if opt.action == 'store':
|
||||
res['arg'] = opt.dest.upper()
|
||||
results.append(res)
|
||||
|
||||
return results
|
||||
|
||||
def opts_docs(self, args=None):
|
||||
''' generate doc structure from options '''
|
||||
|
||||
# cli name
|
||||
name = os.path.basename(sys.argv[0])
|
||||
if '-' in name:
|
||||
name = name.split('-')[1]
|
||||
else:
|
||||
name = 'adhoc'
|
||||
|
||||
# cli info
|
||||
docs = {
|
||||
'cli': name,
|
||||
'usage': self.parser.usage,
|
||||
'short_desc': self.parser.description
|
||||
}
|
||||
|
||||
if self.VALID_ACTIONS:
|
||||
myopts = []
|
||||
for action in self.VALID_ACTIONS:
|
||||
newopts = self._opt_doc_list(action)
|
||||
for nopt in newopts:
|
||||
if nopt not in myopts:
|
||||
myopts.append(nopt)
|
||||
docs['options'] = myopts
|
||||
else:
|
||||
docs['options'] = self._opt_doc_list()
|
||||
|
||||
return docs
|
||||
|
|
|
@ -46,7 +46,9 @@ except ImportError:
|
|||
########################################################
|
||||
|
||||
class AdHocCLI(CLI):
|
||||
''' Ad-hoc Ansible allows you to define and run a single task 'playbook' against a set of hosts '''
|
||||
''' is an extra-simple tool/framework/API for doing 'remote things'.
|
||||
this command allows you to define and run a single task 'playbook' against a set of hosts
|
||||
'''
|
||||
|
||||
def parse(self):
|
||||
''' create an options parser for bin/ansible '''
|
||||
|
|
|
@ -58,8 +58,13 @@ except ImportError:
|
|||
|
||||
|
||||
class ConsoleCLI(CLI, cmd.Cmd):
|
||||
''' a REPL that allows for running ad-hoc tasks against a chosen inventory (based on dominis' ansible-shell).'''
|
||||
|
||||
modules = []
|
||||
ARGUMENTS = {
|
||||
'host-pattern': 'A name of a group in the inventory, a shell-like glob '
|
||||
'selecting hosts in inventory or any combination of the two separated by commas.',
|
||||
}
|
||||
|
||||
def __init__(self, args):
|
||||
|
||||
|
|
|
@ -40,7 +40,10 @@ except ImportError:
|
|||
|
||||
|
||||
class DocCLI(CLI):
|
||||
""" Doc command line class """
|
||||
''' displays information on modules installed in Ansible libraries.
|
||||
It displays a terse listing of plugins and their short descriptions,
|
||||
provides a printout of their DOCUMENTATION strings,
|
||||
and it can create a short "snippet" which can be pasted into a playbook. '''
|
||||
|
||||
def __init__(self, args):
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ except ImportError:
|
|||
|
||||
|
||||
class GalaxyCLI(CLI):
|
||||
'''command to manage Ansible roles in shared repostories, the default of which is Ansible Galaxy *https://galaxy.ansible.com*.'''
|
||||
|
||||
SKIP_INFO_KEYS = ("name", "description", "readme_html", "related", "summary_fields", "average_aw_composite", "average_aw_score", "url" )
|
||||
VALID_ACTIONS = ("delete", "import", "info", "init", "install", "list", "login", "remove", "search", "setup")
|
||||
|
@ -59,20 +60,10 @@ class GalaxyCLI(CLI):
|
|||
self.galaxy = None
|
||||
super(GalaxyCLI, self).__init__(args)
|
||||
|
||||
def parse(self):
|
||||
''' create an options parser for bin/ansible '''
|
||||
def set_action(self):
|
||||
|
||||
self.parser = CLI.base_parser(
|
||||
usage = "usage: %%prog [%s] [--help] [options] ..." % "|".join(self.VALID_ACTIONS),
|
||||
epilog = "\nSee '%s <command> --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0])
|
||||
)
|
||||
super(GalaxyCLI, self).set_action()
|
||||
|
||||
self.set_action()
|
||||
|
||||
# common
|
||||
self.parser.add_option('-s', '--server', dest='api_server', default=C.GALAXY_SERVER, help='The API server destination')
|
||||
self.parser.add_option('-c', '--ignore-certs', action='store_true', dest='ignore_certs', default=C.GALAXY_IGNORE_CERTS,
|
||||
help='Ignore SSL certificate validation errors.')
|
||||
|
||||
# specific to actions
|
||||
if self.action == "delete":
|
||||
|
@ -135,6 +126,20 @@ class GalaxyCLI(CLI):
|
|||
if self.action in ("init","install"):
|
||||
self.parser.add_option('-f', '--force', dest='force', action='store_true', default=False, help='Force overwriting an existing role')
|
||||
|
||||
def parse(self):
|
||||
''' create an options parser for bin/ansible '''
|
||||
|
||||
self.parser = CLI.base_parser(
|
||||
usage = "usage: %%prog [%s] [--help] [options] ..." % "|".join(self.VALID_ACTIONS),
|
||||
epilog = "\nSee '%s <command> --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0])
|
||||
)
|
||||
|
||||
# common
|
||||
self.parser.add_option('-s', '--server', dest='api_server', default=C.GALAXY_SERVER, help='The API server destination')
|
||||
self.parser.add_option('-c', '--ignore-certs', action='store_true', dest='ignore_certs', default=C.GALAXY_IGNORE_CERTS,
|
||||
help='Ignore SSL certificate validation errors.')
|
||||
self.set_action()
|
||||
|
||||
super(GalaxyCLI, self).parse()
|
||||
|
||||
display.verbosity = self.options.verbosity
|
||||
|
@ -182,8 +187,7 @@ class GalaxyCLI(CLI):
|
|||
|
||||
def execute_init(self):
|
||||
"""
|
||||
Executes the init action, which creates the skeleton framework
|
||||
of a role that complies with the galaxy metadata format.
|
||||
creates the skeleton framework of a role that complies with the galaxy metadata format.
|
||||
"""
|
||||
|
||||
init_path = self.get_opt('init_path', './')
|
||||
|
@ -255,9 +259,7 @@ class GalaxyCLI(CLI):
|
|||
|
||||
def execute_info(self):
|
||||
"""
|
||||
Executes the info action. This action prints out detailed
|
||||
information about an installed role as well as info available
|
||||
from the galaxy API.
|
||||
prints out detailed information about an installed role as well as info available from the galaxy API.
|
||||
"""
|
||||
|
||||
if len(self.args) == 0:
|
||||
|
@ -304,10 +306,8 @@ class GalaxyCLI(CLI):
|
|||
|
||||
def execute_install(self):
|
||||
"""
|
||||
Executes the installation action. The args list contains the
|
||||
roles to be installed, unless -f was specified. The list of roles
|
||||
can be a name (which will be downloaded via the galaxy API and github),
|
||||
or it can be a local .tar.gz file.
|
||||
uses the args list of roles to be installed, unless -f was specified. The list of roles
|
||||
can be a name (which will be downloaded via the galaxy API and github), or it can be a local .tar.gz file.
|
||||
"""
|
||||
|
||||
role_file = self.get_opt("role_file", None)
|
||||
|
@ -432,8 +432,7 @@ class GalaxyCLI(CLI):
|
|||
|
||||
def execute_remove(self):
|
||||
"""
|
||||
Executes the remove action. The args list contains the list
|
||||
of roles to be removed. This list can contain more than one role.
|
||||
removes the list of roles passed as arguments from the local system.
|
||||
"""
|
||||
|
||||
if len(self.args) == 0:
|
||||
|
@ -453,10 +452,7 @@ class GalaxyCLI(CLI):
|
|||
|
||||
def execute_list(self):
|
||||
"""
|
||||
Executes the list action. The args list can contain zero
|
||||
or one role. If one is specified, only that role will be
|
||||
shown, otherwise all roles in the specified directory will
|
||||
be shown.
|
||||
lists the roles installed on the local system or matches a single role passed as an argument.
|
||||
"""
|
||||
|
||||
if len(self.args) > 1:
|
||||
|
@ -500,6 +496,7 @@ class GalaxyCLI(CLI):
|
|||
return 0
|
||||
|
||||
def execute_search(self):
|
||||
''' searches for roles on the Ansible Galaxy server'''
|
||||
page_size = 1000
|
||||
search = None
|
||||
|
||||
|
@ -544,7 +541,7 @@ class GalaxyCLI(CLI):
|
|||
|
||||
def execute_login(self):
|
||||
"""
|
||||
Verify user's identify via Github and retrieve an auth token from Galaxy.
|
||||
verify user's identify via Github and retrieve an auth token from Ansible Galaxy.
|
||||
"""
|
||||
# Authenticate with github and retrieve a token
|
||||
if self.options.token is None:
|
||||
|
@ -567,9 +564,7 @@ class GalaxyCLI(CLI):
|
|||
return 0
|
||||
|
||||
def execute_import(self):
|
||||
"""
|
||||
Import a role into Galaxy
|
||||
"""
|
||||
""" used to import a role into Ansible Galaxy """
|
||||
|
||||
colors = {
|
||||
'INFO': 'normal',
|
||||
|
@ -625,9 +620,7 @@ class GalaxyCLI(CLI):
|
|||
return 0
|
||||
|
||||
def execute_setup(self):
|
||||
"""
|
||||
Setup an integration from Github or Travis
|
||||
"""
|
||||
""" Setup an integration from Github or Travis for Ansible Galaxy roles"""
|
||||
|
||||
if self.options.setup_list:
|
||||
# List existing integration secrets
|
||||
|
@ -664,9 +657,7 @@ class GalaxyCLI(CLI):
|
|||
return 0
|
||||
|
||||
def execute_delete(self):
|
||||
"""
|
||||
Delete a role from galaxy.ansible.com
|
||||
"""
|
||||
""" Delete a role from Ansible Galaxy. """
|
||||
|
||||
if len(self.args) < 2:
|
||||
raise AnsibleError("Missing one or more arguments. Expected: github_user github_repo")
|
||||
|
|
|
@ -44,7 +44,9 @@ except ImportError:
|
|||
#---------------------------------------------------------------------------------------------------
|
||||
|
||||
class PlaybookCLI(CLI):
|
||||
''' code behind ansible playbook cli'''
|
||||
''' the tool to run *Ansible playbooks*, which are a configuration and multinode deployment system.
|
||||
See the project home page (https://docs.ansible.com) for more information. '''
|
||||
|
||||
|
||||
def parse(self):
|
||||
|
||||
|
|
|
@ -44,7 +44,16 @@ except ImportError:
|
|||
########################################################
|
||||
|
||||
class PullCLI(CLI):
|
||||
''' code behind ansible ad-hoc cli'''
|
||||
''' is used to up a remote copy of ansible on each managed node,
|
||||
each set to run via cron and update playbook source via a source repository.
|
||||
This inverts the default *push* architecture of ansible into a *pull* architecture,
|
||||
which has near-limitless scaling potential.
|
||||
|
||||
The setup playbook can be tuned to change the cron frequency, logging locations, and parameters to ansible-pull.
|
||||
This is useful both for extreme scale-out as well as periodic remediation.
|
||||
Usage of the 'fetch' module to retrieve logs from ansible-pull runs would be an
|
||||
excellent way to gather and analyze remote logs from ansible-pull.
|
||||
'''
|
||||
|
||||
DEFAULT_REPO_TYPE = 'git'
|
||||
DEFAULT_PLAYBOOK = 'local.yml'
|
||||
|
@ -53,12 +62,18 @@ class PullCLI(CLI):
|
|||
2: 'File is not readable'
|
||||
}
|
||||
SUPPORTED_REPO_MODULES = ['git']
|
||||
ARGUMENTS = {
|
||||
'playbook.yml': 'The name of one the YAML format files to run as an Ansible playbook.'
|
||||
'This can be a relative path within the checkout. By default, Ansible will'
|
||||
"look for a playbook based on the host's fully-qualified domain name,"
|
||||
'on the host hostname and finally a playbook named *local.yml*.',
|
||||
}
|
||||
|
||||
def parse(self):
|
||||
''' create an options parser for bin/ansible '''
|
||||
|
||||
self.parser = CLI.base_parser(
|
||||
usage='%prog -U <repository> [options]',
|
||||
usage='%prog -U <repository> [options] [<playbook.yml>]',
|
||||
connect_opts=True,
|
||||
vault_opts=True,
|
||||
runtask_opts=True,
|
||||
|
@ -70,22 +85,18 @@ class PullCLI(CLI):
|
|||
)
|
||||
|
||||
# options unique to pull
|
||||
self.parser.add_option('--purge', default=False, action='store_true',
|
||||
help='purge checkout after playbook run')
|
||||
self.parser.add_option('--purge', default=False, action='store_true', help='purge checkout after playbook run')
|
||||
self.parser.add_option('-o', '--only-if-changed', dest='ifchanged', default=False, action='store_true',
|
||||
help='only run the playbook if the repository has been updated')
|
||||
self.parser.add_option('-s', '--sleep', dest='sleep', default=None,
|
||||
help='sleep for random interval (between 0 and n number of seconds) before starting. This is a useful way to disperse git requests')
|
||||
self.parser.add_option('-f', '--force', dest='force', default=False, action='store_true',
|
||||
help='run the playbook even if the repository could not be updated')
|
||||
self.parser.add_option('-d', '--directory', dest='dest', default=None,
|
||||
help='directory to checkout repository to')
|
||||
self.parser.add_option('-U', '--url', dest='url', default=None,
|
||||
help='URL of the playbook repository')
|
||||
self.parser.add_option('--full', dest='fullclone', action='store_true',
|
||||
help='Do a full clone, instead of a shallow one.')
|
||||
self.parser.add_option('-d', '--directory', dest='dest', default=None, help='directory to checkout repository to')
|
||||
self.parser.add_option('-U', '--url', dest='url', default=None, help='URL of the playbook repository')
|
||||
self.parser.add_option('--full', dest='fullclone', action='store_true', help='Do a full clone, instead of a shallow one.')
|
||||
self.parser.add_option('-C', '--checkout', dest='checkout',
|
||||
help='branch/tag/commit to checkout. ' 'Defaults to behavior of repository module.')
|
||||
help='branch/tag/commit to checkout. Defaults to behavior of repository module.')
|
||||
self.parser.add_option('--accept-host-key', default=False, dest='accept_host_key', action='store_true',
|
||||
help='adds the hostkey for the repo url if not already added')
|
||||
self.parser.add_option('-m', '--module-name', dest='module_name', default=self.DEFAULT_REPO_TYPE,
|
||||
|
@ -96,8 +107,7 @@ class PullCLI(CLI):
|
|||
self.parser.add_option('--clean', dest='clean', default=False, action='store_true',
|
||||
help='modified files in the working repository will be discarded')
|
||||
self.parser.add_option('--track-subs', dest='tracksubs', default=False, action='store_true',
|
||||
help='submodules will track the latest changes'
|
||||
' This is equivalent to specifying the --remote flag to git submodule update')
|
||||
help='submodules will track the latest changes. This is equivalent to specifying the --remote flag to git submodule update')
|
||||
|
||||
# for pull we don't wan't a default
|
||||
self.parser.set_defaults(inventory=None)
|
||||
|
|
|
@ -36,7 +36,17 @@ except ImportError:
|
|||
|
||||
|
||||
class VaultCLI(CLI):
|
||||
""" Vault command line class """
|
||||
''' can encrypt any structured data file used by Ansible.
|
||||
This can include *group_vars/* or *host_vars/* inventory variables,
|
||||
variables loaded by *include_vars* or *vars_files*, or variable files
|
||||
passed on the ansible-playbook command line with *-e @file.yml* or *-e @file.json*.
|
||||
Role variables and defaults are also included!
|
||||
|
||||
Because Ansible tasks, handlers, and so on are also data, these can also be encrypted with vault.
|
||||
If you'd like to not betray what variables you are even using, you can go as far to keep an individual task file entirely encrypted.
|
||||
|
||||
The password used with vault currently must be the same for all files you wish to use together at the same time.
|
||||
'''
|
||||
|
||||
VALID_ACTIONS = ("create", "decrypt", "edit", "encrypt", "encrypt_string", "rekey", "view")
|
||||
|
||||
|
@ -51,16 +61,9 @@ class VaultCLI(CLI):
|
|||
self.encrypt_string_read_stdin = False
|
||||
super(VaultCLI, self).__init__(args)
|
||||
|
||||
def parse(self):
|
||||
def set_action(self):
|
||||
|
||||
self.parser = CLI.base_parser(
|
||||
vault_opts=True,
|
||||
usage = "usage: %%prog [%s] [options] [vaultfile.yml]" % "|".join(self.VALID_ACTIONS),
|
||||
desc = "encryption/decryption utility for Ansbile data files",
|
||||
epilog = "\nSee '%s <command> --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0])
|
||||
)
|
||||
|
||||
self.set_action()
|
||||
super(VaultCLI, self).set_action()
|
||||
|
||||
# options specific to self.actions
|
||||
if self.action == "create":
|
||||
|
@ -88,6 +91,17 @@ class VaultCLI(CLI):
|
|||
elif self.action == "rekey":
|
||||
self.parser.set_usage("usage: %prog rekey [options] file_name")
|
||||
|
||||
def parse(self):
|
||||
|
||||
self.parser = CLI.base_parser(
|
||||
vault_opts=True,
|
||||
usage = "usage: %%prog [%s] [options] [vaultfile.yml]" % "|".join(self.VALID_ACTIONS),
|
||||
desc = "encryption/decryption utility for Ansbile data files",
|
||||
epilog = "\nSee '%s <command> --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0])
|
||||
)
|
||||
|
||||
self.set_action()
|
||||
|
||||
super(VaultCLI, self).parse()
|
||||
|
||||
display.verbosity = self.options.verbosity
|
||||
|
@ -162,6 +176,7 @@ class VaultCLI(CLI):
|
|||
os.umask(old_umask)
|
||||
|
||||
def execute_encrypt(self):
|
||||
''' encrypt the supplied file using the provided vault secret '''
|
||||
|
||||
if len(self.args) == 0 and sys.stdin.isatty():
|
||||
display.display("Reading plaintext input from stdin", stderr=True)
|
||||
|
@ -191,6 +206,7 @@ class VaultCLI(CLI):
|
|||
return yaml_ciphertext
|
||||
|
||||
def execute_encrypt_string(self):
|
||||
''' encrypt the supplied string using the provided vault secret '''
|
||||
b_plaintext = None
|
||||
|
||||
# Holds tuples (the_text, the_source_of_the_string, the variable name if its provided).
|
||||
|
@ -314,6 +330,7 @@ class VaultCLI(CLI):
|
|||
return output
|
||||
|
||||
def execute_decrypt(self):
|
||||
''' decrypt the supplied file using the provided vault secret '''
|
||||
|
||||
if len(self.args) == 0 and sys.stdin.isatty():
|
||||
display.display("Reading ciphertext input from stdin", stderr=True)
|
||||
|
@ -325,6 +342,7 @@ class VaultCLI(CLI):
|
|||
display.display("Decryption successful", stderr=True)
|
||||
|
||||
def execute_create(self):
|
||||
''' create and open a file in an editor that will be encryped with the provided vault secret when closed'''
|
||||
|
||||
if len(self.args) > 1:
|
||||
raise AnsibleOptionsError("ansible-vault create can take only one filename argument")
|
||||
|
@ -332,10 +350,12 @@ class VaultCLI(CLI):
|
|||
self.editor.create_file(self.args[0])
|
||||
|
||||
def execute_edit(self):
|
||||
''' open and decrypt an existing vaulted file in an editor, that will be encryped again when closed'''
|
||||
for f in self.args:
|
||||
self.editor.edit_file(f)
|
||||
|
||||
def execute_view(self):
|
||||
''' open, decrypt and view an existing vaulted file using a pager using the supplied vault secret '''
|
||||
|
||||
for f in self.args:
|
||||
# Note: vault should return byte strings because it could encrypt
|
||||
|
@ -346,6 +366,7 @@ class VaultCLI(CLI):
|
|||
self.pager(to_text(self.editor.plaintext(f)))
|
||||
|
||||
def execute_rekey(self):
|
||||
''' re-encrypt a vaulted file with a new secret, the previous secret is required '''
|
||||
for f in self.args:
|
||||
if not (os.path.isfile(f)):
|
||||
raise AnsibleError(f + " does not exist")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue