iact3/cli_modules/list.py (98 lines of code) (raw):

# -*- coding: utf-8 -*- import asyncio import logging from iact3.cli import CliCore from iact3.config import BaseConfig, DEFAULT_CONFIG_FILE, DEFAULT_PROJECT_ROOT from iact3.generate_params import IAC_NAME from iact3.plugin.ros import StackPlugin from iact3.stack import SYS_TAGS LOG = logging.getLogger(__name__) class List: ''' List stacks which were created by Iact3 for all regions. ''' @CliCore.longform_param_required('project_path') def __init__(self, regions: str = None, config_file: str = None, project_path: str = None): ''' :param regions: comma separated list of regions to delete from, default will scan all regions :param config_file: path to a config file :param project_path: root path of the project relative to config file ''' self.regions = regions self.config_file = config_file self.project_path = project_path @classmethod async def create(cls, regions: str = None, config_file: str = None, project_path: str = None, tags: dict = None, stack_id: str = None): credential = cls.get_credential(config_file, project_path) if regions: regions = regions.split(',') else: region_plugin = StackPlugin(region_id='cn-hangzhou', credential=credential) regions = await region_plugin.get_regions() list_tasks = [] if tags: tags.update(SYS_TAGS) else: tags = SYS_TAGS for region in regions: stack_plugin = StackPlugin(region_id=region, credential=credential) list_tasks.append( asyncio.create_task(stack_plugin.fetch_all_stacks(tags, stack_id=stack_id)) ) stacks = await asyncio.gather(*list_tasks) all_stacks, project_length, test_length, stack_name_length = cls._get_all_stacks(stacks) if not all_stacks: LOG.info('can not find any stack.') return header = f'ProjectName{" "*project_length}TestName{" "*test_length}StackName{" "*stack_name_length}Region' LOG.info(header) column = '{} {} {} {}' for stack in all_stacks: project_name = cls._format_name(stack['ProjectName'], project_length) test_name = cls._format_name(stack['TestName'], test_length) stack_name = cls._format_name(stack['StackName'], stack_name_length) LOG.info(column.format(project_name, test_name, stack_name, stack['RegionId'])) return all_stacks @classmethod def _get_all_stacks(cls, stacks): all_stacks = [] longest_project_name = '' longest_test_name = '' longest_stack_name = '' for region_stacks in stacks: for stack in region_stacks: stack_name = stack['StackName'] if len(stack_name) > len(longest_stack_name): longest_stack_name = stack_name tags = stack['Tags'] for tag in tags: if tag['Key'] == f'{IAC_NAME}-test-name': test_name = tag['Value'] if len(test_name) > len(longest_test_name): longest_test_name = test_name stack['TestName'] = test_name elif tag['Key'] == f'{IAC_NAME}-project-name': project_name = tag['Value'] if len(project_name) > len(longest_project_name): longest_project_name = project_name stack['ProjectName'] = project_name elif tag['Key'] == f'{IAC_NAME}-id': stack['TestId'] = tag['Value'] all_stacks.append(stack) return all_stacks, len(longest_project_name), len(longest_test_name), len(longest_stack_name) @classmethod def _format_name(cls, name, length): if len(name) < length: name += f'{" " * (length - len(name))}' return name @classmethod def get_credential(cls, config_file: str = None, project_path: str = None): base_config = BaseConfig.create( project_config_file=config_file or DEFAULT_CONFIG_FILE, project_path=project_path or DEFAULT_PROJECT_ROOT, fail_ok=True ) return base_config.get_credential()