コード例 #1
0
def test_galaxy_cli_error_with_message():
    msg = "there was an error in the cli"
    galaxy_cli_error = cli_exceptions.GalaxyCliError(msg)

    assert isinstance(galaxy_cli_error, exceptions.GalaxyError)

    with pytest.raises(cli_exceptions.GalaxyCliError, match=msg) as exc_info:
        raise cli_exceptions.GalaxyCliError(msg)
    log.debug("exc_info: %s", exc_info)
コード例 #2
0
ファイル: galaxy.py プロジェクト: panickervinod/mazer
    def execute_setup(self):
        """ Setup an integration from Github or Travis for Ansible Galaxy roles"""

        if self.options.setup_list:
            # List existing integration secrets
            secrets = self.api.list_secrets()
            if len(secrets) == 0:
                # None found
                self.display("No integrations found.")
                return 0
            self.display(u'\n' + "ID         Source     Repo", color=runtime.COLOR_OK)
            self.display("---------- ---------- ----------", color=runtime.COLOR_OK)
            for secret in secrets:
                self.display("%-10s %-10s %s/%s" % (secret['id'], secret['source'], secret['github_user'],
                                                    secret['github_repo']), color=runtime.COLOR_OK)
            return 0

        if self.options.remove_id:
            # Remove a secret
            self.api.remove_secret(self.options.remove_id)
            self.display("Secret removed. Integrations using this secret will not longer work.", color=runtime.COLOR_OK)
            return 0

        if len(self.args) < 4:
            raise cli_exceptions.GalaxyCliError("Missing one or more arguments. Expecting: source github_user github_repo secret")

        secret = self.args.pop()
        github_repo = self.args.pop()
        github_user = self.args.pop()
        source = self.args.pop()

        resp = self.api.add_secret(source, github_user, github_repo, secret)
        self.display("Added integration for %s %s/%s" % (resp['source'], resp['github_user'], resp['github_repo']))

        return 0
コード例 #3
0
ファイル: galaxy.py プロジェクト: alikins/mazer_old
 def exit_without_ignore(self, rc=1):
     """
     Exits with the specified return code unless the
     option --ignore-errors was specified
     """
     if not self.options.ignore_errors:
         raise cli_exceptions.GalaxyCliError(
             '- you can use --ignore-errors to skip failed roles and finish processing the list.'
         )
コード例 #4
0
ファイル: galaxy.py プロジェクト: panickervinod/mazer
    def execute_import(self):
        """ used to import a role into Ansible Galaxy """

        # FIXME/TODO(alikins): replace with logging or display callback
        colors = {
            'INFO': 'normal',
            'WARNING': runtime.COLOR_WARN,
            'ERROR': runtime.COLOR_ERROR,
            'SUCCESS': runtime.COLOR_OK,
            'FAILED': runtime.COLOR_ERROR,
            'DEBUG': runtime.COLOR_DEBUG,
        }

        if len(self.args) < 2:
            raise cli_exceptions.GalaxyCliError("Expected a github_username and github_repository. Use --help.")

        github_repo = to_text(self.args.pop(), errors='surrogate_or_strict')
        github_user = to_text(self.args.pop(), errors='surrogate_or_strict')

        if self.options.check_status:
            task = self.api.get_import_task(github_user=github_user, github_repo=github_repo)
        else:
            # Submit an import request
            task = self.api.create_import_task(github_user, github_repo, reference=self.options.reference, role_name=self.options.role_name)

            if len(task) > 1:
                # found multiple roles associated with github_user/github_repo
                self.display("WARNING: More than one Galaxy role associated with Github repo %s/%s." % (github_user, github_repo),
                             color='yellow')
                self.display("The following Galaxy roles are being updated:" + u'\n', color=runtime.COLOR_CHANGED)
                for t in task:
                    self.display('%s.%s' % (t['summary_fields']['role']['namespace'], t['summary_fields']['role']['name']), color=runtime.COLOR_CHANGED)
                    self.display(u'\nTo properly namespace this role, remove each of the above and re-import %s/%s from scratch' % (github_user, github_repo),
                                 color=runtime.COLOR_CHANGED)
                return 0
            # found a single role as expected
            self.display("Successfully submitted import request %d" % task[0]['id'])
            if not self.options.wait:
                self.display("Role name: %s" % task[0]['summary_fields']['role']['name'])
                self.display("Repo: %s/%s" % (task[0]['github_user'], task[0]['github_repo']))

        if self.options.check_status or self.options.wait:
            # Get the status of the import
            msg_list = []
            finished = False
            while not finished:
                task = self.api.get_import_task(task_id=task[0]['id'])
                for msg in task[0]['summary_fields']['task_messages']:
                    if msg['id'] not in msg_list:
                        self.display(msg['message_text'], color=colors[msg['message_type']])
                        msg_list.append(msg['id'])
                if task[0]['state'] in ['SUCCESS', 'FAILED']:
                    finished = True
                else:
                    time.sleep(10)

        return 0
コード例 #5
0
def exit_without_ignore(ignore_errors, msg=None, rc=1):
    """
    Exits with the specified return code unless the
    option --ignore-errors was specified
    """
    ignore_error_blurb = '- you can use --ignore-errors to skip failed content items and finish processing the list.'
    if not ignore_errors:
        message = ignore_error_blurb
        if msg:
            message = '%s:\n%s' % (msg, ignore_error_blurb)
        raise cli_exceptions.GalaxyCliError(message)
コード例 #6
0
ファイル: galaxy.py プロジェクト: alikins/mazer_old
    def execute_search(self):
        ''' searches for roles on the Ansible Galaxy server'''
        page_size = 1000
        search = None

        if len(self.args):
            terms = []
            for i in range(len(self.args)):
                terms.append(self.args.pop())
            search = '+'.join(terms[::-1])

        if not search and not self.options.platforms and not self.options.galaxy_tags and not self.options.author:
            raise cli_exceptions.GalaxyCliError(
                "Invalid query. At least one search term, platform, galaxy tag or author must be provided."
            )

        response = self.api.search_roles(search,
                                         platforms=self.options.platforms,
                                         tags=self.options.galaxy_tags,
                                         author=self.options.author,
                                         page_size=page_size)

        if response['count'] == 0:
            self.display("No roles match your search.")
            return True

        data = [u'']

        if response['count'] > page_size:
            data.append(
                u"Found %d roles matching your search. Showing first %s." %
                (response['count'], page_size))
        else:
            data.append(u"Found %d roles matching your search:" %
                        response['count'])

        max_len = []
        for role in response['results']:
            max_len.append(len(role['username'] + '.' + role['name']))
        name_len = max(max_len)
        format_str = u" %%-%ds %%s" % name_len
        data.append(u'')
        data.append(format_str % (u"Name", u"Description"))
        data.append(format_str % (u"----", u"-----------"))
        for role in response['results']:
            data.append(
                format_str %
                (u'%s.%s' %
                 (role['username'], role['name']), role['description']))

        data = u'\n'.join(data)
        self.display(data)
        return True
コード例 #7
0
def remove_repository(installed_repository, display_callback=None):
    log.debug('looking for repository %s to remove', installed_repository)

    log.debug('repository to remove: %s %s', installed_repository,
              type(installed_repository))

    try:
        res = repository.remove(installed_repository)
        if res:
            display_callback('- successfully removed %s' %
                             installed_repository.label)
        else:
            display_callback('- %s is not installed, skipping.' %
                             installed_repository.label)
    except Exception as e:
        log.exception(e)
        raise cli_exceptions.GalaxyCliError(
            "Failed to remove installed repository %s: %s" %
            (installed_repository.label, str(e)))
コード例 #8
0
ファイル: galaxy.py プロジェクト: panickervinod/mazer
    def execute_delete(self):
        """ Delete a role from Ansible Galaxy. """

        if len(self.args) < 2:
            raise cli_exceptions.GalaxyCliError("Missing one or more arguments. Expected: github_user github_repo")

        github_repo = self.args.pop()
        github_user = self.args.pop()
        resp = self.api.delete_role(github_user, github_repo)

        if len(resp['deleted_roles']) > 1:
            self.display("Deleted the following roles:")
            self.display("ID     User            Name")
            self.display("------ --------------- ----------")
            for role in resp['deleted_roles']:
                self.display("%-8s %-15s %s" % (role.id, role.namespace, role.name))

        self.display(resp['status'])

        return True
コード例 #9
0
ファイル: galaxy.py プロジェクト: alikins/mazer_old
    def execute_remove(self):
        """
        removes the list of roles passed as arguments from the local system.
        """

        if len(self.args) == 0:
            raise cli_exceptions.CliOptionsError(
                '- you must specify at least one role to remove.')

        for role_name in self.args:
            role = GalaxyContent(self.galaxy, role_name)
            try:
                if role.remove():
                    self.display('- successfully removed %s' % role_name)
                else:
                    self.display('- %s is not installed, skipping.' %
                                 role_name)
            except Exception as e:
                raise cli_exceptions.GalaxyCliError(
                    "Failed to remove role %s: %s" % (role_name, str(e)))

        return 0
コード例 #10
0
def test_galaxy_cli_error():
    galaxy_cli_error = cli_exceptions.GalaxyCliError()

    assert isinstance(galaxy_cli_error, exceptions.GalaxyError)
コード例 #11
0
ファイル: galaxy.py プロジェクト: alikins/mazer_old
    def execute_install(self):
        """
        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.options.role_file

        if len(self.args) == 0 and role_file is None:
            # the user needs to specify one of either --role-file or specify a single user/role name
            raise cli_exceptions.CliOptionsError(
                "- you must specify a user/role name or a roles file")

        no_deps = self.options.no_deps
        force = self.options.force

        roles_left = []
        if role_file:
            try:
                f = open(role_file, 'r')
                if role_file.endswith('.yaml') or role_file.endswith('.yml'):
                    try:
                        required_roles = yaml.safe_load(f.read())
                    except Exception as e:
                        raise cli_exceptions.GalaxyCliError(
                            "Unable to load data from the requirements file: %s"
                            % role_file)

                    if required_roles is None:
                        raise cli_exceptions.GalaxyCliError(
                            "No roles found in file: %s" % role_file)

                    for role in required_roles:
                        if "include" not in role:
                            role = GalaxyContent.yaml_parse(role)
                            log.info("found role %s in yaml file", str(role))
                            if "name" not in role and "scm" not in role:
                                raise cli_exceptions.GalaxyCliError(
                                    "Must specify name or src for role")
                            roles_left.append(
                                GalaxyContent(self.galaxy, **role))
                        else:
                            with open(role["include"]) as f_include:
                                try:
                                    roles_left += [
                                        GalaxyContent(self.galaxy, **r)
                                        for r in (
                                            GalaxyContent.yaml_parse(i)
                                            for i in yaml.safe_load(f_include))
                                    ]
                                except Exception as e:
                                    msg = "Unable to load data from the include requirements file: %s %s"
                                    raise cli_exceptions.GalaxyCliError(
                                        msg % (role_file, e))
                else:
                    log.warn(
                        "DEPRECATED going forward only the yaml format will be supported (version='%s')",
                        "2.6")
                    # roles listed in a file, one per line
                    for rline in f.readlines():
                        if rline.startswith("#") or rline.strip() == '':
                            continue
                        log.debug('found role %s in text file', str(rline))
                        role = GalaxyContent.yaml_parse(rline.strip())
                        roles_left.append(GalaxyContent(self.galaxy, **role))
                f.close()
            except (IOError, OSError) as e:
                raise cli_exceptions.GalaxyCliError('Unable to open %s: %s' %
                                                    (role_file, str(e)))
        else:
            # roles were specified directly, so we'll just go out grab them
            # (and their dependencies, unless the user doesn't want us to).
            for rname in self.args:
                role = GalaxyContent.yaml_parse(rname.strip())
                roles_left.append(GalaxyContent(self.galaxy, **role))

        for role in roles_left:
            # only process roles in roles files when names matches if given
            if role_file and self.args and role.name not in self.args:
                log.info('Skipping role %s', role.name)
                continue

            log.info('Processing role %s ', role.name)

            # query the galaxy API for the role data

            if role.install_info is not None:
                if role.install_info['version'] != role.version or force:
                    if force:
                        self.display(
                            '- changing role %s from %s to %s' % role.name,
                            role.install_info['version'], role.version
                            or "unspecified")
                        role.remove()
                    else:
                        log.warn(
                            '- %s (%s) is already installed - use --force to change version to %s',
                            role.name, role.install_info['version'],
                            role.version or "unspecified")
                        continue
                else:
                    if not force:
                        self.display('- %s is already installed, skipping.' %
                                     str(role))
                        continue

            try:
                installed = role.install()
            except exceptions.GalaxyError as e:
                self.log.exception(e)
                log.warn("- %s was NOT installed successfully: %s ", role.name,
                         str(e))
                self.exit_without_ignore()
                continue

            # install dependencies, if we want them
            if not no_deps and installed:
                if not role.metadata:
                    log.warn("Meta file %s is empty. Skipping dependencies.",
                             role.path)
                else:
                    role_dependencies = role.metadata.get('dependencies') or []
                    for dep in role_dependencies:
                        log.debug('Installing dep %s', dep)
                        dep_info = GalaxyContent.yaml_parse(dep)
                        dep_role = GalaxyContent(self.galaxy, **dep_info)
                        if '.' not in dep_role.name and '.' not in dep_role.src and dep_role.scm is None:
                            # we know we can skip this, as it's not going to
                            # be found on galaxy.ansible.com
                            continue
                        if dep_role.install_info is None:
                            if dep_role not in roles_left:
                                self.display('- adding dependency: %s' %
                                             str(dep_role))
                                roles_left.append(dep_role)
                            else:
                                self.display(
                                    '- dependency %s already pending installation.'
                                    % dep_role.name)
                        else:
                            if dep_role.install_info[
                                    'version'] != dep_role.version:
                                log.warning(
                                    '- dependency %s from role %s differs from already installed version (%s), skipping'
                                    % str(dep_role), role.name,
                                    dep_role.install_info['version'])
                            else:
                                self.display(
                                    '- dependency %s is already installed, skipping.'
                                    % dep_role.name)

            if not installed:
                log.warning("- %s was NOT installed successfully.", role.name)
                self.exit_without_ignore()

        return 0
コード例 #12
0
ファイル: galaxy.py プロジェクト: alikins/mazer_old
    def execute_init(self):
        """
        creates the skeleton framework of a role that complies with the galaxy metadata format.
        """

        init_path = self.options.init_path
        force = self.options.force
        role_skeleton_path = self.options.role_skeleton

        role_name = self.args.pop(0).strip() if self.args else None
        if not role_name:
            raise cli_exceptions.CliOptionsError(
                "- no role name specified for init")
        role_path = os.path.join(init_path, role_name)
        if os.path.exists(role_path):
            if os.path.isfile(role_path):
                raise cli_exceptions.GalaxyCliError(
                    "- the path %s already exists, but is a file - aborting" %
                    role_path)
            elif not force:
                raise cli_exceptions.GalaxyCliError(
                    "- the directory %s already exists."
                    "you can use --force to re-initialize this directory,\n"
                    "however it will reset any main.yml files that may have\n"
                    "been modified there already." % role_path)

        # FIXME(akl): role_skeleton stuff should probably be a module or two and a few classes instead of inline here
        # role_skeleton ends mostly being a list of file paths to copy
        inject_data = dict(
            role_name=role_name,
            author='your name',
            description='your description',
            company='your company (optional)',
            license='license (GPLv2, CC-BY, etc)',
            issue_tracker_url='http://example.com/issue/tracker',
            min_ansible_version='1.2',
            role_type=self.options.role_type)

        import pprint
        self.log.debug('inject_data: %s', pprint.pformat(inject_data))

        # create role directory
        if not os.path.exists(role_path):
            os.makedirs(role_path)

        if role_skeleton_path is not None:
            skeleton_ignore_expressions = runtime.GALAXY_ROLE_SKELETON_IGNORE
        else:
            this_dir, this_filename = os.path.split(__file__)

            type_path = getattr(self.options, 'role_type', "default")
            role_skeleton_path = os.path.join(this_dir, '../',
                                              'data/role_skelton', type_path)

            self.log.debug('role_skeleton_path: %s', role_skeleton_path)

            skeleton_ignore_expressions = ['^.*/.git_keep$']

        role_skeleton = os.path.expanduser(role_skeleton_path)

        self.log.debug('role_skeleton: %s', role_skeleton)
        skeleton_ignore_re = [
            re.compile(x) for x in skeleton_ignore_expressions
        ]

        template_env = Environment(loader=FileSystemLoader(role_skeleton))

        # TODO: mv elsewhere, this is main role install logic
        for root, dirs, files in os.walk(role_skeleton, topdown=True):
            rel_root = os.path.relpath(root, role_skeleton)
            in_templates_dir = rel_root.split(os.sep, 1)[0] == 'templates'
            dirs[:] = [
                d for d in dirs
                if not any(r.match(d) for r in skeleton_ignore_re)
            ]

            for f in files:
                filename, ext = os.path.splitext(f)
                if any(
                        r.match(os.path.join(rel_root, f))
                        for r in skeleton_ignore_re):
                    continue
                elif ext == ".j2" and not in_templates_dir:
                    src_template = os.path.join(rel_root, f)
                    dest_file = os.path.join(role_path, rel_root, filename)
                    template_env.get_template(src_template).stream(
                        inject_data).dump(dest_file)
                else:
                    f_rel_path = os.path.relpath(os.path.join(root, f),
                                                 role_skeleton)
                    shutil.copyfile(os.path.join(root, f),
                                    os.path.join(role_path, f_rel_path))

            for d in dirs:
                dir_path = os.path.join(role_path, rel_root, d)
                if not os.path.exists(dir_path):
                    os.makedirs(dir_path)

        self.display("- %s was created successfully" % role_name)