added docs to CLI docstringsadded

removed 'now intermediate build files' from repo
adjusted gitignore
This commit is contained in:
Brian Coca 2017-03-23 01:11:40 -04:00 committed by Brian Coca
commit 18a7a1ec31
21 changed files with 269 additions and 1803 deletions

View file

@ -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

View file

@ -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 '''

View file

@ -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):

View file

@ -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):

View file

@ -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")

View file

@ -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):

View file

@ -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)

View file

@ -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")