import json from peewee import * from analyst.libs import ( consts, util ) from . import base USE_LOCAL_DB = True class TagsField(TextField): def python_value(self, value): return json.loads(value) def db_value(self, value): return json.dumps(value) class JsonField(TextField): def python_value(self, value): return json.loads(value) def db_value(self, value): return json.dumps(value) class CloudAsset(base.BaseModel): class Meta: db_table = 'cloud_assets' id = IntegerField(primary_key=True) env = CharField(max_length=32, default='') provider = CharField(max_length=32, default='') # aws, gcp account_id = CharField(max_length=64, default='') # '1234567' for AWS, 'dbaas-prod' for GCP region = CharField(max_length=32, default='') # us-west-2, us-east1 product = CharField(max_length=32, default='') # ec2, elb, etc rid = CharField(max_length=256, default='') # cloud resource id rname = CharField(max_length=256, default='') # cloud resource name resource_created_at = DateTimeField() # the create timestamp of cloud resource, not the db record resource_deleted_at = DateTimeField(default=None, null=True) created_at = DateTimeField() updated_at = DateTimeField() service_type = CharField(max_length=32, default='') # dedicated, serverless _usedby = CharField(column_name='usedby', max_length=32, default='') # customer-tidb, dbaas-control-plane-shoot, dbaas-control-plane-seed, etc. vpc_name = CharField(max_length=128, default='') # prod-1372813089454534876-eks-us-west-2-56999911 vpc_id = CharField(max_length=128, default='') # vpc-017c8c6639dbe8461 vpc_type = CharField(max_length=32, default='') # shoot, seed, base shoot_id = CharField(max_length=32, default='') # for gardener only k8s_name = CharField(max_length=128, default='') # prod-1372813089454534876-eks-us-west-2-56999911 network_namespace = CharField(max_length=64, default='') # prod-123 _network_name = CharField(column_name='network_name', max_length=64, default='') # eks-us-west-2 arch = CharField(max_length=32, default='') tenant_id = CharField(max_length=64, default='') project_id = CharField(max_length=64, default='') cluster_id = CharField(max_length=64, default='') # component: pd, tiproxy, tidb, tikv, tiflash, br, ticdc, import, admin component = CharField(max_length=64, default='') member = CharField(max_length=64, default='') # only set if the cluster_id is set and isn't 'admin'. 'db-tidb-0' resource_tags = TextField(default='[]') status = CharField(max_length=32, default='') # 'in-use', 'may-leaked', 'leaked', 'unknown', 'cleaned' reason = CharField(max_length=2048, default='') link = CharField(max_length=1024, default='') extra_info = JsonField(default=lambda: {}) @property def usedby(self): return self._usedby @usedby.setter def usedby(self, value: str): self._usedby = value.lower() @property def network_name(self): return self._network_name @network_name.setter def network_name(self, value: str): self._network_name = value.lower() if 'aws' in value or 'gcp' in value or self.shoot_id: self.arch = consts.Arch.Gardener elif self.belong_to_3layers_arch(): self.arch = consts.Arch.ThreeLayers else: self.arch = consts.Arch.CloudNative def amend(self): if util.CLUSTER_ID_RE.match(self.cluster_id): self.usedby = consts.UsedBy.CustomerTiDB def belong_to_3layers_arch(self) -> bool: prefix = consts.BELONG_TO_3LAYERS_ARCH_PREFIX.format(env=self.env) return any([ self.rname.startswith(prefix), # VPC 'dedicated-prod-us-west-2-5032057922c27e89c58c1cc6bcedd-847fa766' self.vpc_name.startswith(prefix), # VPC 'dedicated-prod-ap-northeast-1-485cd89cbc9cdc735a3aa08f-4d4680ee' self.k8s_name.startswith(prefix) # EKS 'dedicated-staging-us-west-2-3dd2d02c596a629e9e119eaa05-5284b157' ]) def uniq_key(self) -> str: return f'{self.id}:{self.env}/{self.provider}/{self.account_id}/{self.region}/{self.product}/{self.rid}' class Owner(base.BaseModel): type = CharField(max_length=32, ) # cluster, network class CleanHistory(base.BaseModel): created_at = DateTimeField() asset = ForeignKeyField(CloudAsset, backref='clean_histories') asset_id = IntegerField(index=True) batch_id = CharField(max_length=64) result = CharField(max_length=64) reason = CharField(max_length=2048, default='') class Meta: table_name = 'clean_histories'