예제 #1
0
    def __try_fetch_projects(cluster: dict) -> bool:
        cluster_id: str = cluster.get('id')
        cluster_name: str = cluster.get('name')

        log: Log = Log.get_singleton()
        log.info(
            "Seeking for all projects inside cluster "
            f"'{cluster_name}' [ID: {cluster_id}]...",
            origin='Rancher')

        status_code: int = 0
        content: dict = {}
        path: str = f"{app_config['static']['clusters']}/{cluster_id}/projects"
        status_code, content = RancherMediator.__get_response(path)
        if status_code != 200:
            RancherMediator.__handle_bad_response(status_code, content)
            return False

        projects: list = []
        data: list = content.get('data')
        for i in range(len(data)):
            project_data: dict = data[i]
            project_id: str = project_data.get('id')
            project_name: str = project_data.get('name')
            project_links: dict = project_data.get('links')
            project: dict = {
                'id': project_id,
                'name': project_name,
                'links': project_links
            }
            projects.append(project)

        cluster['projects'] = projects
        return True
예제 #2
0
 def __handle_bad_response(status_code: int, content: dict) -> None:
     log: Log = Log.get_singleton()
     log.error("Something wrong happened!",
               origin='Rancher',
               args={
                   'Status Code': status_code,
                   'Message': content.get('message')
               })
예제 #3
0
 def __load_template(template: str, path: str) -> str:
     log: Log = Log.get_singleton()
     log.info(
         f"Loading template '{template}' -> {path}",
         origin='Markdown'
     )
     with open(path, 'r') as file:
         return file.read()
예제 #4
0
    def try_parse(settings: dict) -> bool:
        log: Log = Log.get_singleton()

        try:
            app_config['rancher'] = settings
            log.info("Successfully parsed all settings!")
            return True
        except KeyError as error:
            log.critical("Unable to parse settings!", args={'Error': error})
        return False
예제 #5
0
    def try_load() -> tuple:
        log: Log = Log.get_singleton()
        if not exists(LocalSettings._DEFAULT_PATH):
            log.warning("There is no settings yet.")
            return False, None

        with open(LocalSettings._DEFAULT_PATH) as file:
            settings: dict = load(file)
            log.info("Successfully loaded all settings!")
            return True, settings
예제 #6
0
    def __show_action(
            type: str, payload: Any,
            filename: str, encoding: str = 'utf8') -> None:
        encoded_payload_dump = dumps(
            payload, sort_keys=True, indent=3)\
            .encode(encoding)

        log: Log = Log.get_singleton()
        log.debug(
            f"Processing '{type}' message for '{filename}'...:"
            f"\n{encoded_payload_dump.decode()}",
            origin=__file__, is_file=True)
예제 #7
0
    def __validate_serialized_data(clusters: list) -> bool:
        log: Log = Log.get_singleton()
        if not clusters:
            log.error(
                "D'oh! There is no cluster.",
                origin='Markdown'
            )
            return False

        for i in range(len(clusters)):
            cluster: Cluster = clusters[i]
            if not cluster.is_valid():
                log.error(
                    "D'oh! This cluster is invalid.",
                    origin='Markdown',
                    args={
                        'Cluster': cluster.to_string(),
                        'Blame': cluster.blame()
                    }
                )
                return False

            projects: list = cluster.get_projects()
            for j in range(len(projects)):
                project: Project = projects[j]
                if not project.is_valid():
                    log.error(
                        "D'oh! This project is invalid.",
                        origin='Markdown',
                        args={
                            'Project': project.to_string(),
                            'Blame': project.blame()
                        }
                    )
                    return False

                workloads: list = project.get_workloads()
                for k in range(len(workloads)):
                    workload: Workload = workloads[k]
                    if not workload.is_valid():
                        log.error(
                            "D'oh! This workload is invalid.",
                            origin='Markdown',
                            args={
                                'Workload': workload.to_string(),
                                'Blame': workload.blame()
                            }
                        )
                        return False
        return True
예제 #8
0
    def build_report(clusters: list) -> None:
        log: Log = Log.get_singleton()

        if not MarkdownMediator.__validate_serialized_data(clusters):
            log.error(
                "Unable to build report without valid data!",
                origin='Markdown'
            )
            return

        if not exists(MarkdownMediator._DEFAULT_DIR):
            log.info(
                "Looks like it's your first time generating a report, "
                "let me create a new folder to save all snapshots.",
                origin='Markdown'
            )

            mkdir(MarkdownMediator._DEFAULT_DIR)

        log.info(
            "Great! All entries are valid to proceed with "
            "report building.", origin='Markdown'
        )

        templates: dict = app_config['templates']
        templates = MarkdownMediator.__load_all_templates(
            templates)

        time: datetime = None
        path: str = None
        time, path = MarkdownMediator.__get_unique_report_id()
        report = MarkdownMediator.__make_report(templates, time, clusters)
        MarkdownMediator.__save_report(path, report)

        clusters_data: list = []
        for i in range(len(clusters)):
            cluster: Cluster = clusters[i]
            clusters_data.append(cluster.to_string())

        ltv: LocalTestVars = LocalTestVars(__file__, 'entries')
        ltv.handle(clusters_data)

        log.info(
            f"Done! Your report is at '{path}'.",
            origin='Markdown'
        )
예제 #9
0
def confirm_input_dialog(question: str, nullable: bool = False) -> str:
    log: Log = Log.get_singleton()
    result: str = None
    while True:
        log.warning(question)
        result = input()

        if nullable:
            if is_null_or_whitespace(result):
                log.error("This answer is invalid, try again!")
                continue

        log.warning("Are you sure? (Y/N)")
        response: str = input()
        if not response or response.lower() != 'y':
            continue
        break
    return result
예제 #10
0
def ask_for_new_credentials() -> None:
    r_base_url: str = app_config['rancher']['base_url']

    log: Log = Log.get_singleton()
    log.warning(
        "Provide your credentials to access Rancher API.\n"
        "If you don't have any API key yet, consider to visit:\n"
        f"\t{format_url(r_base_url, app_config['static']['api_keys'])}")

    r_username = confirm_input_dialog(
        "Insert your Rancher Access Key (username):")
    r_password = confirm_input_dialog(
        "Insert your Rancher Secret Key (password):")

    app_config['rancher']['username'] = r_username
    app_config['rancher']['password'] = r_password

    LocalSettings.save()
예제 #11
0
    def __log_action(
            type: str, payload: Any,
            filename: str, encoding: str = 'utf8') -> None:
        from os import path, makedirs
        if not path.exists(LocalTestVars.__LOGS_FOLDER):
            makedirs(LocalTestVars.__LOGS_FOLDER)

        log: Log = Log.get_singleton()
        log.debug(
            f"Saving {type} log...", origin=__file__, is_file=True)

        with open(
                f"{LocalTestVars.__LOGS_FOLDER}/test.{filename}.log",
                "w", encoding=encoding) as log_file:
            encoded_payload_dump = dumps(
                payload, sort_keys=True,
                indent=3, ensure_ascii=False)\
                .encode(encoding)
            log_file.write(encoded_payload_dump.decode())
예제 #12
0
    def __validate_credentials() -> bool:
        log: Log = Log.get_singleton()
        log.info("Hold on, let me validate your credentials to proceed...",
                 origin='Rancher')

        status_code: int = 0
        content: dict = {}
        status_code, content = RancherMediator.__get_response()
        if status_code != 200:
            log.error(
                "Unable to authenticate! Consider to check your credentials.",
                origin='Rancher',
                args={
                    'Status Code': status_code,
                    'Message': content.get('message')
                })
            return False

        log.info("Cool! I'm ready to use Rancher API :D", origin='Rancher')
        return True
예제 #13
0
    def handle(self, payload: Any) -> None:
        args = self.__parser.parse_args()
        log: Log = Log.get_singleton()

        if not self.__displayed:
            from sys import argv
            if len(argv[1:]) > 0:
                log.debug(
                    self.__parser.description,
                    origin=__file__, is_file=True)
                self.__displayed = True

        if payload and args.show:
            LocalTestVars.__show_action(
                self.__type, payload,
                self.__filename, self.__encoding)
        if payload and args.log:
            LocalTestVars.__log_action(
                self.__type, payload,
                self.__filename, self.__encoding)
예제 #14
0
    def __load_all_templates(templates: dict) -> dict:
        log: Log = Log.get_singleton()
        log.info(
            "Gimme a sec... Let me organize these "
            "templates real quick!", origin='Markdown'
        )

        reports: dict = templates['reports']
        for key, value in reports.items():
            reports[key] = MarkdownMediator.__load_template(key, value)

        tables: dict = templates['tables']
        for key1, value1 in tables.items():
            table: dict = value1
            for key2, value2 in table.items():
                tables[key1][key2] = MarkdownMediator.__load_template(
                    f"{key1}-{key2}", value2)

        templates['reports'] = reports
        templates['tables'] = tables
        return templates
예제 #15
0
    def __try_fetch_clusters() -> bool:
        log: Log = Log.get_singleton()
        log.info("Let me take a look into your clusters...", origin='Rancher')

        status_code: int = 0
        content: dict = {}
        path: str = app_config['static']['clusters']
        status_code, content = RancherMediator.__get_response(path)
        if status_code != 200:
            RancherMediator.__handle_bad_response(status_code, content)
            return False

        clusters: list = []
        data: list = content.get('data')
        for i in range(len(data)):
            cluster_data: dict = data[i]
            cluster_id: str = cluster_data.get('id')
            cluster_name: str = cluster_data.get('name')
            cluster: dict = {'id': cluster_id, 'name': cluster_name}
            clusters.append(cluster)

        RancherMediator.__add_key_value_pair('clusters', clusters)
        return True
예제 #16
0
    def __try_fetch_workloads(project: dict) -> bool:
        project_id: str = project.get('id')
        project_name: str = project.get('name')
        project_links: dict = project.pop('links')

        log: Log = Log.get_singleton()
        log.info(
            "Seeking for all workloads inside project "
            f"'{project_name}' [ID: {project_id}]...",
            origin='Rancher')

        status_code: int = 0
        content: dict = {}
        path: str = project_links.get('workloads')
        status_code, content = RancherMediator.__get_response(path, raw=True)
        if status_code != 200:
            RancherMediator.__handle_bad_response(status_code, content)
            return False

        workloads: list = []
        data: list = content.get('data')
        for i in range(len(data)):
            workload_data: dict = data[i]
            workload_id: str = workload_data.get('id')
            workload_name: str = workload_data.get('name')
            workload_containers: list = workload_data.get('containers')
            workload_namespace: str = workload_data.get('namespaceId')
            workload: dict = {
                'id': workload_id,
                'name': workload_name,
                'containers': workload_containers,
                'namespace': workload_namespace
            }
            workloads.append(workload)

        project['workloads'] = workloads
        return True
예제 #17
0
def yes_or_no_input_dialog(question: str) -> bool:
    log: Log = Log.get_singleton()
    log.warning(f'{question} (Y/N)')
    response: str = input()
    return response and response.lower() == 'y'
예제 #18
0
    def core() -> None:
        log: Log = Log.get_singleton()

        while True:
            if not RancherMediator.__validate_credentials():
                if yes_or_no_input_dialog(
                        "Do you want to retry with new credentials?"):
                    ask_for_new_credentials()
                    continue
                else:
                    break

            if not RancherMediator.__try_fetch_clusters():
                log.error(
                    "Unable to fetch any cluster! Therefore, I cannot proceed...",
                    origin='Rancher')
                break

            clusters: list = []
            _, clusters = RancherMediator.__try_get_value('clusters')

            log.info("Clusters detected in Rancher!",
                     origin='Rancher',
                     args={'Number of clusters': len(clusters)})

            for i in range(len(clusters)):
                cluster: dict = clusters[i]
                if not RancherMediator.__try_fetch_projects(cluster):
                    log.warning(
                        "Well... There is no project for "
                        f"cluster '{cluster.get('name')}'.",
                        origin='Rancher')
                    continue

                projects: list = cluster.get('projects')

                log.info(
                    f"Projects detected in cluster '{cluster.get('name')}'!",
                    origin='Rancher',
                    args={'Number of projects': len(projects)})

                for i in range(len(projects)):
                    project: dict = projects[i]
                    if not RancherMediator.__try_fetch_workloads(project):
                        log.warning(
                            "Well... There is no workload for "
                            f"project '{project.get('name')}' "
                            f"from cluster '{cluster.get('name')}'.",
                            origin='Rancher')
                        continue

                    workloads: list = project.get('workloads')

                    log.info(
                        f"Workloads detected in project '{project.get('name')}'"
                        f" from cluster '{cluster.get('name')}'!",
                        origin='Rancher',
                        args={'Number of projects': len(workloads)})

                    for j in range(len(workloads)):
                        workload: dict = workloads[j]
                        if not RancherMediator.__try_wraps_version(workload):
                            log.warning(
                                "Well... There is no container for "
                                f"workload '{workload.get('name')}' "
                                f"in project '{project.get('name')}' "
                                f"from cluster '{cluster.get('name')}'.",
                                origin='Rancher')
                            continue
                RancherMediator.__try_update_value('clusters', clusters)

            entries: dict = RancherMediator.__get_entries()

            clusters: list = []
            clusters_data: list = entries.get('clusters')
            for i in range(len(clusters_data)):
                cluster_data: dict = clusters_data[i]
                cluster: Cluster = Cluster()
                cluster.serialize(cluster_data)
                clusters.append(cluster)

            MarkdownMediator.build_report(clusters)
            break

        log.warning("All services are preparing to shutdown...",
                    origin='Rancher')