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
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') })
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()
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
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
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)
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
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' )
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
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()
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())
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
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)
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
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
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
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'
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')