Exemplo n.º 1
0
    def init_parser(self):

        super(ConfigCLI, self).init_parser(
            desc="View ansible configuration.",
        )

        common = opt_help.argparse.ArgumentParser(add_help=False)
        opt_help.add_verbosity_options(common)
        common.add_argument('-c', '--config', dest='config_file',
                            help="path to configuration file, defaults to first file found in precedence.")
        common.add_argument("-t", "--type", action="store", default='base', dest='type', choices=['all', 'base'] + list(C.CONFIGURABLE_PLUGINS),
                            help="Filter down to a specific plugin type.")
        common.add_argument('args', help='Specific plugin to target, requires type of plugin to be set', nargs='*')

        subparsers = self.parser.add_subparsers(dest='action')
        subparsers.required = True

        list_parser = subparsers.add_parser('list', help='Print all config options', parents=[common])
        list_parser.set_defaults(func=self.execute_list)

        dump_parser = subparsers.add_parser('dump', help='Dump configuration', parents=[common])
        dump_parser.set_defaults(func=self.execute_dump)
        dump_parser.add_argument('--only-changed', '--changed-only', dest='only_changed', action='store_true',
                                 help="Only show configurations that have changed from the default")

        view_parser = subparsers.add_parser('view', help='View configuration file', parents=[common])
        view_parser.set_defaults(func=self.execute_view)

        init_parser = subparsers.add_parser('init', help='Create initial configuration', parents=[common])
        init_parser.set_defaults(func=self.execute_init)
        init_parser.add_argument('--format', '-f', dest='format', action='store', choices=['ini', 'env', 'vars'], default='ini',
                                 help='Output format for init')
        init_parser.add_argument('--disabled', dest='commented', action='store_true', default=False,
                                 help='Prefixes all entries with a comment character to disable them')
Exemplo n.º 2
0
    def init_parser(self):

        super(ConfigCLI, self).init_parser(
            desc="View ansible configuration.",
        )

        common = opt_help.argparse.ArgumentParser(add_help=False)
        opt_help.add_verbosity_options(common)
        common.add_argument('-c', '--config', dest='config_file',
                            help="path to configuration file, defaults to first file found in precedence.")
        common.add_argument("-t", "--type", action="store", default='base', dest='type', choices=['all', 'base'] + list(C.CONFIGURABLE_PLUGINS),
                            help="Show configuration for a plugin type, for a specific plugin's options see ansible-doc.")

        subparsers = self.parser.add_subparsers(dest='action')
        subparsers.required = True

        list_parser = subparsers.add_parser('list', help='Print all config options', parents=[common])
        list_parser.set_defaults(func=self.execute_list)

        dump_parser = subparsers.add_parser('dump', help='Dump configuration', parents=[common])
        dump_parser.set_defaults(func=self.execute_dump)
        dump_parser.add_argument('--only-changed', '--changed-only', dest='only_changed', action='store_true',
                                 help="Only show configurations that have changed from the default")

        view_parser = subparsers.add_parser('view', help='View configuration file', parents=[common])
        view_parser.set_defaults(func=self.execute_view)
Exemplo n.º 3
0
    def init_parser(self):

        super(ConfigCLI,
              self).init_parser(desc="View ansible configuration.", )

        common = opt_help.argparse.ArgumentParser(add_help=False)
        opt_help.add_verbosity_options(common)
        common.add_argument(
            '-c',
            '--config',
            dest='config_file',
            help=
            "path to configuration file, defaults to first file found in precedence."
        )

        subparsers = self.parser.add_subparsers(dest='action')
        subparsers.required = True

        list_parser = subparsers.add_parser('list',
                                            help='Print all config options',
                                            parents=[common])
        list_parser.set_defaults(func=self.execute_list)

        dump_parser = subparsers.add_parser('dump',
                                            help='Dump configuration',
                                            parents=[common])
        dump_parser.set_defaults(func=self.execute_dump)
        dump_parser.add_argument(
            '--only-changed',
            dest='only_changed',
            action='store_true',
            help="Only show configurations that have changed from the default")

        view_parser = subparsers.add_parser('view',
                                            help='View configuration file',
                                            parents=[common])
        view_parser.set_defaults(func=self.execute_view)
Exemplo n.º 4
0
    def init_parser(self):
        super(VaultCLI, self).init_parser(
            desc="encryption/decryption utility for Ansible data files",
            epilog="\nSee '%s <command> --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0])
        )

        common = opt_help.argparse.ArgumentParser(add_help=False)
        opt_help.add_vault_options(common)
        opt_help.add_verbosity_options(common)

        subparsers = self.parser.add_subparsers(dest='action')
        subparsers.required = True

        output = opt_help.argparse.ArgumentParser(add_help=False)
        output.add_argument('--output', default=None, dest='output_file',
                            help='output file name for encrypt or decrypt; use - for stdout',
                            type=opt_help.unfrack_path())

        # For encrypting actions, we can also specify which of multiple vault ids should be used for encrypting
        vault_id = opt_help.argparse.ArgumentParser(add_help=False)
        vault_id.add_argument('--encrypt-vault-id', default=[], dest='encrypt_vault_id',
                              action='store', type=str,
                              help='the vault id used to encrypt (required if more than one vault-id is provided)')

        create_parser = subparsers.add_parser('create', help='Create new vault encrypted file', parents=[vault_id, common])
        create_parser.set_defaults(func=self.execute_create)
        create_parser.add_argument('args', help='Filename', metavar='file_name', nargs='*')

        decrypt_parser = subparsers.add_parser('decrypt', help='Decrypt vault encrypted file', parents=[output, common])
        decrypt_parser.set_defaults(func=self.execute_decrypt)
        decrypt_parser.add_argument('args', help='Filename', metavar='file_name', nargs='*')

        edit_parser = subparsers.add_parser('edit', help='Edit vault encrypted file', parents=[vault_id, common])
        edit_parser.set_defaults(func=self.execute_edit)
        edit_parser.add_argument('args', help='Filename', metavar='file_name', nargs='*')

        view_parser = subparsers.add_parser('view', help='View vault encrypted file', parents=[common])
        view_parser.set_defaults(func=self.execute_view)
        view_parser.add_argument('args', help='Filename', metavar='file_name', nargs='*')

        encrypt_parser = subparsers.add_parser('encrypt', help='Encrypt YAML file', parents=[common, output, vault_id])
        encrypt_parser.set_defaults(func=self.execute_encrypt)
        encrypt_parser.add_argument('args', help='Filename', metavar='file_name', nargs='*')

        enc_str_parser = subparsers.add_parser('encrypt_string', help='Encrypt a string', parents=[common, output, vault_id])
        enc_str_parser.set_defaults(func=self.execute_encrypt_string)
        enc_str_parser.add_argument('args', help='String to encrypt', metavar='string_to_encrypt', nargs='*')
        enc_str_parser.add_argument('-p', '--prompt', dest='encrypt_string_prompt',
                                    action='store_true',
                                    help="Prompt for the string to encrypt")
        enc_str_parser.add_argument('--show-input', dest='show_string_input', default=False, action='store_true',
                                    help='Do not hide input when prompted for the string to encrypt')
        enc_str_parser.add_argument('-n', '--name', dest='encrypt_string_names',
                                    action='append',
                                    help="Specify the variable name")
        enc_str_parser.add_argument('--stdin-name', dest='encrypt_string_stdin_name',
                                    default=None,
                                    help="Specify the variable name for stdin")

        rekey_parser = subparsers.add_parser('rekey', help='Re-key a vault encrypted file', parents=[common, vault_id])
        rekey_parser.set_defaults(func=self.execute_rekey)
        rekey_new_group = rekey_parser.add_mutually_exclusive_group()
        rekey_new_group.add_argument('--new-vault-password-file', default=None, dest='new_vault_password_file',
                                     help="new vault password file for rekey", type=opt_help.unfrack_path())
        rekey_new_group.add_argument('--new-vault-id', default=None, dest='new_vault_id', type=str,
                                     help='the new vault identity to use for rekey')
        rekey_parser.add_argument('args', help='Filename', metavar='file_name', nargs='*')
Exemplo n.º 5
0
    def init_parser(self):
        ''' create an options parser for bin/ansible '''

        super(GalaxyCLI, self).init_parser(
            desc="Perform various Role related operations.",
        )

        # common
        common = opt_help.argparse.ArgumentParser(add_help=False)
        common.add_argument('-s', '--server', dest='api_server', default=C.GALAXY_SERVER, help='The API server destination')
        common.add_argument('-c', '--ignore-certs', action='store_true', dest='ignore_certs', default=C.GALAXY_IGNORE_CERTS,
                            help='Ignore SSL certificate validation errors.')
        opt_help.add_verbosity_options(common)

        # options that apply to more than one action
        user_repo = opt_help.argparse.ArgumentParser(add_help=False)
        user_repo.add_argument('github_user', help='GitHub username')
        user_repo.add_argument('github_repo', help='GitHub repository')

        offline = opt_help.argparse.ArgumentParser(add_help=False)
        offline.add_argument('--offline', dest='offline', default=False, action='store_true',
                             help="Don't query the galaxy API when creating roles")

        default_roles_path = C.config.get_configuration_definition('DEFAULT_ROLES_PATH').get('default', '')
        roles_path = opt_help.argparse.ArgumentParser(add_help=False)
        roles_path.add_argument('-p', '--roles-path', dest='roles_path', type=opt_help.unfrack_path(pathsep=True),
                                default=C.DEFAULT_ROLES_PATH, action=opt_help.PrependListAction,
                                help='The path to the directory containing your roles. The default is the first writable one'
                                     'configured via DEFAULT_ROLES_PATH: %s ' % default_roles_path)

        force = opt_help.argparse.ArgumentParser(add_help=False)
        force.add_argument('-f', '--force', dest='force', action='store_true', default=False,
                           help='Force overwriting an existing role or collection')

        # Add sub parser for the Galaxy role type (role or collection)
        type_parser = self.parser.add_subparsers(metavar='TYPE', dest='type')
        type_parser.required = True

        # Define the actions for the collection object type
        collection = type_parser.add_parser('collection',
                                            parents=[common],
                                            help='Manage an Ansible Galaxy collection.')

        collection_parser = collection.add_subparsers(metavar='ACTION', dest='collection')
        collection_parser.required = True

        build_parser = collection_parser.add_parser(
            'build', help='Build an Ansible collection artifact that can be published to Ansible Galaxy.',
            parents=[common, force])
        build_parser.set_defaults(func=self.execute_build)
        build_parser.add_argument(
            'args', metavar='collection', nargs='*', default=('./',),
            help='Path to the collection(s) directory to build. This should be the directory that contains the '
                 'galaxy.yml file. The default is the current working directory.')

        build_parser.add_argument(
            '--output-path', dest='output_path', default='./',
            help='The path in which the collection is built to. The default is the current working directory.')

        self.add_init_parser(collection_parser, [common, force])

        cinstall_parser = collection_parser.add_parser('install', help='Install collection from Ansible Galaxy',
                                                       parents=[force, common])
        cinstall_parser.set_defaults(func=self.execute_install)
        cinstall_parser.add_argument('args', metavar='collection_name', nargs='*',
                                     help='The collection(s) name or path/url to a tar.gz collection artifact. This '
                                          'is mutually exclusive with --requirements-file.')
        cinstall_parser.add_argument('-p', '--collections-path', dest='collections_path', default='./',
                                     help='The path to the directory containing your collections.')
        cinstall_parser.add_argument('-i', '--ignore-errors', dest='ignore_errors', action='store_true', default=False,
                                     help='Ignore errors during installation and continue with the next specified '
                                          'collection. This will not ignore dependency conflict errors.')
        cinstall_parser.add_argument('-r', '--requirements-file', dest='requirements',
                                     help='A file containing a list of collections to be installed.')

        cinstall_exclusive = cinstall_parser.add_mutually_exclusive_group()
        cinstall_exclusive.add_argument('-n', '--no-deps', dest='no_deps', action='store_true', default=False,
                                        help="Don't download collections listed as dependencies")
        cinstall_exclusive.add_argument('--force-with-deps', dest='force_with_deps', action='store_true', default=False,
                                        help="Force overwriting an existing collection and its dependencies")

        publish_parser = collection_parser.add_parser(
            'publish', help='Publish a collection artifact to Ansible Galaxy.',
            parents=[common])
        publish_parser.set_defaults(func=self.execute_publish)
        publish_parser.add_argument(
            'args', metavar='collection_path', help='The path to the collection tarball to publish.')
        publish_parser.add_argument(
            '--api-key', dest='api_key',
            help='The Ansible Galaxy API key which can be found at https://galaxy.ansible.com/me/preferences. '
                 'You can also use ansible-galaxy login to retrieve this key.')
        publish_parser.add_argument(
            '--no-wait', dest='wait', action='store_false', default=True,
            help="Don't wait for import validation results.")

        # Define the actions for the role object type
        role = type_parser.add_parser('role',
                                      parents=[common],
                                      help='Manage an Ansible Galaxy role.')
        role_parser = role.add_subparsers(metavar='ACTION', dest='role')
        role_parser.required = True

        delete_parser = role_parser.add_parser('delete', parents=[user_repo, common],
                                               help='Removes the role from Galaxy. It does not remove or alter the actual GitHub repository.')
        delete_parser.set_defaults(func=self.execute_delete)

        import_parser = role_parser.add_parser('import', help='Import a role', parents=[user_repo, common])
        import_parser.set_defaults(func=self.execute_import)
        import_parser.add_argument('--no-wait', dest='wait', action='store_false', default=True, help="Don't wait for import results.")
        import_parser.add_argument('--branch', dest='reference',
                                   help='The name of a branch to import. Defaults to the repository\'s default branch (usually master)')
        import_parser.add_argument('--role-name', dest='role_name', help='The name the role should have, if different than the repo name')
        import_parser.add_argument('--status', dest='check_status', action='store_true', default=False,
                                   help='Check the status of the most recent import request for given github_user/github_repo.')

        info_parser = role_parser.add_parser('info', help='View more details about a specific role.',
                                             parents=[offline, common, roles_path])
        info_parser.set_defaults(func=self.execute_info)
        info_parser.add_argument('args', nargs='+', help='role', metavar='role_name[,version]')

        rinit_parser = self.add_init_parser(role_parser, [offline, force, common])
        rinit_parser.add_argument('--type',
                                  dest='role_type',
                                  action='store',
                                  default='default',
                                  help="Initialize using an alternate role type. Valid types include: 'container', 'apb' and 'network'.")

        install_parser = role_parser.add_parser('install', help='Install Roles from file(s), URL(s) or tar file(s)',
                                                parents=[force, common, roles_path])
        install_parser.set_defaults(func=self.execute_install)
        install_parser.add_argument('-i', '--ignore-errors', dest='ignore_errors', action='store_true', default=False,
                                    help='Ignore errors and continue with the next specified role.')
        install_parser.add_argument('-r', '--role-file', dest='role_file', help='A file containing a list of roles to be imported')
        install_parser.add_argument('-g', '--keep-scm-meta', dest='keep_scm_meta', action='store_true',
                                    default=False, help='Use tar instead of the scm archive option when packaging the role')
        install_parser.add_argument('args', help='Role name, URL or tar file', metavar='role', nargs='*')
        install_exclusive = install_parser.add_mutually_exclusive_group()
        install_exclusive.add_argument('-n', '--no-deps', dest='no_deps', action='store_true', default=False,
                                       help="Don't download roles listed as dependencies")
        install_exclusive.add_argument('--force-with-deps', dest='force_with_deps', action='store_true', default=False,
                                       help="Force overwriting an existing role and it's dependencies")

        remove_parser = role_parser.add_parser('remove', help='Delete roles from roles_path.', parents=[common, roles_path])
        remove_parser.set_defaults(func=self.execute_remove)
        remove_parser.add_argument('args', help='Role(s)', metavar='role', nargs='+')

        list_parser = role_parser.add_parser('list', help='Show the name and version of each role installed in the roles_path.',
                                             parents=[common, roles_path])
        list_parser.set_defaults(func=self.execute_list)
        list_parser.add_argument('role', help='Role', nargs='?', metavar='role')

        login_parser = role_parser.add_parser('login', parents=[common],
                                              help="Login to api.github.com server in order to use ansible-galaxy role "
                                                   "sub command such as 'import', 'delete', 'publish', and 'setup'")
        login_parser.set_defaults(func=self.execute_login)
        login_parser.add_argument('--github-token', dest='token', default=None,
                                  help='Identify with github token rather than username and password.')

        search_parser = role_parser.add_parser('search', help='Search the Galaxy database by tags, platforms, author and multiple keywords.',
                                               parents=[common])
        search_parser.set_defaults(func=self.execute_search)
        search_parser.add_argument('--platforms', dest='platforms', help='list of OS platforms to filter by')
        search_parser.add_argument('--galaxy-tags', dest='galaxy_tags', help='list of galaxy tags to filter by')
        search_parser.add_argument('--author', dest='author', help='GitHub username')
        search_parser.add_argument('args', help='Search terms', metavar='searchterm', nargs='*')

        setup_parser = role_parser.add_parser('setup', help='Manage the integration between Galaxy and the given source.',
                                              parents=[roles_path, common])
        setup_parser.set_defaults(func=self.execute_setup)
        setup_parser.add_argument('--remove', dest='remove_id', default=None,
                                  help='Remove the integration matching the provided ID value. Use --list to see ID values.')
        setup_parser.add_argument('--list', dest="setup_list", action='store_true', default=False, help='List all of your integrations.')
        setup_parser.add_argument('source', help='Source')
        setup_parser.add_argument('github_user', help='GitHub username')
        setup_parser.add_argument('github_repo', help='GitHub repository')
        setup_parser.add_argument('secret', help='Secret')
Exemplo n.º 6
0
def main(args=None):
    """ Called to initiate the connect to the remote device
    """

    parser = opt_help.create_base_parser(prog='ansible-connection')
    opt_help.add_verbosity_options(parser)
    parser.add_argument('playbook_pid')
    parser.add_argument('task_uuid')
    args = parser.parse_args(args[1:] if args is not None else args)

    # initialize verbosity
    display.verbosity = args.verbosity

    rc = 0
    result = {}
    messages = list()
    socket_path = None

    # Need stdin as a byte stream
    stdin = sys.stdin.buffer

    # Note: update the below log capture code after Display.display() is refactored.
    saved_stdout = sys.stdout
    sys.stdout = io.StringIO()

    try:
        # read the play context data via stdin, which means depickling it
        opts_data = read_stream(stdin)
        init_data = read_stream(stdin)

        pc_data = pickle.loads(init_data, encoding='bytes')
        options = pickle.loads(opts_data, encoding='bytes')

        play_context = PlayContext()
        play_context.deserialize(pc_data)

    except Exception as e:
        rc = 1
        result.update({
            'error': to_text(e),
            'exception': traceback.format_exc()
        })

    if rc == 0:
        ssh = connection_loader.get('ssh', class_only=True)
        ansible_playbook_pid = args.playbook_pid
        task_uuid = args.task_uuid
        cp = ssh._create_control_path(play_context.remote_addr,
                                      play_context.port,
                                      play_context.remote_user,
                                      play_context.connection,
                                      ansible_playbook_pid)
        # create the persistent connection dir if need be and create the paths
        # which we will be using later
        tmp_path = unfrackpath(C.PERSISTENT_CONTROL_PATH_DIR)
        makedirs_safe(tmp_path)

        socket_path = unfrackpath(cp % dict(directory=tmp_path))
        lock_path = unfrackpath("%s/.ansible_pc_lock_%s" %
                                os.path.split(socket_path))

        with file_lock(lock_path):
            if not os.path.exists(socket_path):
                messages.append(
                    ('vvvv',
                     'local domain socket does not exist, starting it'))
                original_path = os.getcwd()
                r, w = os.pipe()
                pid = fork_process()

                if pid == 0:
                    try:
                        os.close(r)
                        wfd = os.fdopen(w, 'w')
                        process = ConnectionProcess(wfd, play_context,
                                                    socket_path, original_path,
                                                    task_uuid,
                                                    ansible_playbook_pid)
                        process.start(options)
                    except Exception:
                        messages.append(('error', traceback.format_exc()))
                        rc = 1

                    if rc == 0:
                        process.run()
                    else:
                        process.shutdown()

                    sys.exit(rc)

                else:
                    os.close(w)
                    rfd = os.fdopen(r, 'r')
                    data = json.loads(rfd.read(), cls=AnsibleJSONDecoder)
                    messages.extend(data.pop('messages'))
                    result.update(data)

            else:
                messages.append(
                    ('vvvv', 'found existing local domain socket, using it!'))
                conn = Connection(socket_path)
                try:
                    conn.set_options(direct=options)
                except ConnectionError as exc:
                    messages.append(('debug', to_text(exc)))
                    raise ConnectionError(
                        'Unable to decode JSON from response set_options. See the debug log for more information.'
                    )
                pc_data = to_text(init_data)
                try:
                    conn.update_play_context(pc_data)
                    conn.set_check_prompt(task_uuid)
                except Exception as exc:
                    # Only network_cli has update_play context and set_check_prompt, so missing this is
                    # not fatal e.g. netconf
                    if isinstance(exc, ConnectionError) and getattr(
                            exc, 'code', None) == -32601:
                        pass
                    else:
                        result.update({
                            'error': to_text(exc),
                            'exception': traceback.format_exc()
                        })

    if os.path.exists(socket_path):
        messages.extend(Connection(socket_path).pop_messages())
    messages.append(('vvvv', sys.stdout.getvalue()))
    result.update({'messages': messages, 'socket_path': socket_path})

    sys.stdout = saved_stdout
    if 'exception' in result:
        rc = 1
        sys.stderr.write(json.dumps(result, cls=AnsibleJSONEncoder))
    else:
        rc = 0
        sys.stdout.write(json.dumps(result, cls=AnsibleJSONEncoder))

    sys.exit(rc)
Exemplo n.º 7
0
    def init_parser(self):
        ''' create an options parser for bin/ansible '''

        super(GalaxyCLI, self).init_parser(
            desc="Perform various Role related operations.", )

        # common
        common = opt_help.argparse.ArgumentParser(add_help=False)
        common.add_argument('-s',
                            '--server',
                            dest='api_server',
                            default=C.GALAXY_SERVER,
                            help='The API server destination')
        common.add_argument('-c',
                            '--ignore-certs',
                            action='store_true',
                            dest='ignore_certs',
                            default=C.GALAXY_IGNORE_CERTS,
                            help='Ignore SSL certificate validation errors.')
        opt_help.add_verbosity_options(common)

        # options that apply to more than one action
        user_repo = opt_help.argparse.ArgumentParser(add_help=False)
        user_repo.add_argument('github_user', help='GitHub username')
        user_repo.add_argument('github_repo', help='GitHub repository')

        offline = opt_help.argparse.ArgumentParser(add_help=False)
        offline.add_argument(
            '--offline',
            dest='offline',
            default=False,
            action='store_true',
            help="Don't query the galaxy API when creating roles")

        roles_path = opt_help.argparse.ArgumentParser(add_help=False)
        roles_path.add_argument(
            '-p',
            '--roles-path',
            dest='roles_path',
            type=opt_help.unfrack_path(pathsep=True),
            default=C.DEFAULT_ROLES_PATH,
            action=opt_help.PrependListAction,
            help=
            'The path to the directory containing your roles. The default is the roles_path '
            'configured in your ansible.cfg file (/etc/ansible/roles if not configured)'
        )

        force = opt_help.argparse.ArgumentParser(add_help=False)
        force.add_argument('-f',
                           '--force',
                           dest='force',
                           action='store_true',
                           default=False,
                           help='Force overwriting an existing role')

        subparsers = self.parser.add_subparsers(dest='action')
        subparsers.required = True

        delete_parser = subparsers.add_parser(
            'delete',
            parents=[user_repo, common],
            help=
            'Removes the role from Galaxy. It does not remove or alter the actual GitHub repository.'
        )
        delete_parser.set_defaults(func=self.execute_delete)

        import_parser = subparsers.add_parser('import',
                                              help='Import a role',
                                              parents=[user_repo, common])
        import_parser.set_defaults(func=self.execute_import)
        import_parser.add_argument('--no-wait',
                                   dest='wait',
                                   action='store_false',
                                   default=True,
                                   help="Don't wait for import results.")
        import_parser.add_argument(
            '--branch',
            dest='reference',
            help=
            'The name of a branch to import. Defaults to the repository\'s default branch (usually master)'
        )
        import_parser.add_argument(
            '--role-name',
            dest='role_name',
            help=
            'The name the role should have, if different than the repo name')
        import_parser.add_argument(
            '--status',
            dest='check_status',
            action='store_true',
            default=False,
            help=
            'Check the status of the most recent import request for given github_user/github_repo.'
        )

        info_parser = subparsers.add_parser(
            'info',
            help='View more details about a specific role.',
            parents=[offline, common, roles_path])
        info_parser.set_defaults(func=self.execute_info)
        info_parser.add_argument('args',
                                 nargs='+',
                                 help='role',
                                 metavar='role_name[,version]')

        init_parser = subparsers.add_parser(
            'init',
            help='Initialize new role with the base structure of a role.',
            parents=[offline, force, common])
        init_parser.set_defaults(func=self.execute_init)
        init_parser.add_argument(
            '--init-path',
            dest='init_path',
            default="./",
            help=
            'The path in which the skeleton role will be created. The default is the current working directory.'
        )
        init_parser.add_argument(
            '--type',
            dest='role_type',
            action='store',
            default='default',
            help=
            "Initialize using an alternate role type. Valid types include: 'container', 'apb' and 'network'."
        )
        init_parser.add_argument(
            '--role-skeleton',
            dest='role_skeleton',
            default=C.GALAXY_ROLE_SKELETON,
            help=
            'The path to a role skeleton that the new role should be based upon.'
        )
        init_parser.add_argument('role_name', help='Role name')

        install_parser = subparsers.add_parser(
            'install',
            help='Install Roles from file(s), URL(s) or tar file(s)',
            parents=[force, common, roles_path])
        install_parser.set_defaults(func=self.execute_install)
        install_parser.add_argument(
            '-i',
            '--ignore-errors',
            dest='ignore_errors',
            action='store_true',
            default=False,
            help='Ignore errors and continue with the next specified role.')
        install_parser.add_argument(
            '-r',
            '--role-file',
            dest='role_file',
            help='A file containing a list of roles to be imported')
        install_parser.add_argument(
            '-g',
            '--keep-scm-meta',
            dest='keep_scm_meta',
            action='store_true',
            default=False,
            help=
            'Use tar instead of the scm archive option when packaging the role'
        )
        install_parser.add_argument('args',
                                    help='Role name, URL or tar file',
                                    metavar='role',
                                    nargs='*')
        install_exclusive = install_parser.add_mutually_exclusive_group()
        install_exclusive.add_argument(
            '-n',
            '--no-deps',
            dest='no_deps',
            action='store_true',
            default=False,
            help="Don't download roles listed as dependencies")
        install_exclusive.add_argument(
            '--force-with-deps',
            dest='force_with_deps',
            action='store_true',
            default=False,
            help="Force overwriting an existing role and it's dependencies")

        remove_parser = subparsers.add_parser(
            'remove',
            help='Delete roles from roles_path.',
            parents=[common, roles_path])
        remove_parser.set_defaults(func=self.execute_remove)
        remove_parser.add_argument('args',
                                   help='Role(s)',
                                   metavar='role',
                                   nargs='+')

        list_parser = subparsers.add_parser(
            'list',
            help=
            'Show the name and version of each role installed in the roles_path.',
            parents=[common, roles_path])
        list_parser.set_defaults(func=self.execute_list)
        list_parser.add_argument('role',
                                 help='Role',
                                 nargs='?',
                                 metavar='role')

        login_parser = subparsers.add_parser(
            'login',
            parents=[common],
            help=
            "Login to api.github.com server in order to use ansible-galaxy sub "
            "command such as 'import', 'delete' and 'setup'")
        login_parser.set_defaults(func=self.execute_login)
        login_parser.add_argument(
            '--github-token',
            dest='token',
            default=None,
            help='Identify with github token rather than username and password.'
        )

        search_parser = subparsers.add_parser(
            'search',
            help=
            'Search the Galaxy database by tags, platforms, author and multiple keywords.',
            parents=[common])
        search_parser.set_defaults(func=self.execute_search)
        search_parser.add_argument('--platforms',
                                   dest='platforms',
                                   help='list of OS platforms to filter by')
        search_parser.add_argument('--galaxy-tags',
                                   dest='galaxy_tags',
                                   help='list of galaxy tags to filter by')
        search_parser.add_argument('--author',
                                   dest='author',
                                   help='GitHub username')
        search_parser.add_argument('args',
                                   help='Search terms',
                                   metavar='searchterm',
                                   nargs='*')

        setup_parser = subparsers.add_parser(
            'setup',
            help='Manage the integration between Galaxy and the given source.',
            parents=[roles_path, common])
        setup_parser.set_defaults(func=self.execute_setup)
        setup_parser.add_argument(
            '--remove',
            dest='remove_id',
            default=None,
            help=
            'Remove the integration matching the provided ID value. Use --list to see ID values.'
        )
        setup_parser.add_argument('--list',
                                  dest="setup_list",
                                  action='store_true',
                                  default=False,
                                  help='List all of your integrations.')
        setup_parser.add_argument('source', help='Source')
        setup_parser.add_argument('github_user', help='GitHub username')
        setup_parser.add_argument('github_repo', help='GitHub repository')
        setup_parser.add_argument('secret', help='Secret')