import datetime import os import sys from typing import Optional, Any, List from app import app from app.extensions import db from app.models.bridges import BridgeConf, Bridge from app.models.base import Group from app.terraform.terraform import TerraformAutomation class BridgeAutomation(TerraformAutomation): template: str """ Terraform configuration template using Jinja 2. """ template_parameters: List[str] """ List of parameters to be read from the application configuration for use in the templating of the Terraform configuration. """ max_bridges = sys.maxsize # TODO: Only enable providers that have details configured enabled = True def tf_prehook(self) -> Optional[Any]: # pylint: disable=useless-return return None def tf_generate(self) -> None: self.tf_write( self.template, groups=Group.query.all(), bridgeconfs=BridgeConf.query.filter( BridgeConf.destroyed.is_(None), BridgeConf.provider == self.provider ).all(), global_namespace=app.config['GLOBAL_NAMESPACE'], terraform_modules_path=os.path.join(*list(os.path.split(app.root_path))[:-1], 'terraform-modules'), backend_config=f"""backend "http" {{ lock_address = "{app.config['TFSTATE_BACKEND']}/{self.short_name}" unlock_address = "{app.config['TFSTATE_BACKEND']}/{self.short_name}" address = "{app.config['TFSTATE_BACKEND']}/{self.short_name}" }}""", **{ k: app.config[k.upper()] for k in self.template_parameters } ) def tf_posthook(self, *, prehook_result: Any = None) -> None: outputs = self.tf_output() for output in outputs: if output.startswith('bridge_hashed_fingerprint_'): parts = outputs[output]['value'].split(" ") if len(parts) < 2: continue bridge = Bridge.query.filter(Bridge.id == output[len('bridge_hashed_fingerprint_'):]).first() bridge.nickname = parts[0] bridge.hashed_fingerprint = parts[1] bridge.terraform_updated = datetime.datetime.utcnow() if output.startswith('bridge_bridgeline_'): parts = outputs[output]['value'].split(" ") if len(parts) < 4: continue bridge = Bridge.query.filter(Bridge.id == output[len('bridge_bridgeline_'):]).first() del parts[3] bridge.bridgeline = " ".join(parts) bridge.terraform_updated = datetime.datetime.utcnow() db.session.commit() @classmethod def active_bridges_count(self) -> int: active_bridges = Bridge.query.filter( Bridge.provider == self.provider, Bridge.destroyed.is_(None), ).all() return len(active_bridges)