Exemplo n.º 1
0
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}
Exemplo n.º 2
0
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()
Exemplo n.º 3
0
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')
Exemplo n.º 4
0
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
Exemplo n.º 5
0
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')