예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
 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
예제 #4
0
 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
예제 #5
0
 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
예제 #6
0
    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}")
예제 #7
0
 def validate(config: "CleanupVolumesConfig") -> bool:
     parse_delta(config.min_age)
     return True
예제 #8
0
 def validate(config: "CleanupAWSLoadbalancersConfig") -> bool:
     parse_delta(config.min_age)
     return True