Module materialize.checks.all_checks.owners

Expand source code Browse git
# Copyright Materialize, Inc. and contributors. All rights reserved.
#
# Use of this software is governed by the Business Source License
# included in the LICENSE file at the root of this repository.
#
# As of the Change Date specified in that file, in accordance with
# the Business Source License, use of this software will be governed
# by the Apache License, Version 2.0.
from textwrap import dedent

from materialize.checks.actions import Testdrive
from materialize.checks.checks import Check
from materialize.checks.executors import Executor
from materialize.mz_version import MzVersion


class Owners(Check):
    def _create_objects(self, role: str, i: int, expensive: bool = False) -> str:
        s = dedent(
            f"""
            $[version>=5200] postgres-execute connection=postgres://mz_system@${{testdrive.materialize-internal-sql-addr}}
            GRANT CREATE ON DATABASE materialize TO {role}
            GRANT CREATE ON SCHEMA materialize.public TO {role}
            GRANT CREATE ON CLUSTER {self._default_cluster()} TO {role}
            $[version>=5900] postgres-execute connection=postgres://mz_system@${{testdrive.materialize-internal-sql-addr}}
            GRANT CREATEDB ON SYSTEM TO {role}
            $[version<5900] postgres-execute connection=postgres://mz_system@${{testdrive.materialize-internal-sql-addr}}
            ALTER ROLE {role} CREATEDB
            $ postgres-execute connection=postgres://{role}@${{testdrive.materialize-sql-addr}}
            CREATE DATABASE owner_db{i}
            CREATE SCHEMA owner_schema{i}
            CREATE CONNECTION owner_kafka_conn{i} FOR KAFKA {self._kafka_broker()}
            CREATE CONNECTION owner_csr_conn{i} FOR CONFLUENT SCHEMA REGISTRY URL '${{testdrive.schema-registry-url}}'
            CREATE TYPE owner_type{i} AS LIST (ELEMENT TYPE = text)
            CREATE TABLE owner_t{i} (c1 int, c2 owner_type{i})
            CREATE INDEX owner_i{i} ON owner_t{i} (c2)
            CREATE VIEW owner_v{i} AS SELECT * FROM owner_t{i}
            CREATE MATERIALIZED VIEW owner_mv{i} AS SELECT * FROM owner_t{i}
            CREATE SECRET owner_secret{i} AS 'MY_SECRET'
            """
        )
        if expensive:
            s += dedent(
                f"""
                $[version<9300] postgres-execute connection=postgres://{role}@${{testdrive.materialize-sql-addr}}
                CREATE SOURCE owner_source{i} FROM LOAD GENERATOR COUNTER (SCALE FACTOR 0.01)
                $[version>=9300] postgres-execute connection=postgres://{role}@${{testdrive.materialize-sql-addr}}
                CREATE SOURCE owner_source{i} FROM LOAD GENERATOR COUNTER
                $ postgres-execute connection=postgres://{role}@${{testdrive.materialize-sql-addr}}
                CREATE SINK owner_sink{i} FROM owner_mv{i} INTO KAFKA CONNECTION owner_kafka_conn{i} (TOPIC 'sink-sink-owner{i}') FORMAT AVRO USING CONFLUENT SCHEMA REGISTRY CONNECTION owner_csr_conn{i} ENVELOPE DEBEZIUM
                CREATE CLUSTER owner_cluster{i} REPLICAS (owner_cluster_r{i} (SIZE '4'))
                """
            )

        return s

    def _alter_object_owners(self, i: int, expensive: bool = False) -> str:
        s = dedent(
            f"""
            $ postgres-execute connection=postgres://mz_system@${{testdrive.materialize-internal-sql-addr}}
            ALTER DATABASE owner_db{i} OWNER TO other_owner
            ALTER SCHEMA owner_schema{i} OWNER TO other_owner
            ALTER CONNECTION owner_kafka_conn{i} OWNER TO other_owner
            ALTER CONNECTION owner_csr_conn{i} OWNER TO other_owner
            ALTER TYPE owner_type{i} OWNER TO other_owner
            ALTER TABLE owner_t{i} OWNER TO other_owner
            ALTER INDEX owner_i{i} OWNER TO other_owner
            ALTER VIEW owner_v{i} OWNER TO other_owner
            ALTER MATERIALIZED VIEW owner_mv{i} OWNER TO other_owner
            ALTER SECRET owner_secret{i} OWNER TO other_owner
            """
        )
        if expensive:
            s += dedent(
                f"""
                ALTER SOURCE owner_source{i} OWNER TO other_owner
                ALTER SINK owner_sink{i} OWNER TO other_owner
                ALTER CLUSTER owner_cluster{i} OWNER TO other_owner
                """
            )

        return s

    def _drop_objects(
        self, role: str, i: int, expensive: bool = False, success: bool = True
    ) -> str:
        cmds = []
        # Drop the sink first so we can drop the materialized view without CASCADE.
        if expensive:
            cmds += [
                f"DROP SOURCE owner_source{i}",
                f"DROP SINK owner_sink{i}",
                f"DROP CLUSTER owner_cluster{i}",
            ]
        cmds += [
            f"DROP SECRET owner_secret{i}",
            f"DROP MATERIALIZED VIEW owner_mv{i}",
            f"DROP VIEW owner_v{i}",
            f"DROP INDEX owner_i{i}",
            f"DROP TABLE owner_t{i}",
            f"DROP TYPE owner_type{i}",
            f"DROP CONNECTION owner_csr_conn{i}",
            f"DROP CONNECTION owner_kafka_conn{i}",
            f"DROP SCHEMA owner_schema{i}",
            f"DROP DATABASE owner_db{i}",
        ]
        if success:
            return (
                f"$ postgres-execute connection=postgres://{role}@${{testdrive.materialize-sql-addr}}\n"
                + "\n".join(cmds)
                + "\n"
            )
        if role != "materialize":
            raise ValueError(
                "Can't check for failures with user other than materialize"
            )
        return "\n".join(
            [f"! {cmd} CASCADE\ncontains: must be owner of\n" for cmd in cmds]
        )

    def _can_run(self, e: Executor) -> bool:
        # Object owner changes weren't persisted in some cases earlier than 0.63.0.
        return self.base_version >= MzVersion.parse_mz("v0.63.0-dev")

    def initialize(self) -> Testdrive:
        return Testdrive(
            dedent(
                """
                $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                GRANT CREATEROLE ON SYSTEM TO materialize

                $[version<5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                ALTER ROLE materialize CREATEROLE

                > CREATE ROLE owner_role_01
                >[version<5900] ALTER ROLE owner_role_01 CREATEDB CREATECLUSTER

                $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                GRANT CREATEDB, CREATECLUSTER ON SYSTEM TO owner_role_01

                > CREATE ROLE other_owner
                """
            )
            + self._create_objects("owner_role_01", 1, expensive=True)
            + self._create_objects("owner_role_01", 2, expensive=True)
            + self._alter_object_owners(2, expensive=True)
        )

    def manipulate(self) -> list[Testdrive]:
        return [
            Testdrive(s)
            for s in [
                self._create_objects("owner_role_01", 3)
                + self._create_objects("owner_role_01", 4)
                + self._alter_object_owners(4)
                + dedent(
                    """
                    $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                    GRANT CREATEROLE ON SYSTEM TO materialize

                    $[version<5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                    ALTER ROLE materialize CREATEROLE

                    > CREATE ROLE owner_role_02
                    >[version<5900] ALTER ROLE owner_role_02 CREATEDB CREATECLUSTER

                    $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                    GRANT CREATEDB, CREATECLUSTER ON SYSTEM TO owner_role_02
                    """
                ),
                self._create_objects("owner_role_01", 5)
                + self._create_objects("owner_role_01", 6)
                + self._alter_object_owners(6)
                + self._create_objects("owner_role_02", 7)
                + self._create_objects("owner_role_02", 8)
                + self._alter_object_owners(8)
                + dedent(
                    """
                    $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                    GRANT CREATEROLE ON SYSTEM TO materialize

                    $[version<5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                    ALTER ROLE materialize CREATEROLE

                    > CREATE ROLE owner_role_03
                    >[version<5900] ALTER ROLE owner_role_03 CREATEDB CREATECLUSTER

                    $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                    GRANT CREATEDB, CREATECLUSTER ON SYSTEM TO owner_role_03
                    """
                ),
            ]
        ]

    def validate(self) -> Testdrive:
        return Testdrive(
            # materialize role is not allowed to drop the objects since it is
            # not the owner, verify this:
            (
                (
                    self._drop_objects("materialize", 1, success=False, expensive=True)
                    + self._drop_objects(
                        "materialize", 2, success=False, expensive=True
                    )
                    + self._drop_objects("materialize", 3, success=False)
                    + self._drop_objects("materialize", 4, success=False)
                    + self._drop_objects("materialize", 5, success=False)
                    + self._drop_objects("materialize", 6, success=False)
                    + self._drop_objects("materialize", 7, success=False)
                    + self._drop_objects("materialize", 8, success=False)
                )
                if self.base_version >= MzVersion.parse_mz("v0.51.0-dev")
                else ""
            )
            + self._create_objects("owner_role_01", 9)
            + self._create_objects("owner_role_02", 10)
            + self._create_objects("owner_role_03", 11)
            + dedent(
                """
                $ psql-execute command="\\l owner_db*"
                \\                              List of databases
                    Name    |     Owner     | Encoding | Collate | Ctype | Access privileges
                ------------+---------------+----------+---------+-------+-------------------
                 owner_db1  | owner_role_01 | UTF8     | C       | C     |
                 owner_db10 | owner_role_02 | UTF8     | C       | C     |
                 owner_db11 | owner_role_03 | UTF8     | C       | C     |
                 owner_db2  | other_owner   | UTF8     | C       | C     |
                 owner_db3  | owner_role_01 | UTF8     | C       | C     |
                 owner_db4  | other_owner   | UTF8     | C       | C     |
                 owner_db5  | owner_role_01 | UTF8     | C       | C     |
                 owner_db6  | other_owner   | UTF8     | C       | C     |
                 owner_db7  | owner_role_02 | UTF8     | C       | C     |
                 owner_db8  | other_owner   | UTF8     | C       | C     |
                 owner_db9  | owner_role_01 | UTF8     | C       | C     |


                $ psql-execute command="\\dn owner_schema*"
                \\        List of schemas
                      Name      |     Owner
                ----------------+---------------
                 owner_schema1  | owner_role_01
                 owner_schema10 | owner_role_02
                 owner_schema11 | owner_role_03
                 owner_schema2  | other_owner
                 owner_schema3  | owner_role_01
                 owner_schema4  | other_owner
                 owner_schema5  | owner_role_01
                 owner_schema6  | other_owner
                 owner_schema7  | owner_role_02
                 owner_schema8  | other_owner
                 owner_schema9  | owner_role_01

                $ psql-execute command="\\dt owner_t*"
                \\             List of relations
                 Schema |   Name    | Type  |     Owner
                --------+-----------+-------+---------------
                 public | owner_t1  | table | owner_role_01
                 public | owner_t10 | table | owner_role_02
                 public | owner_t11 | table | owner_role_03
                 public | owner_t2  | table | other_owner
                 public | owner_t3  | table | owner_role_01
                 public | owner_t4  | table | other_owner
                 public | owner_t5  | table | owner_role_01
                 public | owner_t6  | table | other_owner
                 public | owner_t7  | table | owner_role_02
                 public | owner_t8  | table | other_owner
                 public | owner_t9  | table | owner_role_01

                $ psql-execute command="\\di owner_i*"
                \\                   List of relations
                 Schema |   Name    | Type  |     Owner     |   Table
                --------+-----------+-------+---------------+-----------
                 public | owner_i1  | index | owner_role_01 | owner_t1
                 public | owner_i10 | index | owner_role_02 | owner_t10
                 public | owner_i11 | index | owner_role_03 | owner_t11
                 public | owner_i2  | index | other_owner   | owner_t2
                 public | owner_i3  | index | owner_role_01 | owner_t3
                 public | owner_i4  | index | other_owner   | owner_t4
                 public | owner_i5  | index | owner_role_01 | owner_t5
                 public | owner_i6  | index | other_owner   | owner_t6
                 public | owner_i7  | index | owner_role_02 | owner_t7
                 public | owner_i8  | index | other_owner   | owner_t8
                 public | owner_i9  | index | owner_role_01 | owner_t9

                $ psql-execute command="\\dv owner_v*"
                \\             List of relations
                 Schema |   Name    | Type |     Owner
                --------+-----------+------+---------------
                 public | owner_v1  | view | owner_role_01
                 public | owner_v10 | view | owner_role_02
                 public | owner_v11 | view | owner_role_03
                 public | owner_v2  | view | other_owner
                 public | owner_v3  | view | owner_role_01
                 public | owner_v4  | view | other_owner
                 public | owner_v5  | view | owner_role_01
                 public | owner_v6  | view | other_owner
                 public | owner_v7  | view | owner_role_02
                 public | owner_v8  | view | other_owner
                 public | owner_v9  | view | owner_role_01

                $ psql-execute command="\\dmv owner_mv*"
                \\                    List of relations
                 Schema |    Name    |       Type        |     Owner
                --------+------------+-------------------+---------------
                 public | owner_mv1  | materialized view | owner_role_01
                 public | owner_mv10 | materialized view | owner_role_02
                 public | owner_mv11 | materialized view | owner_role_03
                 public | owner_mv2  | materialized view | other_owner
                 public | owner_mv3  | materialized view | owner_role_01
                 public | owner_mv4  | materialized view | other_owner
                 public | owner_mv5  | materialized view | owner_role_01
                 public | owner_mv6  | materialized view | other_owner
                 public | owner_mv7  | materialized view | owner_role_02
                 public | owner_mv8  | materialized view | other_owner
                 public | owner_mv9  | materialized view | owner_role_01

                > SELECT mz_types.name, mz_roles.name FROM mz_types JOIN mz_roles ON mz_types.owner_id = mz_roles.id WHERE mz_types.name LIKE 'owner_type%'
                owner_type1  owner_role_01
                owner_type10 owner_role_02
                owner_type11 owner_role_03
                owner_type2  other_owner
                owner_type3  owner_role_01
                owner_type4  other_owner
                owner_type5  owner_role_01
                owner_type6  other_owner
                owner_type7  owner_role_02
                owner_type8  other_owner
                owner_type9  owner_role_01

                > SELECT mz_secrets.name, mz_roles.name FROM mz_secrets JOIN mz_roles ON mz_secrets.owner_id = mz_roles.id WHERE mz_secrets.name LIKE 'owner_secret%'
                owner_secret1  owner_role_01
                owner_secret10 owner_role_02
                owner_secret11 owner_role_03
                owner_secret2  other_owner
                owner_secret3  owner_role_01
                owner_secret4  other_owner
                owner_secret5  owner_role_01
                owner_secret6  other_owner
                owner_secret7  owner_role_02
                owner_secret8  other_owner
                owner_secret9  owner_role_01

                > SELECT mz_sources.name, mz_roles.name FROM mz_sources JOIN mz_roles ON mz_sources.owner_id = mz_roles.id WHERE mz_sources.name LIKE 'owner_source%' AND type = 'load-generator'
                owner_source1 owner_role_01
                owner_source2 other_owner

                > SELECT mz_sinks.name, mz_roles.name FROM mz_sinks JOIN mz_roles ON mz_sinks.owner_id = mz_roles.id WHERE mz_sinks.name LIKE 'owner_sink%'
                owner_sink1 owner_role_01
                owner_sink2 other_owner

                > SELECT mz_clusters.name, mz_roles.name FROM mz_clusters JOIN mz_roles ON mz_clusters.owner_id = mz_roles.id WHERE mz_clusters.name LIKE 'owner_cluster%'
                owner_cluster1 owner_role_01
                owner_cluster2 other_owner

                > SELECT mz_cluster_replicas.name, mz_roles.name FROM mz_cluster_replicas JOIN mz_roles ON mz_cluster_replicas.owner_id = mz_roles.id WHERE mz_cluster_replicas.name LIKE 'owner_cluster_r%'
                owner_cluster_r1 owner_role_01
                owner_cluster_r2 other_owner

                > SELECT mz_connections.name, mz_roles.name FROM mz_connections JOIN mz_roles ON mz_connections.owner_id = mz_roles.id WHERE mz_connections.name LIKE 'owner_%'
                owner_csr_conn1  owner_role_01
                owner_csr_conn10 owner_role_02
                owner_csr_conn11 owner_role_03
                owner_csr_conn2  other_owner
                owner_csr_conn3  owner_role_01
                owner_csr_conn4  other_owner
                owner_csr_conn5  owner_role_01
                owner_csr_conn6  other_owner
                owner_csr_conn7  owner_role_02
                owner_csr_conn8  other_owner
                owner_csr_conn9  owner_role_01
                owner_kafka_conn1  owner_role_01
                owner_kafka_conn10 owner_role_02
                owner_kafka_conn11 owner_role_03
                owner_kafka_conn2  other_owner
                owner_kafka_conn3  owner_role_01
                owner_kafka_conn4  other_owner
                owner_kafka_conn5  owner_role_01
                owner_kafka_conn6  other_owner
                owner_kafka_conn7  owner_role_02
                owner_kafka_conn8  other_owner
                owner_kafka_conn9  owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_databases WHERE name LIKE 'owner_db%'
                owner_db1  owner_role_01=UC/owner_role_01
                owner_db10 owner_role_02=UC/owner_role_02
                owner_db11 owner_role_03=UC/owner_role_03
                owner_db2  other_owner=UC/other_owner
                owner_db3  owner_role_01=UC/owner_role_01
                owner_db4  other_owner=UC/other_owner
                owner_db5  owner_role_01=UC/owner_role_01
                owner_db6  other_owner=UC/other_owner
                owner_db7  owner_role_02=UC/owner_role_02
                owner_db8  other_owner=UC/other_owner
                owner_db9  owner_role_01=UC/owner_role_01
                owner_db1  mz_support=U/owner_role_01
                owner_db10 mz_support=U/owner_role_02
                owner_db11 mz_support=U/owner_role_03
                owner_db2  mz_support=U/other_owner
                owner_db3  mz_support=U/owner_role_01
                owner_db4  mz_support=U/other_owner
                owner_db5  mz_support=U/owner_role_01
                owner_db6  mz_support=U/other_owner
                owner_db7  mz_support=U/owner_role_02
                owner_db8  mz_support=U/other_owner
                owner_db9  mz_support=U/owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_schemas WHERE name LIKE 'owner_schema%'
                owner_schema1  owner_role_01=UC/owner_role_01
                owner_schema10 owner_role_02=UC/owner_role_02
                owner_schema11 owner_role_03=UC/owner_role_03
                owner_schema2  other_owner=UC/other_owner
                owner_schema3  owner_role_01=UC/owner_role_01
                owner_schema4  other_owner=UC/other_owner
                owner_schema5  owner_role_01=UC/owner_role_01
                owner_schema6  other_owner=UC/other_owner
                owner_schema7  owner_role_02=UC/owner_role_02
                owner_schema8  other_owner=UC/other_owner
                owner_schema9  owner_role_01=UC/owner_role_01
                owner_schema1  mz_support=U/owner_role_01
                owner_schema10 mz_support=U/owner_role_02
                owner_schema11 mz_support=U/owner_role_03
                owner_schema2  mz_support=U/other_owner
                owner_schema3  mz_support=U/owner_role_01
                owner_schema4  mz_support=U/other_owner
                owner_schema5  mz_support=U/owner_role_01
                owner_schema6  mz_support=U/other_owner
                owner_schema7  mz_support=U/owner_role_02
                owner_schema8  mz_support=U/other_owner
                owner_schema9  mz_support=U/owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_tables WHERE name LIKE 'owner_t%'
                owner_t1  owner_role_01=arwd/owner_role_01
                owner_t10 owner_role_02=arwd/owner_role_02
                owner_t11 owner_role_03=arwd/owner_role_03
                owner_t2  other_owner=arwd/other_owner
                owner_t3  owner_role_01=arwd/owner_role_01
                owner_t4  other_owner=arwd/other_owner
                owner_t5  owner_role_01=arwd/owner_role_01
                owner_t6  other_owner=arwd/other_owner
                owner_t7  owner_role_02=arwd/owner_role_02
                owner_t8  other_owner=arwd/other_owner
                owner_t9  owner_role_01=arwd/owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_views WHERE name LIKE 'owner_v%'
                owner_v1  owner_role_01=r/owner_role_01
                owner_v10 owner_role_02=r/owner_role_02
                owner_v11 owner_role_03=r/owner_role_03
                owner_v2  other_owner=r/other_owner
                owner_v3  owner_role_01=r/owner_role_01
                owner_v4  other_owner=r/other_owner
                owner_v5  owner_role_01=r/owner_role_01
                owner_v6  other_owner=r/other_owner
                owner_v7  owner_role_02=r/owner_role_02
                owner_v8  other_owner=r/other_owner
                owner_v9  owner_role_01=r/owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_materialized_views WHERE name LIKE 'owner_mv%'
                owner_mv1  owner_role_01=r/owner_role_01
                owner_mv10 owner_role_02=r/owner_role_02
                owner_mv11 owner_role_03=r/owner_role_03
                owner_mv2  other_owner=r/other_owner
                owner_mv3  owner_role_01=r/owner_role_01
                owner_mv4  other_owner=r/other_owner
                owner_mv5  owner_role_01=r/owner_role_01
                owner_mv6  other_owner=r/other_owner
                owner_mv7  owner_role_02=r/owner_role_02
                owner_mv8  other_owner=r/other_owner
                owner_mv9  owner_role_01=r/owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_types WHERE name LIKE 'owner_type%'
                owner_type1  =U/owner_role_01
                owner_type1  owner_role_01=U/owner_role_01
                owner_type10 =U/owner_role_02
                owner_type10 owner_role_02=U/owner_role_02
                owner_type11 =U/owner_role_03
                owner_type11 owner_role_03=U/owner_role_03
                owner_type2  =U/other_owner
                owner_type2  other_owner=U/other_owner
                owner_type3  =U/owner_role_01
                owner_type3  owner_role_01=U/owner_role_01
                owner_type4  =U/other_owner
                owner_type4  other_owner=U/other_owner
                owner_type5  =U/owner_role_01
                owner_type5  owner_role_01=U/owner_role_01
                owner_type6  =U/other_owner
                owner_type6  other_owner=U/other_owner
                owner_type7  =U/owner_role_02
                owner_type7  owner_role_02=U/owner_role_02
                owner_type8  =U/other_owner
                owner_type8  other_owner=U/other_owner
                owner_type9  =U/owner_role_01
                owner_type9  owner_role_01=U/owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_secrets WHERE name LIKE 'owner_secret%'
                owner_secret1  owner_role_01=U/owner_role_01
                owner_secret10 owner_role_02=U/owner_role_02
                owner_secret11 owner_role_03=U/owner_role_03
                owner_secret2  other_owner=U/other_owner
                owner_secret3  owner_role_01=U/owner_role_01
                owner_secret4  other_owner=U/other_owner
                owner_secret5  owner_role_01=U/owner_role_01
                owner_secret6  other_owner=U/other_owner
                owner_secret7  owner_role_02=U/owner_role_02
                owner_secret8  other_owner=U/other_owner
                owner_secret9  owner_role_01=U/owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_sources WHERE name LIKE 'owner_source%' AND type = 'load-generator'
                owner_source1 owner_role_01=r/owner_role_01
                owner_source2 other_owner=r/other_owner

                ! SELECT name, unnest(privileges)::text FROM mz_sinks WHERE name LIKE 'owner_sink%'
                contains: column "privileges" does not exist

                > SELECT name, unnest(privileges)::text FROM mz_clusters WHERE name LIKE 'owner_cluster%'
                owner_cluster1 mz_support=U/owner_role_01
                owner_cluster1 owner_role_01=UC/owner_role_01
                owner_cluster2 mz_support=U/other_owner
                owner_cluster2 other_owner=UC/other_owner

                > SELECT name, unnest(privileges)::text FROM mz_connections WHERE name LIKE 'owner_%'
                owner_csr_conn1  owner_role_01=U/owner_role_01
                owner_csr_conn10 owner_role_02=U/owner_role_02
                owner_csr_conn11 owner_role_03=U/owner_role_03
                owner_csr_conn2  other_owner=U/other_owner
                owner_csr_conn3  owner_role_01=U/owner_role_01
                owner_csr_conn4  other_owner=U/other_owner
                owner_csr_conn5  owner_role_01=U/owner_role_01
                owner_csr_conn6  other_owner=U/other_owner
                owner_csr_conn7  owner_role_02=U/owner_role_02
                owner_csr_conn8  other_owner=U/other_owner
                owner_csr_conn9  owner_role_01=U/owner_role_01
                owner_kafka_conn1  owner_role_01=U/owner_role_01
                owner_kafka_conn10 owner_role_02=U/owner_role_02
                owner_kafka_conn11 owner_role_03=U/owner_role_03
                owner_kafka_conn2  other_owner=U/other_owner
                owner_kafka_conn3  owner_role_01=U/owner_role_01
                owner_kafka_conn4  other_owner=U/other_owner
                owner_kafka_conn5  owner_role_01=U/owner_role_01
                owner_kafka_conn6  other_owner=U/other_owner
                owner_kafka_conn7  owner_role_02=U/owner_role_02
                owner_kafka_conn8  other_owner=U/other_owner
                owner_kafka_conn9  owner_role_01=U/owner_role_01
                """
            )
            + self._drop_objects("owner_role_01", 9)
            + self._drop_objects("owner_role_02", 10)
            + self._drop_objects("owner_role_03", 11)
        )

Classes

class Owners (base_version: MzVersion, rng: random.Random | None)
Expand source code Browse git
class Owners(Check):
    def _create_objects(self, role: str, i: int, expensive: bool = False) -> str:
        s = dedent(
            f"""
            $[version>=5200] postgres-execute connection=postgres://mz_system@${{testdrive.materialize-internal-sql-addr}}
            GRANT CREATE ON DATABASE materialize TO {role}
            GRANT CREATE ON SCHEMA materialize.public TO {role}
            GRANT CREATE ON CLUSTER {self._default_cluster()} TO {role}
            $[version>=5900] postgres-execute connection=postgres://mz_system@${{testdrive.materialize-internal-sql-addr}}
            GRANT CREATEDB ON SYSTEM TO {role}
            $[version<5900] postgres-execute connection=postgres://mz_system@${{testdrive.materialize-internal-sql-addr}}
            ALTER ROLE {role} CREATEDB
            $ postgres-execute connection=postgres://{role}@${{testdrive.materialize-sql-addr}}
            CREATE DATABASE owner_db{i}
            CREATE SCHEMA owner_schema{i}
            CREATE CONNECTION owner_kafka_conn{i} FOR KAFKA {self._kafka_broker()}
            CREATE CONNECTION owner_csr_conn{i} FOR CONFLUENT SCHEMA REGISTRY URL '${{testdrive.schema-registry-url}}'
            CREATE TYPE owner_type{i} AS LIST (ELEMENT TYPE = text)
            CREATE TABLE owner_t{i} (c1 int, c2 owner_type{i})
            CREATE INDEX owner_i{i} ON owner_t{i} (c2)
            CREATE VIEW owner_v{i} AS SELECT * FROM owner_t{i}
            CREATE MATERIALIZED VIEW owner_mv{i} AS SELECT * FROM owner_t{i}
            CREATE SECRET owner_secret{i} AS 'MY_SECRET'
            """
        )
        if expensive:
            s += dedent(
                f"""
                $[version<9300] postgres-execute connection=postgres://{role}@${{testdrive.materialize-sql-addr}}
                CREATE SOURCE owner_source{i} FROM LOAD GENERATOR COUNTER (SCALE FACTOR 0.01)
                $[version>=9300] postgres-execute connection=postgres://{role}@${{testdrive.materialize-sql-addr}}
                CREATE SOURCE owner_source{i} FROM LOAD GENERATOR COUNTER
                $ postgres-execute connection=postgres://{role}@${{testdrive.materialize-sql-addr}}
                CREATE SINK owner_sink{i} FROM owner_mv{i} INTO KAFKA CONNECTION owner_kafka_conn{i} (TOPIC 'sink-sink-owner{i}') FORMAT AVRO USING CONFLUENT SCHEMA REGISTRY CONNECTION owner_csr_conn{i} ENVELOPE DEBEZIUM
                CREATE CLUSTER owner_cluster{i} REPLICAS (owner_cluster_r{i} (SIZE '4'))
                """
            )

        return s

    def _alter_object_owners(self, i: int, expensive: bool = False) -> str:
        s = dedent(
            f"""
            $ postgres-execute connection=postgres://mz_system@${{testdrive.materialize-internal-sql-addr}}
            ALTER DATABASE owner_db{i} OWNER TO other_owner
            ALTER SCHEMA owner_schema{i} OWNER TO other_owner
            ALTER CONNECTION owner_kafka_conn{i} OWNER TO other_owner
            ALTER CONNECTION owner_csr_conn{i} OWNER TO other_owner
            ALTER TYPE owner_type{i} OWNER TO other_owner
            ALTER TABLE owner_t{i} OWNER TO other_owner
            ALTER INDEX owner_i{i} OWNER TO other_owner
            ALTER VIEW owner_v{i} OWNER TO other_owner
            ALTER MATERIALIZED VIEW owner_mv{i} OWNER TO other_owner
            ALTER SECRET owner_secret{i} OWNER TO other_owner
            """
        )
        if expensive:
            s += dedent(
                f"""
                ALTER SOURCE owner_source{i} OWNER TO other_owner
                ALTER SINK owner_sink{i} OWNER TO other_owner
                ALTER CLUSTER owner_cluster{i} OWNER TO other_owner
                """
            )

        return s

    def _drop_objects(
        self, role: str, i: int, expensive: bool = False, success: bool = True
    ) -> str:
        cmds = []
        # Drop the sink first so we can drop the materialized view without CASCADE.
        if expensive:
            cmds += [
                f"DROP SOURCE owner_source{i}",
                f"DROP SINK owner_sink{i}",
                f"DROP CLUSTER owner_cluster{i}",
            ]
        cmds += [
            f"DROP SECRET owner_secret{i}",
            f"DROP MATERIALIZED VIEW owner_mv{i}",
            f"DROP VIEW owner_v{i}",
            f"DROP INDEX owner_i{i}",
            f"DROP TABLE owner_t{i}",
            f"DROP TYPE owner_type{i}",
            f"DROP CONNECTION owner_csr_conn{i}",
            f"DROP CONNECTION owner_kafka_conn{i}",
            f"DROP SCHEMA owner_schema{i}",
            f"DROP DATABASE owner_db{i}",
        ]
        if success:
            return (
                f"$ postgres-execute connection=postgres://{role}@${{testdrive.materialize-sql-addr}}\n"
                + "\n".join(cmds)
                + "\n"
            )
        if role != "materialize":
            raise ValueError(
                "Can't check for failures with user other than materialize"
            )
        return "\n".join(
            [f"! {cmd} CASCADE\ncontains: must be owner of\n" for cmd in cmds]
        )

    def _can_run(self, e: Executor) -> bool:
        # Object owner changes weren't persisted in some cases earlier than 0.63.0.
        return self.base_version >= MzVersion.parse_mz("v0.63.0-dev")

    def initialize(self) -> Testdrive:
        return Testdrive(
            dedent(
                """
                $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                GRANT CREATEROLE ON SYSTEM TO materialize

                $[version<5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                ALTER ROLE materialize CREATEROLE

                > CREATE ROLE owner_role_01
                >[version<5900] ALTER ROLE owner_role_01 CREATEDB CREATECLUSTER

                $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                GRANT CREATEDB, CREATECLUSTER ON SYSTEM TO owner_role_01

                > CREATE ROLE other_owner
                """
            )
            + self._create_objects("owner_role_01", 1, expensive=True)
            + self._create_objects("owner_role_01", 2, expensive=True)
            + self._alter_object_owners(2, expensive=True)
        )

    def manipulate(self) -> list[Testdrive]:
        return [
            Testdrive(s)
            for s in [
                self._create_objects("owner_role_01", 3)
                + self._create_objects("owner_role_01", 4)
                + self._alter_object_owners(4)
                + dedent(
                    """
                    $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                    GRANT CREATEROLE ON SYSTEM TO materialize

                    $[version<5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                    ALTER ROLE materialize CREATEROLE

                    > CREATE ROLE owner_role_02
                    >[version<5900] ALTER ROLE owner_role_02 CREATEDB CREATECLUSTER

                    $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                    GRANT CREATEDB, CREATECLUSTER ON SYSTEM TO owner_role_02
                    """
                ),
                self._create_objects("owner_role_01", 5)
                + self._create_objects("owner_role_01", 6)
                + self._alter_object_owners(6)
                + self._create_objects("owner_role_02", 7)
                + self._create_objects("owner_role_02", 8)
                + self._alter_object_owners(8)
                + dedent(
                    """
                    $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                    GRANT CREATEROLE ON SYSTEM TO materialize

                    $[version<5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                    ALTER ROLE materialize CREATEROLE

                    > CREATE ROLE owner_role_03
                    >[version<5900] ALTER ROLE owner_role_03 CREATEDB CREATECLUSTER

                    $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                    GRANT CREATEDB, CREATECLUSTER ON SYSTEM TO owner_role_03
                    """
                ),
            ]
        ]

    def validate(self) -> Testdrive:
        return Testdrive(
            # materialize role is not allowed to drop the objects since it is
            # not the owner, verify this:
            (
                (
                    self._drop_objects("materialize", 1, success=False, expensive=True)
                    + self._drop_objects(
                        "materialize", 2, success=False, expensive=True
                    )
                    + self._drop_objects("materialize", 3, success=False)
                    + self._drop_objects("materialize", 4, success=False)
                    + self._drop_objects("materialize", 5, success=False)
                    + self._drop_objects("materialize", 6, success=False)
                    + self._drop_objects("materialize", 7, success=False)
                    + self._drop_objects("materialize", 8, success=False)
                )
                if self.base_version >= MzVersion.parse_mz("v0.51.0-dev")
                else ""
            )
            + self._create_objects("owner_role_01", 9)
            + self._create_objects("owner_role_02", 10)
            + self._create_objects("owner_role_03", 11)
            + dedent(
                """
                $ psql-execute command="\\l owner_db*"
                \\                              List of databases
                    Name    |     Owner     | Encoding | Collate | Ctype | Access privileges
                ------------+---------------+----------+---------+-------+-------------------
                 owner_db1  | owner_role_01 | UTF8     | C       | C     |
                 owner_db10 | owner_role_02 | UTF8     | C       | C     |
                 owner_db11 | owner_role_03 | UTF8     | C       | C     |
                 owner_db2  | other_owner   | UTF8     | C       | C     |
                 owner_db3  | owner_role_01 | UTF8     | C       | C     |
                 owner_db4  | other_owner   | UTF8     | C       | C     |
                 owner_db5  | owner_role_01 | UTF8     | C       | C     |
                 owner_db6  | other_owner   | UTF8     | C       | C     |
                 owner_db7  | owner_role_02 | UTF8     | C       | C     |
                 owner_db8  | other_owner   | UTF8     | C       | C     |
                 owner_db9  | owner_role_01 | UTF8     | C       | C     |


                $ psql-execute command="\\dn owner_schema*"
                \\        List of schemas
                      Name      |     Owner
                ----------------+---------------
                 owner_schema1  | owner_role_01
                 owner_schema10 | owner_role_02
                 owner_schema11 | owner_role_03
                 owner_schema2  | other_owner
                 owner_schema3  | owner_role_01
                 owner_schema4  | other_owner
                 owner_schema5  | owner_role_01
                 owner_schema6  | other_owner
                 owner_schema7  | owner_role_02
                 owner_schema8  | other_owner
                 owner_schema9  | owner_role_01

                $ psql-execute command="\\dt owner_t*"
                \\             List of relations
                 Schema |   Name    | Type  |     Owner
                --------+-----------+-------+---------------
                 public | owner_t1  | table | owner_role_01
                 public | owner_t10 | table | owner_role_02
                 public | owner_t11 | table | owner_role_03
                 public | owner_t2  | table | other_owner
                 public | owner_t3  | table | owner_role_01
                 public | owner_t4  | table | other_owner
                 public | owner_t5  | table | owner_role_01
                 public | owner_t6  | table | other_owner
                 public | owner_t7  | table | owner_role_02
                 public | owner_t8  | table | other_owner
                 public | owner_t9  | table | owner_role_01

                $ psql-execute command="\\di owner_i*"
                \\                   List of relations
                 Schema |   Name    | Type  |     Owner     |   Table
                --------+-----------+-------+---------------+-----------
                 public | owner_i1  | index | owner_role_01 | owner_t1
                 public | owner_i10 | index | owner_role_02 | owner_t10
                 public | owner_i11 | index | owner_role_03 | owner_t11
                 public | owner_i2  | index | other_owner   | owner_t2
                 public | owner_i3  | index | owner_role_01 | owner_t3
                 public | owner_i4  | index | other_owner   | owner_t4
                 public | owner_i5  | index | owner_role_01 | owner_t5
                 public | owner_i6  | index | other_owner   | owner_t6
                 public | owner_i7  | index | owner_role_02 | owner_t7
                 public | owner_i8  | index | other_owner   | owner_t8
                 public | owner_i9  | index | owner_role_01 | owner_t9

                $ psql-execute command="\\dv owner_v*"
                \\             List of relations
                 Schema |   Name    | Type |     Owner
                --------+-----------+------+---------------
                 public | owner_v1  | view | owner_role_01
                 public | owner_v10 | view | owner_role_02
                 public | owner_v11 | view | owner_role_03
                 public | owner_v2  | view | other_owner
                 public | owner_v3  | view | owner_role_01
                 public | owner_v4  | view | other_owner
                 public | owner_v5  | view | owner_role_01
                 public | owner_v6  | view | other_owner
                 public | owner_v7  | view | owner_role_02
                 public | owner_v8  | view | other_owner
                 public | owner_v9  | view | owner_role_01

                $ psql-execute command="\\dmv owner_mv*"
                \\                    List of relations
                 Schema |    Name    |       Type        |     Owner
                --------+------------+-------------------+---------------
                 public | owner_mv1  | materialized view | owner_role_01
                 public | owner_mv10 | materialized view | owner_role_02
                 public | owner_mv11 | materialized view | owner_role_03
                 public | owner_mv2  | materialized view | other_owner
                 public | owner_mv3  | materialized view | owner_role_01
                 public | owner_mv4  | materialized view | other_owner
                 public | owner_mv5  | materialized view | owner_role_01
                 public | owner_mv6  | materialized view | other_owner
                 public | owner_mv7  | materialized view | owner_role_02
                 public | owner_mv8  | materialized view | other_owner
                 public | owner_mv9  | materialized view | owner_role_01

                > SELECT mz_types.name, mz_roles.name FROM mz_types JOIN mz_roles ON mz_types.owner_id = mz_roles.id WHERE mz_types.name LIKE 'owner_type%'
                owner_type1  owner_role_01
                owner_type10 owner_role_02
                owner_type11 owner_role_03
                owner_type2  other_owner
                owner_type3  owner_role_01
                owner_type4  other_owner
                owner_type5  owner_role_01
                owner_type6  other_owner
                owner_type7  owner_role_02
                owner_type8  other_owner
                owner_type9  owner_role_01

                > SELECT mz_secrets.name, mz_roles.name FROM mz_secrets JOIN mz_roles ON mz_secrets.owner_id = mz_roles.id WHERE mz_secrets.name LIKE 'owner_secret%'
                owner_secret1  owner_role_01
                owner_secret10 owner_role_02
                owner_secret11 owner_role_03
                owner_secret2  other_owner
                owner_secret3  owner_role_01
                owner_secret4  other_owner
                owner_secret5  owner_role_01
                owner_secret6  other_owner
                owner_secret7  owner_role_02
                owner_secret8  other_owner
                owner_secret9  owner_role_01

                > SELECT mz_sources.name, mz_roles.name FROM mz_sources JOIN mz_roles ON mz_sources.owner_id = mz_roles.id WHERE mz_sources.name LIKE 'owner_source%' AND type = 'load-generator'
                owner_source1 owner_role_01
                owner_source2 other_owner

                > SELECT mz_sinks.name, mz_roles.name FROM mz_sinks JOIN mz_roles ON mz_sinks.owner_id = mz_roles.id WHERE mz_sinks.name LIKE 'owner_sink%'
                owner_sink1 owner_role_01
                owner_sink2 other_owner

                > SELECT mz_clusters.name, mz_roles.name FROM mz_clusters JOIN mz_roles ON mz_clusters.owner_id = mz_roles.id WHERE mz_clusters.name LIKE 'owner_cluster%'
                owner_cluster1 owner_role_01
                owner_cluster2 other_owner

                > SELECT mz_cluster_replicas.name, mz_roles.name FROM mz_cluster_replicas JOIN mz_roles ON mz_cluster_replicas.owner_id = mz_roles.id WHERE mz_cluster_replicas.name LIKE 'owner_cluster_r%'
                owner_cluster_r1 owner_role_01
                owner_cluster_r2 other_owner

                > SELECT mz_connections.name, mz_roles.name FROM mz_connections JOIN mz_roles ON mz_connections.owner_id = mz_roles.id WHERE mz_connections.name LIKE 'owner_%'
                owner_csr_conn1  owner_role_01
                owner_csr_conn10 owner_role_02
                owner_csr_conn11 owner_role_03
                owner_csr_conn2  other_owner
                owner_csr_conn3  owner_role_01
                owner_csr_conn4  other_owner
                owner_csr_conn5  owner_role_01
                owner_csr_conn6  other_owner
                owner_csr_conn7  owner_role_02
                owner_csr_conn8  other_owner
                owner_csr_conn9  owner_role_01
                owner_kafka_conn1  owner_role_01
                owner_kafka_conn10 owner_role_02
                owner_kafka_conn11 owner_role_03
                owner_kafka_conn2  other_owner
                owner_kafka_conn3  owner_role_01
                owner_kafka_conn4  other_owner
                owner_kafka_conn5  owner_role_01
                owner_kafka_conn6  other_owner
                owner_kafka_conn7  owner_role_02
                owner_kafka_conn8  other_owner
                owner_kafka_conn9  owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_databases WHERE name LIKE 'owner_db%'
                owner_db1  owner_role_01=UC/owner_role_01
                owner_db10 owner_role_02=UC/owner_role_02
                owner_db11 owner_role_03=UC/owner_role_03
                owner_db2  other_owner=UC/other_owner
                owner_db3  owner_role_01=UC/owner_role_01
                owner_db4  other_owner=UC/other_owner
                owner_db5  owner_role_01=UC/owner_role_01
                owner_db6  other_owner=UC/other_owner
                owner_db7  owner_role_02=UC/owner_role_02
                owner_db8  other_owner=UC/other_owner
                owner_db9  owner_role_01=UC/owner_role_01
                owner_db1  mz_support=U/owner_role_01
                owner_db10 mz_support=U/owner_role_02
                owner_db11 mz_support=U/owner_role_03
                owner_db2  mz_support=U/other_owner
                owner_db3  mz_support=U/owner_role_01
                owner_db4  mz_support=U/other_owner
                owner_db5  mz_support=U/owner_role_01
                owner_db6  mz_support=U/other_owner
                owner_db7  mz_support=U/owner_role_02
                owner_db8  mz_support=U/other_owner
                owner_db9  mz_support=U/owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_schemas WHERE name LIKE 'owner_schema%'
                owner_schema1  owner_role_01=UC/owner_role_01
                owner_schema10 owner_role_02=UC/owner_role_02
                owner_schema11 owner_role_03=UC/owner_role_03
                owner_schema2  other_owner=UC/other_owner
                owner_schema3  owner_role_01=UC/owner_role_01
                owner_schema4  other_owner=UC/other_owner
                owner_schema5  owner_role_01=UC/owner_role_01
                owner_schema6  other_owner=UC/other_owner
                owner_schema7  owner_role_02=UC/owner_role_02
                owner_schema8  other_owner=UC/other_owner
                owner_schema9  owner_role_01=UC/owner_role_01
                owner_schema1  mz_support=U/owner_role_01
                owner_schema10 mz_support=U/owner_role_02
                owner_schema11 mz_support=U/owner_role_03
                owner_schema2  mz_support=U/other_owner
                owner_schema3  mz_support=U/owner_role_01
                owner_schema4  mz_support=U/other_owner
                owner_schema5  mz_support=U/owner_role_01
                owner_schema6  mz_support=U/other_owner
                owner_schema7  mz_support=U/owner_role_02
                owner_schema8  mz_support=U/other_owner
                owner_schema9  mz_support=U/owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_tables WHERE name LIKE 'owner_t%'
                owner_t1  owner_role_01=arwd/owner_role_01
                owner_t10 owner_role_02=arwd/owner_role_02
                owner_t11 owner_role_03=arwd/owner_role_03
                owner_t2  other_owner=arwd/other_owner
                owner_t3  owner_role_01=arwd/owner_role_01
                owner_t4  other_owner=arwd/other_owner
                owner_t5  owner_role_01=arwd/owner_role_01
                owner_t6  other_owner=arwd/other_owner
                owner_t7  owner_role_02=arwd/owner_role_02
                owner_t8  other_owner=arwd/other_owner
                owner_t9  owner_role_01=arwd/owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_views WHERE name LIKE 'owner_v%'
                owner_v1  owner_role_01=r/owner_role_01
                owner_v10 owner_role_02=r/owner_role_02
                owner_v11 owner_role_03=r/owner_role_03
                owner_v2  other_owner=r/other_owner
                owner_v3  owner_role_01=r/owner_role_01
                owner_v4  other_owner=r/other_owner
                owner_v5  owner_role_01=r/owner_role_01
                owner_v6  other_owner=r/other_owner
                owner_v7  owner_role_02=r/owner_role_02
                owner_v8  other_owner=r/other_owner
                owner_v9  owner_role_01=r/owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_materialized_views WHERE name LIKE 'owner_mv%'
                owner_mv1  owner_role_01=r/owner_role_01
                owner_mv10 owner_role_02=r/owner_role_02
                owner_mv11 owner_role_03=r/owner_role_03
                owner_mv2  other_owner=r/other_owner
                owner_mv3  owner_role_01=r/owner_role_01
                owner_mv4  other_owner=r/other_owner
                owner_mv5  owner_role_01=r/owner_role_01
                owner_mv6  other_owner=r/other_owner
                owner_mv7  owner_role_02=r/owner_role_02
                owner_mv8  other_owner=r/other_owner
                owner_mv9  owner_role_01=r/owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_types WHERE name LIKE 'owner_type%'
                owner_type1  =U/owner_role_01
                owner_type1  owner_role_01=U/owner_role_01
                owner_type10 =U/owner_role_02
                owner_type10 owner_role_02=U/owner_role_02
                owner_type11 =U/owner_role_03
                owner_type11 owner_role_03=U/owner_role_03
                owner_type2  =U/other_owner
                owner_type2  other_owner=U/other_owner
                owner_type3  =U/owner_role_01
                owner_type3  owner_role_01=U/owner_role_01
                owner_type4  =U/other_owner
                owner_type4  other_owner=U/other_owner
                owner_type5  =U/owner_role_01
                owner_type5  owner_role_01=U/owner_role_01
                owner_type6  =U/other_owner
                owner_type6  other_owner=U/other_owner
                owner_type7  =U/owner_role_02
                owner_type7  owner_role_02=U/owner_role_02
                owner_type8  =U/other_owner
                owner_type8  other_owner=U/other_owner
                owner_type9  =U/owner_role_01
                owner_type9  owner_role_01=U/owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_secrets WHERE name LIKE 'owner_secret%'
                owner_secret1  owner_role_01=U/owner_role_01
                owner_secret10 owner_role_02=U/owner_role_02
                owner_secret11 owner_role_03=U/owner_role_03
                owner_secret2  other_owner=U/other_owner
                owner_secret3  owner_role_01=U/owner_role_01
                owner_secret4  other_owner=U/other_owner
                owner_secret5  owner_role_01=U/owner_role_01
                owner_secret6  other_owner=U/other_owner
                owner_secret7  owner_role_02=U/owner_role_02
                owner_secret8  other_owner=U/other_owner
                owner_secret9  owner_role_01=U/owner_role_01

                > SELECT name, unnest(privileges)::text FROM mz_sources WHERE name LIKE 'owner_source%' AND type = 'load-generator'
                owner_source1 owner_role_01=r/owner_role_01
                owner_source2 other_owner=r/other_owner

                ! SELECT name, unnest(privileges)::text FROM mz_sinks WHERE name LIKE 'owner_sink%'
                contains: column "privileges" does not exist

                > SELECT name, unnest(privileges)::text FROM mz_clusters WHERE name LIKE 'owner_cluster%'
                owner_cluster1 mz_support=U/owner_role_01
                owner_cluster1 owner_role_01=UC/owner_role_01
                owner_cluster2 mz_support=U/other_owner
                owner_cluster2 other_owner=UC/other_owner

                > SELECT name, unnest(privileges)::text FROM mz_connections WHERE name LIKE 'owner_%'
                owner_csr_conn1  owner_role_01=U/owner_role_01
                owner_csr_conn10 owner_role_02=U/owner_role_02
                owner_csr_conn11 owner_role_03=U/owner_role_03
                owner_csr_conn2  other_owner=U/other_owner
                owner_csr_conn3  owner_role_01=U/owner_role_01
                owner_csr_conn4  other_owner=U/other_owner
                owner_csr_conn5  owner_role_01=U/owner_role_01
                owner_csr_conn6  other_owner=U/other_owner
                owner_csr_conn7  owner_role_02=U/owner_role_02
                owner_csr_conn8  other_owner=U/other_owner
                owner_csr_conn9  owner_role_01=U/owner_role_01
                owner_kafka_conn1  owner_role_01=U/owner_role_01
                owner_kafka_conn10 owner_role_02=U/owner_role_02
                owner_kafka_conn11 owner_role_03=U/owner_role_03
                owner_kafka_conn2  other_owner=U/other_owner
                owner_kafka_conn3  owner_role_01=U/owner_role_01
                owner_kafka_conn4  other_owner=U/other_owner
                owner_kafka_conn5  owner_role_01=U/owner_role_01
                owner_kafka_conn6  other_owner=U/other_owner
                owner_kafka_conn7  owner_role_02=U/owner_role_02
                owner_kafka_conn8  other_owner=U/other_owner
                owner_kafka_conn9  owner_role_01=U/owner_role_01
                """
            )
            + self._drop_objects("owner_role_01", 9)
            + self._drop_objects("owner_role_02", 10)
            + self._drop_objects("owner_role_03", 11)
        )

Ancestors

Methods

def initialize(self) ‑> Testdrive
Expand source code Browse git
def initialize(self) -> Testdrive:
    return Testdrive(
        dedent(
            """
            $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
            GRANT CREATEROLE ON SYSTEM TO materialize

            $[version<5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
            ALTER ROLE materialize CREATEROLE

            > CREATE ROLE owner_role_01
            >[version<5900] ALTER ROLE owner_role_01 CREATEDB CREATECLUSTER

            $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
            GRANT CREATEDB, CREATECLUSTER ON SYSTEM TO owner_role_01

            > CREATE ROLE other_owner
            """
        )
        + self._create_objects("owner_role_01", 1, expensive=True)
        + self._create_objects("owner_role_01", 2, expensive=True)
        + self._alter_object_owners(2, expensive=True)
    )
def manipulate(self) ‑> list[Testdrive]
Expand source code Browse git
def manipulate(self) -> list[Testdrive]:
    return [
        Testdrive(s)
        for s in [
            self._create_objects("owner_role_01", 3)
            + self._create_objects("owner_role_01", 4)
            + self._alter_object_owners(4)
            + dedent(
                """
                $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                GRANT CREATEROLE ON SYSTEM TO materialize

                $[version<5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                ALTER ROLE materialize CREATEROLE

                > CREATE ROLE owner_role_02
                >[version<5900] ALTER ROLE owner_role_02 CREATEDB CREATECLUSTER

                $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                GRANT CREATEDB, CREATECLUSTER ON SYSTEM TO owner_role_02
                """
            ),
            self._create_objects("owner_role_01", 5)
            + self._create_objects("owner_role_01", 6)
            + self._alter_object_owners(6)
            + self._create_objects("owner_role_02", 7)
            + self._create_objects("owner_role_02", 8)
            + self._alter_object_owners(8)
            + dedent(
                """
                $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                GRANT CREATEROLE ON SYSTEM TO materialize

                $[version<5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                ALTER ROLE materialize CREATEROLE

                > CREATE ROLE owner_role_03
                >[version<5900] ALTER ROLE owner_role_03 CREATEDB CREATECLUSTER

                $[version>=5900] postgres-execute connection=postgres://mz_system@${testdrive.materialize-internal-sql-addr}
                GRANT CREATEDB, CREATECLUSTER ON SYSTEM TO owner_role_03
                """
            ),
        ]
    ]
def validate(self) ‑> Testdrive
Expand source code Browse git
def validate(self) -> Testdrive:
    return Testdrive(
        # materialize role is not allowed to drop the objects since it is
        # not the owner, verify this:
        (
            (
                self._drop_objects("materialize", 1, success=False, expensive=True)
                + self._drop_objects(
                    "materialize", 2, success=False, expensive=True
                )
                + self._drop_objects("materialize", 3, success=False)
                + self._drop_objects("materialize", 4, success=False)
                + self._drop_objects("materialize", 5, success=False)
                + self._drop_objects("materialize", 6, success=False)
                + self._drop_objects("materialize", 7, success=False)
                + self._drop_objects("materialize", 8, success=False)
            )
            if self.base_version >= MzVersion.parse_mz("v0.51.0-dev")
            else ""
        )
        + self._create_objects("owner_role_01", 9)
        + self._create_objects("owner_role_02", 10)
        + self._create_objects("owner_role_03", 11)
        + dedent(
            """
            $ psql-execute command="\\l owner_db*"
            \\                              List of databases
                Name    |     Owner     | Encoding | Collate | Ctype | Access privileges
            ------------+---------------+----------+---------+-------+-------------------
             owner_db1  | owner_role_01 | UTF8     | C       | C     |
             owner_db10 | owner_role_02 | UTF8     | C       | C     |
             owner_db11 | owner_role_03 | UTF8     | C       | C     |
             owner_db2  | other_owner   | UTF8     | C       | C     |
             owner_db3  | owner_role_01 | UTF8     | C       | C     |
             owner_db4  | other_owner   | UTF8     | C       | C     |
             owner_db5  | owner_role_01 | UTF8     | C       | C     |
             owner_db6  | other_owner   | UTF8     | C       | C     |
             owner_db7  | owner_role_02 | UTF8     | C       | C     |
             owner_db8  | other_owner   | UTF8     | C       | C     |
             owner_db9  | owner_role_01 | UTF8     | C       | C     |


            $ psql-execute command="\\dn owner_schema*"
            \\        List of schemas
                  Name      |     Owner
            ----------------+---------------
             owner_schema1  | owner_role_01
             owner_schema10 | owner_role_02
             owner_schema11 | owner_role_03
             owner_schema2  | other_owner
             owner_schema3  | owner_role_01
             owner_schema4  | other_owner
             owner_schema5  | owner_role_01
             owner_schema6  | other_owner
             owner_schema7  | owner_role_02
             owner_schema8  | other_owner
             owner_schema9  | owner_role_01

            $ psql-execute command="\\dt owner_t*"
            \\             List of relations
             Schema |   Name    | Type  |     Owner
            --------+-----------+-------+---------------
             public | owner_t1  | table | owner_role_01
             public | owner_t10 | table | owner_role_02
             public | owner_t11 | table | owner_role_03
             public | owner_t2  | table | other_owner
             public | owner_t3  | table | owner_role_01
             public | owner_t4  | table | other_owner
             public | owner_t5  | table | owner_role_01
             public | owner_t6  | table | other_owner
             public | owner_t7  | table | owner_role_02
             public | owner_t8  | table | other_owner
             public | owner_t9  | table | owner_role_01

            $ psql-execute command="\\di owner_i*"
            \\                   List of relations
             Schema |   Name    | Type  |     Owner     |   Table
            --------+-----------+-------+---------------+-----------
             public | owner_i1  | index | owner_role_01 | owner_t1
             public | owner_i10 | index | owner_role_02 | owner_t10
             public | owner_i11 | index | owner_role_03 | owner_t11
             public | owner_i2  | index | other_owner   | owner_t2
             public | owner_i3  | index | owner_role_01 | owner_t3
             public | owner_i4  | index | other_owner   | owner_t4
             public | owner_i5  | index | owner_role_01 | owner_t5
             public | owner_i6  | index | other_owner   | owner_t6
             public | owner_i7  | index | owner_role_02 | owner_t7
             public | owner_i8  | index | other_owner   | owner_t8
             public | owner_i9  | index | owner_role_01 | owner_t9

            $ psql-execute command="\\dv owner_v*"
            \\             List of relations
             Schema |   Name    | Type |     Owner
            --------+-----------+------+---------------
             public | owner_v1  | view | owner_role_01
             public | owner_v10 | view | owner_role_02
             public | owner_v11 | view | owner_role_03
             public | owner_v2  | view | other_owner
             public | owner_v3  | view | owner_role_01
             public | owner_v4  | view | other_owner
             public | owner_v5  | view | owner_role_01
             public | owner_v6  | view | other_owner
             public | owner_v7  | view | owner_role_02
             public | owner_v8  | view | other_owner
             public | owner_v9  | view | owner_role_01

            $ psql-execute command="\\dmv owner_mv*"
            \\                    List of relations
             Schema |    Name    |       Type        |     Owner
            --------+------------+-------------------+---------------
             public | owner_mv1  | materialized view | owner_role_01
             public | owner_mv10 | materialized view | owner_role_02
             public | owner_mv11 | materialized view | owner_role_03
             public | owner_mv2  | materialized view | other_owner
             public | owner_mv3  | materialized view | owner_role_01
             public | owner_mv4  | materialized view | other_owner
             public | owner_mv5  | materialized view | owner_role_01
             public | owner_mv6  | materialized view | other_owner
             public | owner_mv7  | materialized view | owner_role_02
             public | owner_mv8  | materialized view | other_owner
             public | owner_mv9  | materialized view | owner_role_01

            > SELECT mz_types.name, mz_roles.name FROM mz_types JOIN mz_roles ON mz_types.owner_id = mz_roles.id WHERE mz_types.name LIKE 'owner_type%'
            owner_type1  owner_role_01
            owner_type10 owner_role_02
            owner_type11 owner_role_03
            owner_type2  other_owner
            owner_type3  owner_role_01
            owner_type4  other_owner
            owner_type5  owner_role_01
            owner_type6  other_owner
            owner_type7  owner_role_02
            owner_type8  other_owner
            owner_type9  owner_role_01

            > SELECT mz_secrets.name, mz_roles.name FROM mz_secrets JOIN mz_roles ON mz_secrets.owner_id = mz_roles.id WHERE mz_secrets.name LIKE 'owner_secret%'
            owner_secret1  owner_role_01
            owner_secret10 owner_role_02
            owner_secret11 owner_role_03
            owner_secret2  other_owner
            owner_secret3  owner_role_01
            owner_secret4  other_owner
            owner_secret5  owner_role_01
            owner_secret6  other_owner
            owner_secret7  owner_role_02
            owner_secret8  other_owner
            owner_secret9  owner_role_01

            > SELECT mz_sources.name, mz_roles.name FROM mz_sources JOIN mz_roles ON mz_sources.owner_id = mz_roles.id WHERE mz_sources.name LIKE 'owner_source%' AND type = 'load-generator'
            owner_source1 owner_role_01
            owner_source2 other_owner

            > SELECT mz_sinks.name, mz_roles.name FROM mz_sinks JOIN mz_roles ON mz_sinks.owner_id = mz_roles.id WHERE mz_sinks.name LIKE 'owner_sink%'
            owner_sink1 owner_role_01
            owner_sink2 other_owner

            > SELECT mz_clusters.name, mz_roles.name FROM mz_clusters JOIN mz_roles ON mz_clusters.owner_id = mz_roles.id WHERE mz_clusters.name LIKE 'owner_cluster%'
            owner_cluster1 owner_role_01
            owner_cluster2 other_owner

            > SELECT mz_cluster_replicas.name, mz_roles.name FROM mz_cluster_replicas JOIN mz_roles ON mz_cluster_replicas.owner_id = mz_roles.id WHERE mz_cluster_replicas.name LIKE 'owner_cluster_r%'
            owner_cluster_r1 owner_role_01
            owner_cluster_r2 other_owner

            > SELECT mz_connections.name, mz_roles.name FROM mz_connections JOIN mz_roles ON mz_connections.owner_id = mz_roles.id WHERE mz_connections.name LIKE 'owner_%'
            owner_csr_conn1  owner_role_01
            owner_csr_conn10 owner_role_02
            owner_csr_conn11 owner_role_03
            owner_csr_conn2  other_owner
            owner_csr_conn3  owner_role_01
            owner_csr_conn4  other_owner
            owner_csr_conn5  owner_role_01
            owner_csr_conn6  other_owner
            owner_csr_conn7  owner_role_02
            owner_csr_conn8  other_owner
            owner_csr_conn9  owner_role_01
            owner_kafka_conn1  owner_role_01
            owner_kafka_conn10 owner_role_02
            owner_kafka_conn11 owner_role_03
            owner_kafka_conn2  other_owner
            owner_kafka_conn3  owner_role_01
            owner_kafka_conn4  other_owner
            owner_kafka_conn5  owner_role_01
            owner_kafka_conn6  other_owner
            owner_kafka_conn7  owner_role_02
            owner_kafka_conn8  other_owner
            owner_kafka_conn9  owner_role_01

            > SELECT name, unnest(privileges)::text FROM mz_databases WHERE name LIKE 'owner_db%'
            owner_db1  owner_role_01=UC/owner_role_01
            owner_db10 owner_role_02=UC/owner_role_02
            owner_db11 owner_role_03=UC/owner_role_03
            owner_db2  other_owner=UC/other_owner
            owner_db3  owner_role_01=UC/owner_role_01
            owner_db4  other_owner=UC/other_owner
            owner_db5  owner_role_01=UC/owner_role_01
            owner_db6  other_owner=UC/other_owner
            owner_db7  owner_role_02=UC/owner_role_02
            owner_db8  other_owner=UC/other_owner
            owner_db9  owner_role_01=UC/owner_role_01
            owner_db1  mz_support=U/owner_role_01
            owner_db10 mz_support=U/owner_role_02
            owner_db11 mz_support=U/owner_role_03
            owner_db2  mz_support=U/other_owner
            owner_db3  mz_support=U/owner_role_01
            owner_db4  mz_support=U/other_owner
            owner_db5  mz_support=U/owner_role_01
            owner_db6  mz_support=U/other_owner
            owner_db7  mz_support=U/owner_role_02
            owner_db8  mz_support=U/other_owner
            owner_db9  mz_support=U/owner_role_01

            > SELECT name, unnest(privileges)::text FROM mz_schemas WHERE name LIKE 'owner_schema%'
            owner_schema1  owner_role_01=UC/owner_role_01
            owner_schema10 owner_role_02=UC/owner_role_02
            owner_schema11 owner_role_03=UC/owner_role_03
            owner_schema2  other_owner=UC/other_owner
            owner_schema3  owner_role_01=UC/owner_role_01
            owner_schema4  other_owner=UC/other_owner
            owner_schema5  owner_role_01=UC/owner_role_01
            owner_schema6  other_owner=UC/other_owner
            owner_schema7  owner_role_02=UC/owner_role_02
            owner_schema8  other_owner=UC/other_owner
            owner_schema9  owner_role_01=UC/owner_role_01
            owner_schema1  mz_support=U/owner_role_01
            owner_schema10 mz_support=U/owner_role_02
            owner_schema11 mz_support=U/owner_role_03
            owner_schema2  mz_support=U/other_owner
            owner_schema3  mz_support=U/owner_role_01
            owner_schema4  mz_support=U/other_owner
            owner_schema5  mz_support=U/owner_role_01
            owner_schema6  mz_support=U/other_owner
            owner_schema7  mz_support=U/owner_role_02
            owner_schema8  mz_support=U/other_owner
            owner_schema9  mz_support=U/owner_role_01

            > SELECT name, unnest(privileges)::text FROM mz_tables WHERE name LIKE 'owner_t%'
            owner_t1  owner_role_01=arwd/owner_role_01
            owner_t10 owner_role_02=arwd/owner_role_02
            owner_t11 owner_role_03=arwd/owner_role_03
            owner_t2  other_owner=arwd/other_owner
            owner_t3  owner_role_01=arwd/owner_role_01
            owner_t4  other_owner=arwd/other_owner
            owner_t5  owner_role_01=arwd/owner_role_01
            owner_t6  other_owner=arwd/other_owner
            owner_t7  owner_role_02=arwd/owner_role_02
            owner_t8  other_owner=arwd/other_owner
            owner_t9  owner_role_01=arwd/owner_role_01

            > SELECT name, unnest(privileges)::text FROM mz_views WHERE name LIKE 'owner_v%'
            owner_v1  owner_role_01=r/owner_role_01
            owner_v10 owner_role_02=r/owner_role_02
            owner_v11 owner_role_03=r/owner_role_03
            owner_v2  other_owner=r/other_owner
            owner_v3  owner_role_01=r/owner_role_01
            owner_v4  other_owner=r/other_owner
            owner_v5  owner_role_01=r/owner_role_01
            owner_v6  other_owner=r/other_owner
            owner_v7  owner_role_02=r/owner_role_02
            owner_v8  other_owner=r/other_owner
            owner_v9  owner_role_01=r/owner_role_01

            > SELECT name, unnest(privileges)::text FROM mz_materialized_views WHERE name LIKE 'owner_mv%'
            owner_mv1  owner_role_01=r/owner_role_01
            owner_mv10 owner_role_02=r/owner_role_02
            owner_mv11 owner_role_03=r/owner_role_03
            owner_mv2  other_owner=r/other_owner
            owner_mv3  owner_role_01=r/owner_role_01
            owner_mv4  other_owner=r/other_owner
            owner_mv5  owner_role_01=r/owner_role_01
            owner_mv6  other_owner=r/other_owner
            owner_mv7  owner_role_02=r/owner_role_02
            owner_mv8  other_owner=r/other_owner
            owner_mv9  owner_role_01=r/owner_role_01

            > SELECT name, unnest(privileges)::text FROM mz_types WHERE name LIKE 'owner_type%'
            owner_type1  =U/owner_role_01
            owner_type1  owner_role_01=U/owner_role_01
            owner_type10 =U/owner_role_02
            owner_type10 owner_role_02=U/owner_role_02
            owner_type11 =U/owner_role_03
            owner_type11 owner_role_03=U/owner_role_03
            owner_type2  =U/other_owner
            owner_type2  other_owner=U/other_owner
            owner_type3  =U/owner_role_01
            owner_type3  owner_role_01=U/owner_role_01
            owner_type4  =U/other_owner
            owner_type4  other_owner=U/other_owner
            owner_type5  =U/owner_role_01
            owner_type5  owner_role_01=U/owner_role_01
            owner_type6  =U/other_owner
            owner_type6  other_owner=U/other_owner
            owner_type7  =U/owner_role_02
            owner_type7  owner_role_02=U/owner_role_02
            owner_type8  =U/other_owner
            owner_type8  other_owner=U/other_owner
            owner_type9  =U/owner_role_01
            owner_type9  owner_role_01=U/owner_role_01

            > SELECT name, unnest(privileges)::text FROM mz_secrets WHERE name LIKE 'owner_secret%'
            owner_secret1  owner_role_01=U/owner_role_01
            owner_secret10 owner_role_02=U/owner_role_02
            owner_secret11 owner_role_03=U/owner_role_03
            owner_secret2  other_owner=U/other_owner
            owner_secret3  owner_role_01=U/owner_role_01
            owner_secret4  other_owner=U/other_owner
            owner_secret5  owner_role_01=U/owner_role_01
            owner_secret6  other_owner=U/other_owner
            owner_secret7  owner_role_02=U/owner_role_02
            owner_secret8  other_owner=U/other_owner
            owner_secret9  owner_role_01=U/owner_role_01

            > SELECT name, unnest(privileges)::text FROM mz_sources WHERE name LIKE 'owner_source%' AND type = 'load-generator'
            owner_source1 owner_role_01=r/owner_role_01
            owner_source2 other_owner=r/other_owner

            ! SELECT name, unnest(privileges)::text FROM mz_sinks WHERE name LIKE 'owner_sink%'
            contains: column "privileges" does not exist

            > SELECT name, unnest(privileges)::text FROM mz_clusters WHERE name LIKE 'owner_cluster%'
            owner_cluster1 mz_support=U/owner_role_01
            owner_cluster1 owner_role_01=UC/owner_role_01
            owner_cluster2 mz_support=U/other_owner
            owner_cluster2 other_owner=UC/other_owner

            > SELECT name, unnest(privileges)::text FROM mz_connections WHERE name LIKE 'owner_%'
            owner_csr_conn1  owner_role_01=U/owner_role_01
            owner_csr_conn10 owner_role_02=U/owner_role_02
            owner_csr_conn11 owner_role_03=U/owner_role_03
            owner_csr_conn2  other_owner=U/other_owner
            owner_csr_conn3  owner_role_01=U/owner_role_01
            owner_csr_conn4  other_owner=U/other_owner
            owner_csr_conn5  owner_role_01=U/owner_role_01
            owner_csr_conn6  other_owner=U/other_owner
            owner_csr_conn7  owner_role_02=U/owner_role_02
            owner_csr_conn8  other_owner=U/other_owner
            owner_csr_conn9  owner_role_01=U/owner_role_01
            owner_kafka_conn1  owner_role_01=U/owner_role_01
            owner_kafka_conn10 owner_role_02=U/owner_role_02
            owner_kafka_conn11 owner_role_03=U/owner_role_03
            owner_kafka_conn2  other_owner=U/other_owner
            owner_kafka_conn3  owner_role_01=U/owner_role_01
            owner_kafka_conn4  other_owner=U/other_owner
            owner_kafka_conn5  owner_role_01=U/owner_role_01
            owner_kafka_conn6  other_owner=U/other_owner
            owner_kafka_conn7  owner_role_02=U/owner_role_02
            owner_kafka_conn8  other_owner=U/other_owner
            owner_kafka_conn9  owner_role_01=U/owner_role_01
            """
        )
        + self._drop_objects("owner_role_01", 9)
        + self._drop_objects("owner_role_02", 10)
        + self._drop_objects("owner_role_03", 11)
    )