def validate(config) -> bool: required_sections = ["kinds", "accounts"] for section in required_sections: if section not in config: raise ValueError(f"Section '{section}' not found in config") if not isinstance(config["kinds"], list) or len(config["kinds"]) == 0: raise ValueError("Error in 'kinds' section") if not isinstance(config["accounts"], dict) or len( config["accounts"]) == 0: raise ValueError("Error in 'accounts' section") default_expiration = config.get("default", {}).get("expiration") if default_expiration is not None: default_expiration = parse_delta(default_expiration) for cloud_id, account in config["accounts"].items(): for account_id, account_data in account.items(): if "name" not in account_data: raise ValueError( f"Missing 'name' for account '{cloud_id}/{account_id}") if "expiration" in account_data: account_data["expiration"] = parse_delta( account_data["expiration"]) else: if default_expiration is None: raise ValueError( f"Missing 'expiration' for account '{cloud_id}/{account_id}'" "and no default expiration defined") account_data["expiration"] = default_expiration return True
def validate(cfg: "CleanupUntaggedConfig") -> bool: config = cfg.config required_sections = ["tags", "kinds", "accounts"] for section in required_sections: if section not in config: raise ValueError(f"Section '{section}' not found in config") if not isinstance(config["tags"], list) or len(config["tags"]) == 0: raise ValueError("Error in 'tags' section") if not isinstance(config["kinds"], list) or len(config["kinds"]) == 0: raise ValueError("Error in 'kinds' section") if not isinstance(config["accounts"], dict) or len( config["accounts"]) == 0: raise ValueError("Error in 'accounts' section") default_age = config.get("default", {}).get("age") if default_age is not None: default_age = parse_delta(default_age) for cloud_id, account in config["accounts"].items(): for account_id, account_data in account.items(): if "name" not in account_data: raise ValueError( f"Missing 'name' for account '{cloud_id}/{account_id}") if "age" in account_data: account_data["age"] = parse_delta(account_data["age"]) else: if default_age is None: raise ValueError( f"Missing 'age' for account '{cloud_id}/{account_id}' and no default age defined'" ) account_data["age"] = default_age return True
def update_age(self) -> None: try: self.age = parse_delta( Config.plugin_cleanup_aws_loadbalancers.min_age) log.debug(f"Cleanup AWS Load balancers minimum age is {self.age}") except ValueError: log.error( "Error while parsing Cleanup AWS Load balancers minimum age" f" {Config.plugin_cleanup_aws_loadbalancers.min_age}") raise
def bootstrap(self) -> bool: if ArgumentParser.args.cleanup_volumes: try: self.age = parse_delta(ArgumentParser.args.cleanup_volumes_age) log.debug(f"Volume Cleanup Plugin Age {self.age}") except ValueError: log.exception( f"Error while parsing Volume Cleanup Age {ArgumentParser.args.volclean_age}" ) else: return True return False
def bootstrap(self) -> bool: if ArgumentParser.args.cleanup_aws_loadbalancers: try: self.age = parse_delta( ArgumentParser.args.cleanup_aws_loadbalancers_age) log.debug(f"AWS Loadbalancer Cleanup Plugin Age {self.age}") except ValueError: log.exception( f"Error while parsing AWS Loadbalancer " f"Cleanup Age {ArgumentParser.args.cleanup_aws_loadbalancers_age}" ) else: return True return False
def do_action(self, data: Dict) -> None: log.info("Tag Validator called") self.config.read() cg = CoreGraph() query_tag = "tagvalidate" exclusion_part = "metadata.protected == false and metadata.phantom == false and metadata.cleaned == false" tags_part = "has_key(reported.tags, expiration)" kinds_part = 'reported.kind in ["' + '", "'.join( self.config["kinds"]) + '"]' account_parts = [] for cloud_id, account in self.config["accounts"].items(): for account_id in account.keys(): account_part = ( f'(metadata.ancestors.cloud.id == "{cloud_id}" and ' f'metadata.ancestors.account.id == "{account_id}")') account_parts.append(account_part) accounts_part = "(" + " or ".join(account_parts) + ")" query = f"{exclusion_part} and {kinds_part} and {tags_part} and {accounts_part} #{query_tag} <-[0:]-" graph = cg.graph(query) commands = [] for node in graph.nodes: cloud = node.cloud(graph) account = node.account(graph) region = node.region(graph) if node.protected or node._resotocore_query_tag != query_tag: continue update_node_tag = False max_expiration = (self.config["accounts"].get(cloud.id, {}).get( account.id, {}).get("expiration")) max_expiration_str = delta_to_str(max_expiration) node_expiration_str = node.tags.get("expiration") try: node_expiration = parse_delta(node_expiration_str) except (AssertionError, ValueError): log_msg = ( f"Invalid expiration tag value {node_expiration_str}" f" - updating tag to {max_expiration_str}") node.log(log_msg) log.error(f"{log_msg} on {node.rtdname} in {cloud.rtdname}" f" {account.rtdname} {region.rtdname}") update_node_tag = True else: if max_expiration < node_expiration: log_msg = ( f"Current expiration tag value {node_expiration_str} is larger" f" than {max_expiration_str} - updating tag") node.log(log_msg) log.error(f"{log_msg} on {node.rtdname}") update_node_tag = True if update_node_tag: commands.append( f"query id({node._resotocore_id}) | tag update --nowait expiration {max_expiration_str}" ) cg.patch_nodes(graph) for command in commands: if ArgumentParser.args.tagvalidator_dry_run: log.debug(f"Tag validator dry run - not executing: {command}") continue for response in cg.execute(command): log.debug(f"Response: {response}")
def validate(config: "CleanupVolumesConfig") -> bool: parse_delta(config.min_age) return True
def validate(config: "CleanupAWSLoadbalancersConfig") -> bool: parse_delta(config.min_age) return True