Example #1
0
class Command(BaseCommand):
    name = 'list_projects'
    help = 'Creates a list of applications and projects that contain a certain word in their name'\
        ' (Proof of Concept only!)'

    def configure(self):
        self.api = APIBase(self.config)
        self.config.opts.add('search_string', "The string to search the name of projects against. Use empty to list all",
                             default='')

    def handle(self):
        search_str = self.config['search_string']

        bu_list = self.api.get_business_units()
        for bu in bu_list:
            bu_output = False
            app_list = self.api.get_applications(business_unit=bu['id'])
            for app in app_list:
                app_output = False
                prj_list = self.api.get_projects(app['id'])
                for prj in prj_list:
                    if search_str in prj['name']:
                        if not bu_output:
                            bu_output = True
                            print 'BU %s: %s' % (bu['id'], bu['name'])
                        if not app_output:
                            app_output = True
                            print '  App %s: %s' % (app['id'], app['name'])
                        print '    Prj %s: %s' % (prj['id'], prj['name'])
        return True
Example #2
0
 def configure(self):
     self.api = APIBase(self.config)
     self.job_return_logs = {}
     self.config.opts.add("filter_connection_alias", "Connection alias")
     self.config.opts.add(
         "filter_connection_access",
         "Filter connections based on server accessibility " "(accessible, inaccessible, all)",
         default="inaccessible",
     )
     self.config.opts.add("filter_frequency", "Frequency (manually|hourly|daily|weekly|monthly)")
     self.config.opts.add("filter_connection_type", "Connection type (alm or analysis)")
     self.config.opts.add("filter_params", "Filter connections based on params {key1:value1,key2:value2}")
     self.config.opts.add("filter_connections", "Connection type-id combinations (alm-1,analysis-1,alm-2...)")
     self.config.opts.add("command_params", "Set additional params {key1:value1,key2:value2}")
Example #3
0
class Command(BaseCommand):
    help = "Downloads project integration connection details from SDE and executes them"

    def configure(self):
        self.api = APIBase(self.config)
        self.job_return_logs = {}
        self.config.opts.add("filter_connection_alias", "Connection alias")
        self.config.opts.add(
            "filter_connection_access",
            "Filter connections based on server accessibility " "(accessible, inaccessible, all)",
            default="inaccessible",
        )
        self.config.opts.add("filter_frequency", "Frequency (manually|hourly|daily|weekly|monthly)")
        self.config.opts.add("filter_connection_type", "Connection type (alm or analysis)")
        self.config.opts.add("filter_params", "Filter connections based on params {key1:value1,key2:value2}")
        self.config.opts.add("filter_connections", "Connection type-id combinations (alm-1,analysis-1,alm-2...)")
        self.config.opts.add("command_params", "Set additional params {key1:value1,key2:value2}")

    def sde_connect(self):
        if not self.api:
            raise Error("Requires initialization")
        try:
            self.api.connect()
        except APIError as err:
            raise Error(
                "Unable to connect to SD Elements. Please review URL"
                " and credentials in configuration file. Reason: %s" % (str(err))
            )

    def validate_configuration(self):
        valid_frequencies = ["manually", "hourly", "daily", "weekly", "monthly"]
        valid_connection_types = ["alm", "analysis"]
        valid_connection_access_options = ["accessible", "inaccessible", "all"]

        if self.config["filter_frequency"] and self.config["filter_frequency"] not in valid_frequencies:
            raise UsageError("%s is not a valid frequency" % self.config["filter_frequency"])

        if (
            self.config["filter_connection_type"]
            and self.config["filter_connection_type"] not in valid_connection_types
        ):
            raise UsageError("%s is not a valid connection type" % self.config["filter_connection_type"])

        if self.config["filter_connection_access"] not in valid_connection_access_options:
            raise UsageError("%s is not a valid connection access option" % self.config["filter_connection_access"])

        self.config.process_json_dict("filter_params")
        self.config.process_json_dict("command_params")

    def in_scope(self, connection):
        """
        Check to see if a connection is in scope
        """
        in_scope = True

        if self.config["filter_connections"]:
            connection_combo_id = connection["type"] + "-" + str(connection["id"])
            in_scope = connection_combo_id in self.config["filter_connections"].split(",")

        # Filter connections based on accessibility
        if in_scope and self.config["filter_connection_access"] == "inaccessible":
            in_scope = in_scope and connection["inaccessible"] is True
        elif in_scope and self.config["filter_connection_access"] == "accessible":
            in_scope = in_scope and connection["inaccessible"] is False

        if in_scope and self.config["filter_connection_alias"]:
            in_scope = in_scope and (connection["alias"] == self.config["filter_connection_alias"])

        if in_scope and self.config["filter_connection_type"]:
            in_scope = in_scope and (connection["type"] == self.config["filter_connection_type"])

        if in_scope and self.config["filter_frequency"]:
            in_scope = in_scope and (connection["frequency"] == self.config["filter_frequency"])

        if in_scope and self.config["filter_params"]:
            for key in self.config["filter_params"]:
                in_scope = in_scope and key in connection["params"]
                in_scope = in_scope and connection["params"][key] == self.config["filter_params"][key]

        return in_scope

    def filter_connections(self, connections):
        filtered_connections = [connection for connection in connections if self.in_scope(connection)]

        return filtered_connections

    def on_job_complete(self, log_info, connection_combo_id):
        if not log_info.msg:
            log_info.msg = "Success"
        self.job_return_logs.update({connection_combo_id: log_info})

    def get_connections(self):
        try:
            alm_connections = self.api.get_integration_connections("alm")
            for connection in alm_connections:
                connection["type"] = "alm"
        except APIError:
            raise Error("Unable to retrieve alm connections from SD Elements")

        try:
            analysis_connections = self.api.get_integration_connections("analysis")
            for connection in analysis_connections:
                connection["type"] = "analysis"
        except APIError:
            raise Error("Unable to retrieve analysis connections from SD Elements")

        return alm_connections + analysis_connections

    def handle(self):
        self.validate_configuration()
        self.sde_connect()

        logger.info("Retrieving connection details")

        connections = self.get_connections()

        logger.info("Found %s connections, starting local execution" % len(connections))

        successful_job_count = 0
        failed_jobs = []
        jobs_with_warnings = []

        filtered_connections = self.filter_connections(connections)
        logger.info("Filtered out %s connections" % (len(connections) - len(filtered_connections)))
        logger.info("Running %s jobs" % len(filtered_connections))

        for connection in filtered_connections:
            command = connection["command"]

            # Check whether this command exists
            if command not in self.config.command_list:
                failed_jobs.append(connection["id"])
                logger.error("No such command %s" % command)
                continue

            params = connection["params"]

            # Set the credentials and method with which to connect to SDE
            # - This isn't sent from the server
            params["sde_api_token"] = self.config["sde_api_token"]
            params["sde_method"] = self.config["sde_method"]

            for key in self.config["command_params"]:
                params[key] = self.config["command_params"][key]

            connection_id = connection["id"]
            connection_type = connection["type"]
            connection_name = connection["alias"]
            connection_combo_id = connection_type + "-" + str(connection_id)

            msg = "Running job with Connection Id: %s, Name: %s, Type: %s"
            logger.info(msg % (connection_id, connection_name, connection_type))

            logger.debug(" + Args: %s" % str(params))

            exit_status = sdetools.call(
                command,
                options=params,
                call_back=self.on_job_complete,
                call_back_args={"connection_combo_id": connection_combo_id},
            )
            if not exit_status:
                failed_jobs.append(connection_combo_id)
            else:
                successful_job_count += 1

            try:
                self.api.update_job_status(
                    connection_id, exit_status, self.job_return_logs[connection_combo_id].msg, connection_type
                )
            except APIError as e:
                jobs_with_warnings.append(connection_combo_id)
                logger.warn(
                    "Could not update job status on server for %s connection id %d: %s"
                    % (connection_type, connection_id, e)
                )

        logger.info("%s jobs completed successfully, %s failed" % (successful_job_count, len(failed_jobs)))

        if failed_jobs:
            logger.error("Failed job(s) by connection id: %s" % ", ".join(failed_jobs))

        if jobs_with_warnings:
            warn_msg = "Connection id(s) of job(s) whose status could not be updated on the server: %s"
            logger.warn(warn_msg % ", ".join(jobs_with_warnings))

        return True
Example #4
0
 def configure(self):
     self.api = APIBase(self.config)
     self.config.opts.add('search_string', "The string to search the name of projects against. Use empty to list all",
                          default='')