class Hook(db.Model, Timestamp): __versioned__ = {} __tablename__ = 'hooks' id = db.Column( postgresql.UUID(as_uuid=True), server_default=text("gen_random_uuid()"), nullable=False, primary_key=True, ) commit_sha = db.Column( db.String(256), index=True, nullable=True, ) headers = db.Column( postgresql.JSONB(), nullable=False, ) payload = db.Column( postgresql.JSONB(), nullable=False, ) processed = db.Column( db.Boolean, nullable=False, default=False, ) version_id = db.Column(db.Integer, nullable=False) __mapper_args__ = {"version_id_col": version_id}
class Deployment(db.Model, Timestamp): __versioned__ = {} __tablename__ = 'deployments' id = db.Column( postgresql.UUID(as_uuid=True), server_default=text("gen_random_uuid()"), nullable=False, primary_key=True ) application_id = db.Column( postgresql.UUID(as_uuid=True), db.ForeignKey('project_applications.id'), nullable=False, ) release = db.Column(postgresql.JSONB(), nullable=False) version_id = db.Column( db.Integer, nullable=False ) complete = db.Column( db.Boolean, nullable=False, default=False ) error = db.Column( db.Boolean, nullable=False, default=False ) error_detail = db.Column( db.String(2048), nullable=True, ) deploy_metadata = db.Column( postgresql.JSONB(), nullable=True, ) deploy_log = db.Column( db.Text(), nullable=True, ) __mapper_args__ = { "version_id_col": version_id } @property def release_object(self): return Release.query.filter_by(id=self.release.get("id", None)).first()
class Image(db.Model, Timestamp): __versioned__ = {} __tablename__ = 'project_app_images' id = db.Column(postgresql.UUID(as_uuid=True), server_default=text("gen_random_uuid()"), nullable=False, primary_key=True) application_id = db.Column( postgresql.UUID(as_uuid=True), db.ForeignKey('project_applications.id'), nullable=False, ) repository_name = db.Column( db.String(256), nullable=False, ) image_id = db.Column( db.String(256), nullable=True, ) version = db.Column( db.Integer, nullable=False, ) version_id = db.Column( db.Integer, nullable=False, ) built = db.Column(db.Boolean, nullable=False, default=False) error = db.Column(db.Boolean, nullable=False, default=False) error_detail = db.Column( db.String(2048), nullable=True, ) deleted = db.Column(db.Boolean, nullable=False, default=False) build_slug = db.Column( db.String(1024), nullable=False, ) dockerfile = db.Column( db.Text(), nullable=True, ) procfile = db.Column( db.Text(), nullable=True, ) processes = db.Column( postgresql.JSONB(), nullable=True, ) image_metadata = db.Column( postgresql.JSONB(), nullable=True, ) image_build_log = db.Column( db.Text(), nullable=True, ) __mapper_args__ = {"version_id_col": version_id} @property def asdict(self): return { "id": str(self.id), "repository": self.repository_name, "tag": str(self.version), "processes": self.processes, } def docker_pull_credentials(self, secret): return generate_docker_credentials( secret=secret, resource_type="repository", resource_name=self.repository_name, resource_actions=["pull"], ) def buildargs(self, reader): return { c.name: c.read_value(reader) for c in self.application.configurations if c.buildtime } @property def commit_sha(self): if self.image_metadata is None or self.image_metadata.get( 'sha') is None: return "null" return self.image_metadata.get('sha')
class Configuration(db.Model, Timestamp): __versioned__ = {} __tablename__ = 'project_app_configurations' id = db.Column(postgresql.UUID(as_uuid=True), server_default=text("gen_random_uuid()"), nullable=False, primary_key=True) application_id = db.Column( postgresql.UUID(as_uuid=True), db.ForeignKey('project_applications.id'), nullable=False, ) name = db.Column( CIText(), nullable=False, ) value = db.Column( db.String(2048), nullable=False, ) key_slug = db.Column( db.Text(), nullable=True, ) build_key_slug = db.Column( db.Text(), nullable=True, ) version_id = db.Column(db.Integer, nullable=False) deleted = db.Column(db.Boolean, nullable=False, default=False) secret = db.Column(db.Boolean, nullable=False, default=False) buildtime = db.Column(db.Boolean, nullable=False, default=False) UniqueConstraint(application_id, name) __mapper_args__ = {"version_id_col": version_id} @property def asdict(self): return { "id": str(self.id), "name": self.name, "version_id": self.version_id, "secret": self.secret, } @property def envconsul_statement(self): directive = 'secret' if self.secret else 'prefix' path = self.key_slug.split(':', 1)[1] return (f'{directive} {{\n' ' no_prefix = true\n' f' path = "{path}"\n' '}') def read_value(self, reader): if self.secret: if self.buildtime: payload = reader.read(self.build_key_slug.split(':', 1)[1], build=True, secret=True) return payload['data'][self.name] return '**secret**' return self.value
class Release(db.Model, Timestamp): __versioned__ = {} __tablename__ = 'project_app_releases' id = db.Column(postgresql.UUID(as_uuid=True), server_default=text("gen_random_uuid()"), nullable=False, primary_key=True) application_id = db.Column( postgresql.UUID(as_uuid=True), db.ForeignKey('project_applications.id'), nullable=False, ) platform = db.Column(platform_version, nullable=False, default='wind') image = db.Column(postgresql.JSONB(), nullable=False) configuration = db.Column(postgresql.JSONB(), nullable=False) image_changes = db.Column(postgresql.JSONB(), nullable=False) configuration_changes = db.Column(postgresql.JSONB(), nullable=False) version_id = db.Column(db.Integer, nullable=False) repository_name = db.Column( db.String(256), nullable=False, ) release_id = db.Column( db.String(256), nullable=True, ) version = db.Column( db.Integer, nullable=False, ) built = db.Column(db.Boolean, nullable=False, default=False) error = db.Column(db.Boolean, nullable=False, default=False) error_detail = db.Column( db.String(2048), nullable=True, ) deleted = db.Column(db.Boolean, nullable=False, default=False) dockerfile = db.Column( db.Text(), nullable=True, ) release_metadata = db.Column( postgresql.JSONB(), nullable=True, ) release_build_log = db.Column( db.Text(), nullable=True, ) __mapper_args__ = {"version_id_col": version_id} @property def valid(self): return ((self.image_object is not None) and all(v is not None for v in self.configuration_objects.values())) @property def deposed(self): return not self.valid @property def deposed_reason(self): reasons = [] if self.image_object is None: reasons.append( f'<code>Image {self.image["repository"]}:{self.image["tag"]} no longer exists!</code>' ) for configuration, configuration_serialized in self.configuration.items( ): configuration_object = Configuration.query.filter_by( id=configuration_serialized["id"]).first() if configuration_object is None: reasons.append( f'<code>Configuration for {configuration} no longer exists!</code>' ) return reasons @property def asdict(self): return { "id": str(self.id), "application_id": str(self.application_id), "platform": self.platform, "image": self.image, "configuration": self.configuration, } @property def configuration_objects(self): return { k: Configuration.query.filter_by(id=v["id"]).first() for k, v in self.configuration.items() } @property def envconsul_configurations(self): configurations = {} environment_statements = '\n'.join([ c.envconsul_statement for c in self.configuration_objects.values() if c is not None ]) for proc_name, proc in self.image_object.processes.items(): custom_env = json.dumps( [f"{key}={value}" for key, value in proc['env']]) exec_statement = ( 'exec {\n' f' command = {json.dumps(proc["cmd"])}\n' ' env = {\n' f' custom = {custom_env}\n' ' blacklist = ["CONSUL_*", "VAULT_*", "KUBERNETES_*"]\n' ' }\n' '}') configurations[proc_name] = '\n'.join( [exec_statement, environment_statements]) return configurations @property def image_object(self): return Image.query.filter_by(id=self.image.get("id", None)).first() @property def processes(self): return { k: v for k, v in self.image_object.processes.items() if not k.startswith('release') } @property def release_commands(self): return { k: v for k, v in self.image_object.processes.items() if k.startswith('release') } def docker_pull_credentials(self, secret): return generate_docker_credentials( secret=secret, resource_type="repository", resource_name=self.repository_name, resource_actions=["pull"], ) def image_pull_secrets(self, secret, registry_urls=None): return generate_kubernetes_imagepullsecrets( secret=secret, registry_urls=registry_urls, resource_type="repository", resource_name=self.repository_name, resource_actions=["pull"], ) @property def commit_sha(self): if self.release_metadata is None or self.release_metadata.get( 'sha') is None: return self.image_object.commit_sha return self.release_metadata.get('sha')