Ejemplo n.º 1
0
def feature(self, node="clickhouse1"):
    """Check alter quota query syntax.

    ```sql
    ALTER QUOTA [IF EXISTS] name [ON CLUSTER cluster_name]
    [RENAME TO new_name]
    [KEYED BY {'none' | 'user name' | 'ip address' | 'client key' | 'client key or user name' | 'client key or ip address'}]
    [FOR [RANDOMIZED] INTERVAL number {SECOND | MINUTE | HOUR | DAY | MONTH}
        {MAX { {QUERIES | ERRORS | RESULT ROWS | RESULT BYTES | READ ROWS | READ BYTES | EXECUTION TIME} = number } [,...] |
        NO LIMITS | TRACKING ONLY} [,...]]
    [TO {role [,...] | ALL | ALL EXCEPT role [,...]}]
    ```
    """
    node = self.context.cluster.node(node)

    def cleanup_quota(quota):
        with Given(f"I ensure that quota {quota} does not exist"):
            node.query(f"DROP QUOTA IF EXISTS {quota}")

    try:
        with Given("I have a quota, a user, and a role"):
            node.query(f"CREATE QUOTA quota0")
            node.query(f"CREATE USER user0")
            node.query(f"CREATE ROLE role0")

        with Scenario(
                "I alter quota with no options",
                requirements=[RQ_SRS_006_RBAC_Quota_Alter("1.0")],
        ):
            with When("I alter quota"):
                node.query("ALTER QUOTA quota0")

        with Scenario(
                "I alter quota that does not exist, throws an exception",
                requirements=[RQ_SRS_006_RBAC_Quota_Alter("1.0")],
        ):
            quota = "quota1"
            cleanup_quota(quota)
            with When(f"I alter quota {quota}, which does not exist"):
                exitcode, message = errors.quota_not_found_in_disk(name=quota)
                node.query(f"ALTER QUOTA {quota}",
                           exitcode=exitcode,
                           message=message)
            del quota

        with Scenario(
                "I alter quota with if exists, quota does exist",
                requirements=[RQ_SRS_006_RBAC_Quota_Alter_IfExists("1.0")],
        ):
            node.query("ALTER QUOTA IF EXISTS quota0")

        with Scenario(
                "I alter quota with if exists, quota does not exist",
                requirements=[RQ_SRS_006_RBAC_Quota_Alter_IfExists("1.0")],
        ):
            quota = "quota1"
            cleanup_quota(quota)
            with When(
                    f"I alter quota {quota}, which does not exist, with IF EXISTS"
            ):
                node.query(f"ALTER QUOTA IF EXISTS {quota}")
            del quota

        with Scenario(
                "I alter quota using rename, target available",
                requirements=[RQ_SRS_006_RBAC_Quota_Alter_Rename("1.0")],
        ):
            node.query("ALTER QUOTA quota0 RENAME TO quota0")

        with Scenario(
                "I alter quota using rename, target unavailable",
                requirements=[RQ_SRS_006_RBAC_Quota_Alter_Rename("1.0")],
        ):
            new_quota = "quota1"

            try:
                with Given(f"Ensure target name {new_quota} is NOT available"):
                    node.query(f"CREATE QUOTA IF NOT EXISTS {new_quota}")

                with When(f"I try to rename to {new_quota}"):
                    exitcode, message = errors.cannot_rename_quota(
                        name="quota0", name_new=new_quota)
                    node.query(
                        f"ALTER QUOTA quota0 RENAME TO {new_quota}",
                        exitcode=exitcode,
                        message=message,
                    )
            finally:
                with Finally(f"I cleanup target name {new_quota}"):
                    node.query(f"DROP QUOTA IF EXISTS {new_quota}")

            del new_quota

        keys = [
            "none",
            "user name",
            "ip address",
            "client key",
            "client key or user name",
            "client key or ip address",
        ]
        for key in keys:
            with Scenario(
                    f"I alter quota keyed by {key}",
                    requirements=[
                        RQ_SRS_006_RBAC_Quota_Alter_KeyedBy("1.0"),
                        RQ_SRS_006_RBAC_Quota_Alter_KeyedByOptions("1.0"),
                    ],
            ):
                with When("I alter quota with a key"):
                    node.query(f"ALTER QUOTA quota0 KEYED BY '{key}'")

        with Scenario(
                "I alter quota for randomized interval",
                requirements=[
                    RQ_SRS_006_RBAC_Quota_Alter_Interval_Randomized("1.0")
                ],
        ):
            with When("I alter quota on a randomized interval"):
                node.query(
                    "ALTER QUOTA quota0 FOR RANDOMIZED INTERVAL 1 DAY NO LIMITS"
                )

        intervals = ["SECOND", "MINUTE", "HOUR", "DAY", "MONTH"]
        for i, interval in enumerate(intervals):
            with Scenario(
                    f"I alter quota for interval {interval}",
                    requirements=[RQ_SRS_006_RBAC_Quota_Alter_Interval("1.0")],
            ):
                with When(f"I alter quota for {interval}"):
                    node.query(
                        f"ALTER QUOTA quota0 FOR INTERVAL 1 {interval} NO LIMITS"
                    )

        constraints = [
            "MAX QUERIES",
            "MAX ERRORS",
            "MAX RESULT ROWS",
            "MAX RESULT BYTES",
            "MAX READ ROWS",
            "MAX READ BYTES",
            "MAX EXECUTION TIME",
            "NO LIMITS",
            "TRACKING ONLY",
        ]
        for i, constraint in enumerate(constraints):
            with Scenario(
                    f"I alter quota for {constraint.lower()}",
                    requirements=[
                        RQ_SRS_006_RBAC_Quota_Alter_Queries("1.0"),
                        RQ_SRS_006_RBAC_Quota_Alter_Errors("1.0"),
                        RQ_SRS_006_RBAC_Quota_Alter_ResultRows("1.0"),
                        RQ_SRS_006_RBAC_Quota_Alter_ReadRows("1.0"),
                        RQ_SRS_006_RBAC_Quota_ALter_ResultBytes("1.0"),
                        RQ_SRS_006_RBAC_Quota_Alter_ReadBytes("1.0"),
                        RQ_SRS_006_RBAC_Quota_Alter_ExecutionTime("1.0"),
                        RQ_SRS_006_RBAC_Quota_Alter_NoLimits("1.0"),
                        RQ_SRS_006_RBAC_Quota_Alter_TrackingOnly("1.0"),
                    ],
            ):
                with When("I alter quota for a constraint"):
                    node.query(
                        f"ALTER QUOTA quota0 FOR INTERVAL 1 DAY {constraint}{' 1024' if constraint.startswith('MAX') else ''}"
                    )

        with Scenario(
                "I create quota for multiple constraints",
                requirements=[
                    RQ_SRS_006_RBAC_Quota_Alter_Interval("1.0"),
                    RQ_SRS_006_RBAC_Quota_Alter_Queries("1.0"),
                ],
        ):
            node.query("ALTER QUOTA quota0 \
                 FOR INTERVAL 1 DAY NO LIMITS, \
                 FOR INTERVAL 2 DAY MAX QUERIES 124, \
                 FOR INTERVAL 1 MONTH TRACKING ONLY")

        with Scenario(
                "I alter quota to assign to one role",
                requirements=[RQ_SRS_006_RBAC_Quota_Alter_Assignment("1.0")],
        ):
            with When("I alter quota to a role"):
                node.query("ALTER QUOTA quota0 TO role0")

        with Scenario(
                "I alter quota to assign to role that does not exist, throws exception",
                requirements=[RQ_SRS_006_RBAC_Quota_Alter_Assignment("1.0")],
        ):
            role = "role1"
            with Given(f"I drop {role} if it exists"):
                node.query(f"DROP ROLE IF EXISTS {role}")
            with Then(
                    f"I alter a quota, assign to role {role}, which does not exist"
            ):
                exitcode, message = errors.role_not_found_in_disk(name=role)
                node.query(f"ALTER QUOTA quota0 TO {role}",
                           exitcode=exitcode,
                           message=message)
            del role

        with Scenario(
                "I alter quota to assign to all except role that does not exist, throws exception",
                requirements=[RQ_SRS_006_RBAC_Quota_Alter_Assignment("1.0")],
        ):
            role = "role1"
            with Given(f"I drop {role} if it exists"):
                node.query(f"DROP ROLE IF EXISTS {role}")
            with Then(
                    f"I alter a quota, assign to all except role {role}, which does not exist"
            ):
                exitcode, message = errors.role_not_found_in_disk(name=role)
                node.query(
                    f"ALTER QUOTA quota0 TO ALL EXCEPT {role}",
                    exitcode=exitcode,
                    message=message,
                )
            del role

        with Scenario(
                "I alter quota to assign to one role and one user",
                requirements=[RQ_SRS_006_RBAC_Quota_Alter_Assignment("1.0")],
        ):
            with When("I alter quota to a role and a user"):
                node.query("ALTER QUOTA quota0 TO role0, user0")

        with Scenario(
                "I alter quota assigned to none",
                requirements=[
                    RQ_SRS_006_RBAC_Quota_Alter_Assignment_None("1.0")
                ],
        ):
            with When("I alter quota to none"):
                node.query("ALTER QUOTA quota0 TO NONE")

        with Scenario(
                "I alter quota to assign to all",
                requirements=[
                    RQ_SRS_006_RBAC_Quota_Alter_Assignment_All("1.0")
                ],
        ):
            with When("I alter quota to all"):
                node.query("ALTER QUOTA quota0 TO ALL")

        with Scenario(
                "I alter quota to assign to all except one role",
                requirements=[
                    RQ_SRS_006_RBAC_Quota_Alter_Assignment_Except("1.0")
                ],
        ):
            with When("I alter quota to all except one role"):
                node.query("ALTER QUOTA quota0 TO ALL EXCEPT role0")

        with Scenario(
                "I alter quota to assign to all except multiple roles",
                requirements=[
                    RQ_SRS_006_RBAC_Quota_Alter_Assignment_Except("1.0")
                ],
        ):
            with When("I alter quota to all except one multiple roles"):
                node.query("ALTER QUOTA quota0 TO ALL EXCEPT role0, user0")

        with Scenario(
                "I alter quota on cluster",
                requirements=[RQ_SRS_006_RBAC_Quota_Alter_Cluster("1.0")],
        ):
            try:
                with Given("I have a quota on a cluster"):
                    node.query(
                        "CREATE QUOTA quota1 ON CLUSTER sharded_cluster")

                with When("I run alter quota command on a cluster"):
                    node.query("ALTER QUOTA quota1 ON CLUSTER sharded_cluster")
                with And("I run alter quota command on a cluster with a key"):
                    node.query(
                        "ALTER QUOTA quota1 ON CLUSTER sharded_cluster KEYED BY 'none'"
                    )
                with And(
                        "I run alter quota command on a cluster with an interval"
                ):
                    node.query(
                        "ALTER QUOTA quota1 ON CLUSTER sharded_cluster FOR INTERVAL 1 DAY TRACKING ONLY"
                    )
                with And("I run alter quota command on a cluster for all"):
                    node.query(
                        "ALTER QUOTA quota1 ON CLUSTER sharded_cluster TO ALL")
            finally:
                with Finally("I drop the quota"):
                    node.query(
                        "DROP QUOTA IF EXISTS quota1 ON CLUSTER sharded_cluster"
                    )

        with Scenario(
                "I alter quota on nonexistent cluster, throws exception",
                requirements=[RQ_SRS_006_RBAC_Quota_Alter_Cluster("1.0")],
        ):
            with When("I run alter quota on a cluster"):
                exitcode, message = errors.cluster_not_found("fake_cluster")
                node.query(
                    "ALTER QUOTA quota0 ON CLUSTER fake_cluster",
                    exitcode=exitcode,
                    message=message,
                )

    finally:
        with Finally("I drop the quota and all the users and roles"):
            node.query(f"DROP QUOTA IF EXISTS quota0")
            node.query(f"DROP USER IF EXISTS user0")
            node.query(f"DROP ROLE IF EXISTS role0")
Ejemplo n.º 2
0
def feature(self, node="clickhouse1"):
    """Check alter settings profile query syntax.

    ```sql
    ALTER SETTINGS PROFILE [IF EXISTS] name
    [ON CLUSTER cluster_name]
    [RENAME TO new_name]
    [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | INHERIT 'profile_name'] [,...]
    [TO {user_or_role [,...] | NONE | ALL | ALL EXCEPT user_or_role [,...]]}
    ```
    """
    node = self.context.cluster.node(node)

    def cleanup_profile(profile):
        with Given(f"I ensure that profile {profile} does not exist"):
            node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}")

    try:
        with Given("I have a profile and some users and roles"):
            node.query(f"CREATE SETTINGS PROFILE profile0")
            node.query(f"CREATE USER user0")
            node.query(f"CREATE ROLE role0")

        with Scenario("I alter settings profile with no options", requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter("1.0")]):
            with When("I alter settings profile"):
                node.query("ALTER SETTINGS PROFILE profile0")

        with Scenario("I alter settings profile short form", requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter("1.0")]):
            with When("I short form alter settings profile"):
                node.query("ALTER PROFILE profile0")

        with Scenario("I alter settings profile that does not exist, throws exception", requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter("1.0")]):
            profile = "profile1"

            cleanup_profile(profile)
            with When(f"I alter settings profile {profile} that doesn't exist"):
                exitcode, message = errors.settings_profile_not_found_in_disk(name=profile)
                node.query(f"ALTER SETTINGS PROFILE {profile}", exitcode=exitcode, message=message)
            del profile

        with Scenario("I alter settings profile if exists", requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter_IfExists("1.0")]):
            with When("I alter settings profile using if exists"):
                node.query("ALTER SETTINGS PROFILE IF EXISTS profile0")

        with Scenario("I alter settings profile if exists, profile does not exist", requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter_IfExists("1.0")]):
            profile = "profile1"

            cleanup_profile(profile)
            with When(f"I alter settings profile {profile} using if exists"):
                node.query(f"ALTER SETTINGS PROFILE IF EXISTS {profile}")

            del profile

        with Scenario("I alter settings profile to rename, target available", requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter_Rename("1.0")]):
            with When("I alter settings profile by renaming it"):
                node.query("ALTER SETTINGS PROFILE profile0 RENAME TO profile0")

        with Scenario("I alter settings profile to rename, target unavailable", requirements=[RQ_SRS_006_RBAC_SettingsProfile_Alter_Rename("1.0")]):
            new_profile = "profile1"

            try:
                with Given(f"Ensure target name {new_profile} is NOT available"):
                    node.query(f"CREATE SETTINGS PROFILE IF NOT EXISTS {new_profile}")

                with When(f"I try to rename to {new_profile}"):
                    exitcode, message = errors.cannot_rename_settings_profile(name="profile0", name_new=new_profile)
                    node.query(f"ALTER SETTINGS PROFILE profile0 RENAME TO {new_profile}", exitcode=exitcode, message=message)
            finally:
                with Finally(f"I cleanup target name {new_profile}"):
                    node.query(f"DROP SETTINGS PROFILE IF EXISTS {new_profile}")

            del new_profile

        with Scenario("I alter settings profile with a setting value", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables("1.0"),
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Value("1.0")]):
            with When("I alter settings profile using settings"):
                node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage = 100000001")

        with Scenario("I alter settings profile with a setting value, does not exist, throws exception", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables("1.0"),
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Value("1.0")]):
            with When("I alter settings profile using settings and nonexistent value"):
                exitcode, message = errors.unknown_setting("fake_setting")
                node.query("ALTER SETTINGS PROFILE profile0 SETTINGS fake_setting = 100000001", exitcode=exitcode, message=message)

        with Scenario("I alter settings profile with a min setting value", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Constraints("1.0")]):
            with When("I alter settings profile using 2 minimum formats"):
                node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage MIN 100000001")
                node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage MIN = 100000001")

        with Scenario("I alter settings profile with a max setting value", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Constraints("1.0")]):
            with When("I alter settings profile using 2 maximum formats"):
                node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage MAX 100000001")
                node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage MAX = 100000001")

        with Scenario("I alter settings profile with min and max setting values", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Constraints("1.0")]):
            with When("I alter settings profile with both min and max"):
                node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage MIN 100000001 MAX 200000001")

        with Scenario("I alter settings profile with a readonly setting", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Constraints("1.0")]):
            with When("I alter settings profile with with readonly"):
                node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage READONLY")

        with Scenario("I alter settings profile with a writable setting", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Constraints("1.0")]):
            with When("I alter settings profile with writable"):
                node.query("ALTER SETTINGS PROFILE profile0 SETTINGS max_memory_usage WRITABLE")

        with Scenario("I alter settings profile with inherited settings", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_Inherit("1.0")]):
            with When("I alter settings profile with inherit"):
                node.query("ALTER SETTINGS PROFILE profile0 SETTINGS INHERIT 'default'")

        with Scenario("I alter settings profile with inherit, parent profile does not exist, throws exception", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_Inherit("1.0")]):
            profile = "profile3"
            with Given(f"I ensure that profile {profile} does not exist"):
                node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}")
            with When("I alter settings profile inherit from nonexistant parent"):
                exitcode, message = errors.settings_profile_not_found_in_disk(profile)
                node.query(f"ALTER PROFILE profile0 SETTINGS INHERIT {profile}", exitcode=exitcode, message=message)
            del profile

        with Scenario("I alter settings profile with multiple settings", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables("1.0"),
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Value("1.0")]):
            with When("I alter settings profile with multiple settings"):
                node.query("ALTER SETTINGS PROFILE profile0"
                " SETTINGS max_memory_usage = 100000001"
                " SETTINGS max_memory_usage_for_user = 100000001")

        with Scenario("I alter settings profile with multiple settings short form", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables("1.0"),
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Variables_Value("1.0")]):
            with When("I alter settings profile with short form multiple settings"):
                node.query("ALTER SETTINGS PROFILE profile0"
                " SETTINGS max_memory_usage = 100000001,"
                " max_memory_usage_for_user = 100000001")

        with Scenario("I alter settings profile assigned to one role", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment("1.0")]):
            with When("I alter settings profile with assignment to role"):
                node.query("ALTER SETTINGS PROFILE profile0 TO role0")

        with Scenario("I alter settings profile to assign to role that does not exist, throws exception", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment("1.0")]):
            role = "role1"
            with Given(f"I drop {role} if it exists"):
                node.query(f"DROP ROLE IF EXISTS {role}")
            with Then(f"I alter a settings profile, assign to role {role}, which does not exist"):
                exitcode, message = errors.role_not_found_in_disk(name=role)
                node.query(f"ALTER SETTINGS PROFILE profile0 TO {role}", exitcode=exitcode, message=message)
            del role

        with Scenario("I alter settings profile to assign to all except role that does not exist, throws exception", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment("1.0")]):
            role = "role1"
            with Given(f"I drop {role} if it exists"):
                node.query(f"DROP ROLE IF EXISTS {role}")
            with Then(f"I alter a settings profile, assign to all except role {role}, which does not exist"):
                exitcode, message = errors.role_not_found_in_disk(name=role)
                node.query(f"ALTER SETTINGS PROFILE profile0 TO ALL EXCEPT {role}", exitcode=exitcode, message=message)
            del role

        with Scenario("I alter settings profile assigned to multiple roles", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment("1.0")]):
            with When("I alter settings profile with assignment to multiple roles"):
                node.query("ALTER SETTINGS PROFILE profile0 TO role0, user0")

        with Scenario("I alter settings profile assigned to all", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_All("1.0")]):
            with When("I alter settings profile with assignment to all"):
                node.query("ALTER SETTINGS PROFILE profile0 TO ALL")

        with Scenario("I alter settings profile assigned to all except one role", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_AllExcept("1.0")]):
            with When("I alter settings profile with assignment to all except a role"):
                node.query("ALTER SETTINGS PROFILE profile0 TO ALL EXCEPT role0")

        with Scenario("I alter settings profile assigned to all except multiple roles", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_AllExcept("1.0")]):
            with When("I alter settings profile with assignmentto all except multiple roles"):
                node.query("ALTER SETTINGS PROFILE profile0 TO ALL EXCEPT role0, user0")

        with Scenario("I alter settings profile assigned to none", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_None("1.0")]):
            with When("I alter settings profile with assignment to none"):
                node.query("ALTER SETTINGS PROFILE profile0 TO NONE")

        with Scenario("I alter settings profile on cluster", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_OnCluster("1.0")]):
            try:
                with Given("I have a settings profile on cluster"):
                    node.query("CREATE SETTINGS PROFILE profile1 ON CLUSTER sharded_cluster")
                with When("I run alter settings profile command"):
                    node.query("ALTER SETTINGS PROFILE profile1 ON CLUSTER sharded_cluster")
                with And("I alter settings profile with settings"):
                    node.query("ALTER SETTINGS PROFILE profile1 ON CLUSTER sharded_cluster SETTINGS max_memory_usage = 100000001")
                with And("I alter settings profile with inherit"):
                    node.query("ALTER SETTINGS PROFILE profile1 ON CLUSTER sharded_cluster SETTINGS INHERIT 'default'")
                with And("I alter settings profile to all"):
                    node.query("ALTER SETTINGS PROFILE profile1 ON CLUSTER sharded_cluster TO ALL")
            finally:
                with Finally("I drop the settings profile"):
                    node.query("DROP SETTINGS PROFILE IF EXISTS profile1 ON CLUSTER sharded_cluster")

        with Scenario("I alter settings profile on fake cluster, throws exception", requirements=[
                RQ_SRS_006_RBAC_SettingsProfile_Alter_Assignment_OnCluster("1.0")]):
            with When("I run alter settings profile command"):
                exitcode, message = errors.cluster_not_found("fake_cluster")
                node.query("ALTER SETTINGS PROFILE profile1 ON CLUSTER fake_cluster", exitcode=exitcode, message=message)

    finally:
        with Finally("I drop the profile and all the users and roles"):
            node.query(f"DROP SETTINGS PROFILE IF EXISTS profile0")
            node.query(f"DROP USER IF EXISTS user0")
            node.query(f"DROP ROLE IF EXISTS role0")
Ejemplo n.º 3
0
def feature(self, node="clickhouse1"):
    """Check create role query syntax.

    ```sql
    CREATE ROLE [IF NOT EXISTS | OR REPLACE] name
    [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...]
    ```
    """
    node = self.context.cluster.node(node)

    @contextmanager
    def cleanup(role):
        try:
            with Given("I ensure the role doesn't already exist"):
                node.query(f"DROP ROLE IF EXISTS {role}")
            yield
        finally:
            with Finally("I drop the role"):
                node.query(f"DROP ROLE IF EXISTS {role}")

    def create_role(role):
        with Given(f"I ensure I do have role {role}"):
            node.query(f"CREATE ROLE OR REPLACE {role}")

    with Scenario(
        "I create role with no options",
        requirements=[RQ_SRS_006_RBAC_Role_Create("1.0")],
    ):
        with cleanup("role0"):
            with When("I create role"):
                node.query("CREATE ROLE role0")

    with Scenario(
        "I create role that already exists, throws exception",
        requirements=[RQ_SRS_006_RBAC_Role_Create("1.0")],
    ):
        role = "role0"
        with cleanup(role):
            with Given(f"I have role {role}"):
                node.query(f"CREATE ROLE {role}")
            with When(f"I create role {role}, throws exception"):
                exitcode, message = errors.cannot_insert_role(name=role)
                node.query(f"CREATE ROLE {role}", exitcode=exitcode, message=message)
        del role

    with Scenario(
        "I create role if not exists, role does not exist",
        requirements=[RQ_SRS_006_RBAC_Role_Create_IfNotExists("1.0")],
    ):
        role = "role1"
        with cleanup(role):
            with When(f"I create role {role} with if not exists"):
                node.query(f"CREATE ROLE IF NOT EXISTS {role}")
        del role

    with Scenario(
        "I create role if not exists, role does exist",
        requirements=[RQ_SRS_006_RBAC_Role_Create_IfNotExists("1.0")],
    ):
        role = "role1"
        with cleanup(role):
            create_role(role)
            with When(f"I create role {role} with if not exists"):
                node.query(f"CREATE ROLE IF NOT EXISTS {role}")
        del role

    with Scenario(
        "I create role or replace, role does not exist",
        requirements=[RQ_SRS_006_RBAC_Role_Create_Replace("1.0")],
    ):
        role = "role2"
        with cleanup(role):
            with When(f"I create role {role} with or replace"):
                node.query(f"CREATE ROLE OR REPLACE {role}")
        del role

    with Scenario(
        "I create role or replace, role does exist",
        requirements=[RQ_SRS_006_RBAC_Role_Create_Replace("1.0")],
    ):
        role = "role2"
        with cleanup(role):
            create_role(role)
            with When(f"I create role {role} with or replace"):
                node.query(f"CREATE ROLE OR REPLACE {role}")
        del role

    with Scenario(
        "I create role on cluster", requirements=[RQ_SRS_006_RBAC_Role_Create("1.0")]
    ):
        try:
            with When("I have a role on a cluster"):
                node.query("CREATE ROLE role1 ON CLUSTER sharded_cluster")
            with And("I run create role or replace on a cluster"):
                node.query("CREATE ROLE OR REPLACE role1 ON CLUSTER sharded_cluster")
            with And("I create role with settings on a cluster"):
                node.query(
                    "CREATE ROLE role2 ON CLUSTER sharded_cluster SETTINGS max_memory_usage=10000000 READONLY"
                )
        finally:
            with Finally("I drop the role"):
                node.query("DROP ROLE IF EXISTS role1,role2 ON CLUSTER sharded_cluster")

    with Scenario(
        "I create role on nonexistent cluster, throws exception",
        requirements=[RQ_SRS_006_RBAC_Role_Create("1.0")],
    ):
        with When("I run create role on a cluster"):
            exitcode, message = errors.cluster_not_found("fake_cluster")
            node.query(
                "CREATE ROLE role1 ON CLUSTER fake_cluster",
                exitcode=exitcode,
                message=message,
            )

    with Scenario(
        "I create role with settings profile",
        requirements=[RQ_SRS_006_RBAC_Role_Create_Settings("1.0")],
    ):
        with cleanup("role3"):
            with When("I create role with settings profile"):
                node.query(
                    "CREATE ROLE role3 SETTINGS PROFILE default, max_memory_usage=10000000 WRITABLE"
                )

    with Scenario(
        "I create role settings profile, fake profile, throws exception",
        requirements=[RQ_SRS_006_RBAC_Role_Create_Settings("1.0")],
    ):
        with cleanup("role4a"):
            with Given("I ensure profile profile0 does not exist"):
                node.query("DROP SETTINGS PROFILE IF EXISTS profile0")
            with When("I create role with settings profile that does not exist"):
                exitcode, message = errors.settings_profile_not_found_in_disk(
                    "profile0"
                )
                node.query(
                    "CREATE ROLE role4a SETTINGS PROFILE profile0",
                    exitcode=exitcode,
                    message=message,
                )

    with Scenario(
        "I create role with settings without profile",
        requirements=[RQ_SRS_006_RBAC_Role_Create_Settings("1.0")],
    ):
        with cleanup("role4"):
            with When("I create role with settings without profile"):
                node.query(
                    "CREATE ROLE role4 SETTINGS max_memory_usage=10000000 READONLY"
                )
Ejemplo n.º 4
0
def feature(self, node="clickhouse1"):
    """Check drop row policy query syntax.

    ```sql
    DROP [ROW] POLICY [IF EXISTS] name [,...] ON [database.]table [,...] [ON CLUSTER cluster_name]
    ```
    """
    node = self.context.cluster.node(node)

    @contextmanager
    def cleanup(policy, on=["default.foo"]):
        try:
            with Given("I have a row policy"):
                for i in policy:
                    for j in on:
                        node.query(f"CREATE ROW POLICY OR REPLACE {i} ON {j}")
            yield
        finally:
            with Finally("I drop the row policy"):
                for i in policy:
                    for j in on:
                        node.query(f"DROP ROW POLICY IF EXISTS {i} ON {j}")

    def cleanup_policy(policy, on="default.foo"):
        with Given(f"I ensure that policy {policy} does not exist"):
            node.query(f"DROP ROW POLICY IF EXISTS {policy} ON {on}")

    try:
        with Given("I have some tables"):
            node.query(
                f"CREATE TABLE default.foo (x UInt64, y String) Engine=Memory")
            node.query(
                f"CREATE TABLE default.foo2 (x UInt64, y String) Engine=Memory"
            )

        with Scenario(
                "I drop row policy with no options",
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Drop("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0"),
                ],
        ):
            with cleanup(["policy1"]):
                with When("I drop row policy"):
                    node.query("DROP ROW POLICY policy1 ON default.foo")

        with Scenario(
                "I drop row policy using short syntax with no options",
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Drop("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0"),
                ],
        ):
            with cleanup(["policy2"]):
                with When("I drop row policy short form"):
                    node.query("DROP POLICY policy2 ON default.foo")

        with Scenario(
                "I drop row policy, does not exist, throws exception",
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Drop("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0"),
                ],
        ):
            policy = "policy1"
            cleanup_policy(policy)
            with When("I drop row policy"):
                exitcode, message = errors.row_policy_not_found_in_disk(
                    name=f"{policy} ON default.foo")
                node.query(
                    f"DROP ROW POLICY {policy} ON default.foo",
                    exitcode=exitcode,
                    message=message,
                )
            del policy

        with Scenario(
                "I drop row policy if exists, policy does exist",
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Drop_IfExists("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0"),
                ],
        ):
            with cleanup(["policy3"]):
                with When("I drop row policy if exists"):
                    node.query(
                        "DROP ROW POLICY IF EXISTS policy3 ON default.foo")

        with Scenario(
                "I drop row policy if exists, policy doesn't exist",
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Drop_IfExists("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0"),
                ],
        ):
            cleanup_policy("policy3")
            with When("I drop row policy if exists"):
                node.query("DROP ROW POLICY IF EXISTS policy3 ON default.foo")

        with Scenario(
                "I drop multiple row policies",
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Drop("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0"),
                ],
        ):
            with cleanup(["policy3", "policy4"]):
                with When("I drop multiple row policies"):
                    node.query(
                        "DROP ROW POLICY policy3, policy4 ON default.foo")

        with Scenario(
                "I drop row policy on multiple tables",
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Drop("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0"),
                ],
        ):
            with cleanup(["policy3"], ["default.foo", "default.foo2"]):
                with When("I drop row policy on multiple tables"):
                    node.query(
                        "DROP ROW POLICY policy3 ON default.foo, default.foo2")

        with Scenario(
                "I drop multiple row policies on multiple tables",
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Drop("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0"),
                ],
        ):
            with cleanup(["policy3", "policy4"],
                         ["default.foo", "default.foo2"]):
                with When("I drop the row policies from the tables"):
                    node.query(
                        "DROP ROW POLICY policy3 ON default.foo, policy4 ON default.foo2"
                    )

        with Scenario(
                "I drop row policy on cluster",
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Drop_OnCluster("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0"),
                ],
        ):
            try:
                with Given("I have a row policy"):
                    node.query(
                        "CREATE ROW POLICY policy13 ON default.foo ON CLUSTER sharded_cluster"
                    )
                with When("I run drop row policy command"):
                    node.query(
                        "DROP ROW POLICY IF EXISTS policy13 ON CLUSTER sharded_cluster ON default.foo"
                    )
            finally:
                with Finally("I drop the row policy in case it still exists"):
                    node.query(
                        "DROP ROW POLICY IF EXISTS policy13 ON default.foo ON CLUSTER sharded_cluster"
                    )

        with Scenario(
                "I drop row policy on cluster after table",
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Drop_OnCluster("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0"),
                ],
        ):
            try:
                with Given("I have a row policy"):
                    node.query(
                        "CREATE ROW POLICY policy12 ON default.foo ON CLUSTER sharded_cluster"
                    )
                with When("I run drop row policy command"):
                    node.query(
                        "DROP ROW POLICY IF EXISTS policy13 ON default.foo ON CLUSTER sharded_cluster"
                    )
            finally:
                with Finally("I drop the row policy in case it still exists"):
                    node.query(
                        "DROP ROW POLICY IF EXISTS policy12 ON default.foo ON CLUSTER sharded_cluster"
                    )

        with Scenario(
                "I drop row policy on fake cluster throws exception",
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Drop_OnCluster("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Drop_On("1.0"),
                ],
        ):
            with When("I run drop row policy command"):
                exitcode, message = errors.cluster_not_found("fake_cluster")
                node.query(
                    "DROP ROW POLICY IF EXISTS policy14 ON default.foo ON CLUSTER fake_cluster",
                    exitcode=exitcode,
                    message=message,
                )
    finally:
        with Finally("I drop the tables"):
            node.query(f"DROP TABLE IF EXISTS default.foo")
            node.query(f"DROP TABLE IF EXISTS default.foo2")
Ejemplo n.º 5
0
def feature(self, node="clickhouse1"):
    """Check create quota query syntax.

    ```sql
    CREATE QUOTA [IF NOT EXISTS | OR REPLACE] name [ON CLUSTER cluster_name]
    [KEYED BY {'none' | 'user name' | 'ip address' | 'client key' | 'client key or user name' | 'client key or ip address'}]
    [FOR [RANDOMIZED] INTERVAL number {SECOND | MINUTE | HOUR | DAY}
        {MAX { {QUERIES | ERRORS | RESULT ROWS | RESULT BYTES | READ ROWS | READ BYTES | EXECUTION TIME} = number } [,...] |
         NO LIMITS | TRACKING ONLY} [,...]]
    [TO {role [,...] | ALL | ALL EXCEPT role [,...]}]
    ```
    """
    node = self.context.cluster.node(node)

    @contextmanager
    def cleanup(quota):
        try:
            with Given("I ensure the quota does not already exist"):
                node.query(f"DROP QUOTA IF EXISTS {quota}")
            yield
        finally:
            with Finally("I drop the quota"):
                node.query(f"DROP QUOTA IF EXISTS {quota}")

    def create_quota(quota):
        with And(f"I ensure I do have quota {quota}"):
                node.query(f"CREATE QUOTA OR REPLACE {quota}")

    try:
        with Given("I have a user and a role"):
            node.query(f"CREATE USER user0")
            node.query(f"CREATE ROLE role0")

        with Scenario("I create quota with no options", requirements=[
                RQ_SRS_006_RBAC_Quota_Create("1.0")]):
            with cleanup("quota0"):
                with When("I create a quota with no options"):
                    node.query("CREATE QUOTA quota0")

        with Scenario("I create quota that already exists, throws exception", requirements=[
                RQ_SRS_006_RBAC_Quota_Create("1.0")]):
            quota = "quota0"
            with cleanup(quota):
                create_quota(quota)
                with When(f"I create a quota {quota} that already exists without IF EXISTS, throws exception"):
                    exitcode, message = errors.cannot_insert_quota(name=quota)
                    node.query(f"CREATE QUOTA {quota}", exitcode=exitcode, message=message)
            del quota

        with Scenario("I create quota if not exists, quota does not exist", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_IfNotExists("1.0")]):
            quota = "quota1"
            with cleanup(quota):
                with When(f"I create a quota {quota} with if not exists"):
                    node.query(f"CREATE QUOTA IF NOT EXISTS {quota}")
            del quota

        with Scenario("I create quota if not exists, quota does exist", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_IfNotExists("1.0")]):
            quota = "quota1"
            with cleanup(quota):
                create_quota(quota)
                with When(f"I create a quota {quota} with if not exists"):
                    node.query(f"CREATE QUOTA IF NOT EXISTS {quota}")
            del quota

        with Scenario("I create quota or replace, quota does not exist", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_Replace("1.0")]):
            quota = "quota2"
            with cleanup(quota):
                with When(f"I create a quota {quota} with or replace"):
                    node.query(f"CREATE QUOTA OR REPLACE {quota}")
            del quota

        with Scenario("I create quota or replace, quota does exist", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_Replace("1.0")]):
            quota = "quota2"
            with cleanup(quota):
                create_quota(quota)
                with When(f"I create a quota {quota} with or replace"):
                    node.query(f"CREATE QUOTA OR REPLACE {quota}")
            del quota

        keys = ['none', 'user name', 'ip address', 'client key', 'client key or user name', 'client key or ip address']
        for i, key in enumerate(keys):
            with Scenario(f"I create quota keyed by {key}", requirements=[
                    RQ_SRS_006_RBAC_Quota_Create_KeyedBy("1.0"),
                    RQ_SRS_006_RBAC_Quota_Create_KeyedByOptions("1.0")]):
                name = f'quota{3 + i}'
                with cleanup(name):
                    with When(f"I create a quota with {key}"):
                        node.query(f"CREATE QUOTA {name} KEYED BY '{key}'")

        with Scenario("I create quota for randomized interval", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_Interval_Randomized("1.0")]):
            with cleanup("quota9"):
                with When("I create a quota for randomized interval"):
                    node.query("CREATE QUOTA quota9 FOR RANDOMIZED INTERVAL 1 DAY NO LIMITS")

        intervals = ['SECOND', 'MINUTE', 'HOUR', 'DAY', 'MONTH']
        for i, interval in enumerate(intervals):
            with Scenario(f"I create quota for interval {interval}", requirements=[
                    RQ_SRS_006_RBAC_Quota_Create_Interval("1.0")]):
                name = f'quota{10 + i}'
                with cleanup(name):
                    with When(f"I create a quota for {interval} interval"):
                        node.query(f"CREATE QUOTA {name} FOR INTERVAL 1 {interval} NO LIMITS")

        constraints = ['MAX QUERIES', 'MAX ERRORS', 'MAX RESULT ROWS',
            'MAX RESULT BYTES', 'MAX READ ROWS', 'MAX READ BYTES', 'MAX EXECUTION TIME',
            'NO LIMITS', 'TRACKING ONLY']
        for i, constraint in enumerate(constraints):
            with Scenario(f"I create quota for {constraint.lower()}", requirements=[
                    RQ_SRS_006_RBAC_Quota_Create_Queries("1.0"),
                    RQ_SRS_006_RBAC_Quota_Create_Errors("1.0"),
                    RQ_SRS_006_RBAC_Quota_Create_ResultRows("1.0"),
                    RQ_SRS_006_RBAC_Quota_Create_ResultBytes("1.0"),
                    RQ_SRS_006_RBAC_Quota_Create_ReadRows("1.0"),
                    RQ_SRS_006_RBAC_Quota_Create_ReadBytes("1.0"),
                    RQ_SRS_006_RBAC_Quota_Create_ExecutionTime("1.0"),
                    RQ_SRS_006_RBAC_Quota_Create_NoLimits("1.0"),
                    RQ_SRS_006_RBAC_Quota_Create_TrackingOnly("1.0")]):
                name = f'quota{15 + i}'
                with cleanup(name):
                    with When(f"I create quota for {constraint.lower()}"):
                        node.query(f"CREATE QUOTA {name} FOR INTERVAL 1 DAY {constraint}{' 1024' if constraint.startswith('MAX') else ''}")

        with Scenario("I create quota for multiple constraints", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_Interval("1.0"),
                RQ_SRS_006_RBAC_Quota_Create_Queries("1.0")]):
            with cleanup("quota23"):
                with When(f"I create quota for multiple constraints"):
                    node.query('CREATE QUOTA quota23 \
                        FOR INTERVAL 1 DAY NO LIMITS, \
                        FOR INTERVAL 2 DAY MAX QUERIES 124, \
                        FOR INTERVAL 1 HOUR TRACKING ONLY')

        with Scenario("I create quota assigned to one role", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_Assignment("1.0")]):
            with cleanup("quota24"):
                with When("I create quota for role"):
                    node.query("CREATE QUOTA quota24 TO role0")

        with Scenario("I create quota to assign to role that does not exist, throws exception", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_Assignment("1.0")]):
            role = "role1"
            with Given(f"I drop {role} if it exists"):
                node.query(f"DROP ROLE IF EXISTS {role}")
            with Then(f"I create a quota, assign to role {role}, which does not exist"):
                exitcode, message = errors.role_not_found_in_disk(name=role)
                node.query(f"CREATE QUOTA quota0 TO {role}", exitcode=exitcode, message=message)
            del role

        with Scenario("I create quota to assign to all except role that does not exist, throws exception", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_Assignment("1.0")]):
            role = "role1"
            with Given(f"I drop {role} if it exists"):
                node.query(f"DROP ROLE IF EXISTS {role}")
            with Then(f"I create a quota, assign to all except role {role}, which does not exist"):
                exitcode, message = errors.role_not_found_in_disk(name=role)
                node.query(f"CREATE QUOTA quota0 TO ALL EXCEPT {role}", exitcode=exitcode, message=message)
            del role

        with Scenario("I create quota assigned to no role", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_Assignment_None("1.0")]):
            with When("I create quota for no role"):
                node.query("CREATE QUOTA quota24 TO NONE")

        with Scenario("I create quota assigned to multiple roles", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_Assignment("1.0")]):
            with cleanup("quota25"):
                with When("I create quota for multiple roles"):
                    node.query("CREATE QUOTA quota25 TO role0, user0")

        with Scenario("I create quota assigned to all", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_Assignment_All("1.0")]):
            with cleanup("quota26"):
                with When("I create quota for all"):
                    node.query("CREATE QUOTA quota26 TO ALL")

        with Scenario("I create quota assigned to all except one role", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_Assignment_Except("1.0")]):
            with cleanup("quota27"):
                with When("I create quota for all except one role"):
                    node.query("CREATE QUOTA quota27 TO ALL EXCEPT role0")

        with Scenario("I create quota assigned to all except multiple roles", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_Assignment_Except("1.0")]):
            with cleanup("quota28"):
                with When("I create quota for all except multiple roles"):
                    node.query("CREATE QUOTA quota28 TO ALL EXCEPT role0, user0")

        with Scenario("I create quota on cluster", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_Cluster("1.0")]):
            try:
                with When("I run create quota command on cluster"):
                    node.query("CREATE QUOTA quota29 ON CLUSTER sharded_cluster")
                with When("I run create quota command on cluster, keyed"):
                    node.query("CREATE QUOTA OR REPLACE quota29 ON CLUSTER sharded_cluster KEYED BY 'none'")
                with When("I run create quota command on cluster, interval"):
                    node.query("CREATE QUOTA OR REPLACE quota29 ON CLUSTER sharded_cluster FOR INTERVAL 1 DAY TRACKING ONLY")
                with When("I run create quota command on cluster, assign"):
                    node.query("CREATE QUOTA OR REPLACE quota29 ON CLUSTER sharded_cluster TO ALL")
            finally:
                with Finally("I drop the quota from cluster"):
                    node.query("DROP QUOTA IF EXISTS quota29 ON CLUSTER sharded_cluster")

        with Scenario("I create quota on nonexistent cluster, throws exception", requirements=[
                RQ_SRS_006_RBAC_Quota_Create_Cluster("1.0")]):
            with When("I run create quota on a cluster"):
                exitcode, message = errors.cluster_not_found("fake_cluster")
                node.query("CREATE QUOTA quota0 ON CLUSTER fake_cluster", exitcode=exitcode, message=message)

    finally:
        with Finally("I drop all the users and roles"):
            node.query(f"DROP USER IF EXISTS user0")
            node.query(f"DROP ROLE IF EXISTS role0")
Ejemplo n.º 6
0
def feature(self, node="clickhouse1"):
    """Check create user query syntax.

    ```sql
    CREATE USER [IF NOT EXISTS | OR REPLACE] name [ON CLUSTER cluster_name]
    [IDENTIFIED [WITH {NO_PASSWORD|PLAINTEXT_PASSWORD|SHA256_PASSWORD|SHA256_HASH|DOUBLE_SHA1_PASSWORD|DOUBLE_SHA1_HASH}] BY {'password'|'hash'}]
    [HOST {LOCAL | NAME 'name' | NAME REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE]
    [DEFAULT ROLE role [,...]]
    [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...]
    ```
    """
    node = self.context.cluster.node(node)

    @contextmanager
    def cleanup(user):
        try:
            with Given("I ensure the user does not already exist", flags=TE):
                node.query(f"DROP USER IF EXISTS {user}")
            yield
        finally:
            with Finally("I drop the user", flags=TE):
                node.query(f"DROP USER IF EXISTS {user}")

    def create_user(user):
        with Given(f"I ensure I do have user {user}"):
            node.query(f"CREATE USER OR REPLACE {user}")

    with Scenario("I create user with no options",
                  flags=TE,
                  requirements=[
                      RQ_SRS_006_RBAC_User_Create("1.0"),
                      RQ_SRS_006_RBAC_User_Create_Host_Default("1.0")
                  ]):
        with cleanup("user0"):
            with When("I create a user with no options"):
                node.query("CREATE USER user0")

    with Scenario("I create user that already exists, throws exception",
                  flags=TE,
                  requirements=[
                      RQ_SRS_006_RBAC_User_Create("1.0"),
                      RQ_SRS_006_RBAC_User_Create_Host_Default("1.0")
                  ]):
        user = "******"
        with cleanup(user):
            create_user(user)
            with When(
                    f"I create a user {user} that already exists without IF EXISTS, throws exception"
            ):
                exitcode, message = errors.cannot_insert_user(name=user)
                node.query(f"CREATE USER {user}",
                           exitcode=exitcode,
                           message=message)
        del user

    with Scenario(
            "I create user with if not exists, user does not exist",
            flags=TE,
            requirements=[RQ_SRS_006_RBAC_User_Create_IfNotExists("1.0")]):
        user = "******"
        with cleanup(user):
            with When(f"I create a user {user} with if not exists"):
                node.query(f"CREATE USER IF NOT EXISTS {user}")
        del user

    #Bug exists, mark as xfail
    with Scenario(
            "I create user with if not exists, user does exist",
            flags=TE,
            requirements=[RQ_SRS_006_RBAC_User_Create_IfNotExists("1.0")]):
        user = "******"
        with cleanup(user):
            create_user(user)
            with When(f"I create a user {user} with if not exists"):
                node.query(f"CREATE USER IF NOT EXISTS {user}")
        del user

    with Scenario("I create user or replace, user does not exist",
                  flags=TE,
                  requirements=[RQ_SRS_006_RBAC_User_Create_Replace("1.0")]):
        user = "******"
        with cleanup(user):
            with When(f"I create a user {user} with or replace"):
                node.query(f"CREATE USER OR REPLACE {user}")
        del user

    with Scenario("I create user or replace, user does exist",
                  flags=TE,
                  requirements=[RQ_SRS_006_RBAC_User_Create_Replace("1.0")]):
        user = "******"
        with cleanup(user):
            create_user(user)
            with When(f"I create a user {user} with or replace"):
                node.query(f"CREATE USER OR REPLACE {user}")
        del user

    with Scenario("I create user with no password",
                  flags=TE,
                  requirements=[
                      RQ_SRS_006_RBAC_User_Create_Password_NoPassword("1.0")
                  ]):
        with cleanup("user1"):
            with When("I create a user with no password"):
                node.query("CREATE USER user1 IDENTIFIED WITH NO_PASSWORD")

    with Scenario("I create user with plaintext password",
                  flags=TE,
                  requirements=[
                      RQ_SRS_006_RBAC_User_Create_Password_PlainText("1.0")
                  ]):
        with cleanup("user1"):
            with When("I create a user with plaintext password"):
                node.query(
                    "CREATE USER user1 IDENTIFIED WITH PLAINTEXT_PASSWORD BY 'mypassword'"
                )

    with Scenario(
            "I create user with sha256 password",
            flags=TE,
            requirements=[
                RQ_SRS_006_RBAC_User_Create_Password_Sha256Password("1.0")
            ]):
        with cleanup("user2"):
            with When("I create a user with sha256 password"):
                password = hashlib.sha256(
                    "mypassword".encode("utf-8")).hexdigest()
                node.query(
                    f"CREATE USER user2 IDENTIFIED WITH SHA256_PASSWORD BY '{password}'"
                )

    with Scenario(
            "I create user with sha256 password using IDENTIFIED BY",
            flags=TE,
            requirements=[
                RQ_SRS_006_RBAC_User_Create_Password_Sha256Password("1.0")
            ]):
        with cleanup("user2"):
            with When("I create a user with sha256 password using short form"):
                password = hashlib.sha256(
                    "mypassword".encode("utf-8")).hexdigest()
                node.query(f"CREATE USER user2 IDENTIFIED BY '{password}'")

    with Scenario("I create user with sha256_hash password",
                  flags=TE,
                  requirements=[
                      RQ_SRS_006_RBAC_User_Create_Password_Sha256Hash("1.0")
                  ]):
        with cleanup("user3"):
            with When("I create a user with sha256_hash"):

                def hash(password):
                    return hashlib.sha256(password.encode("utf-8")).hexdigest()

                password = hash(hash("mypassword"))
                node.query(
                    f"CREATE USER user3 IDENTIFIED WITH SHA256_HASH BY '{password}'"
                )

    with Scenario(
            "I create user with double sha1 password",
            flags=TE,
            requirements=[
                RQ_SRS_006_RBAC_User_Create_Password_DoubleSha1Password("1.0")
            ]):
        with cleanup("user3"):
            with When("I create a user with double_sha1_password"):
                node.query(
                    f"CREATE USER user3 IDENTIFIED WITH DOUBLE_SHA1_PASSWORD BY 'mypassword'"
                )

    with Scenario(
            "I create user with double sha1 hash",
            flags=TE,
            requirements=[
                RQ_SRS_006_RBAC_User_Create_Password_DoubleSha1Hash("1.0")
            ]):
        with cleanup("user3"):
            with When("I create a user with double_sha1_hash"):

                def hash(password):
                    return hashlib.sha1(password.encode("utf-8")).hexdigest()

                password = hash(hash("mypassword"))
                node.query(
                    f"CREATE USER user3 IDENTIFIED WITH DOUBLE_SHA1_HASH BY '{password}'"
                )

    with Scenario("I create user with host name",
                  flags=TE,
                  requirements=[RQ_SRS_006_RBAC_User_Create_Host_Name("1.0")]):
        with cleanup("user4"):
            with When("I create a user with host name"):
                node.query(
                    "CREATE USER user4 HOST NAME 'localhost', NAME 'clickhouse.com'"
                )

    with Scenario(
            "I create user with host regexp",
            flags=TE,
            requirements=[RQ_SRS_006_RBAC_User_Create_Host_Regexp("1.0")]):
        with cleanup("user5"):
            with When("I create a user with host regexp"):
                node.query(
                    "CREATE USER user5 HOST REGEXP 'lo.?*host', REGEXP 'lo*host'"
                )

    with Scenario("I create user with host ip",
                  flags=TE,
                  requirements=[RQ_SRS_006_RBAC_User_Create_Host_IP("1.0")]):
        with cleanup("user6"):
            with When("I create a user with host ip"):
                node.query(
                    "CREATE USER user6 HOST IP '127.0.0.1', IP '127.0.0.2'")

    with Scenario("I create user with host like",
                  flags=TE,
                  requirements=[RQ_SRS_006_RBAC_User_Create_Host_Like("1.0")]):
        with cleanup("user7"):
            with When("I create a user with host like"):
                node.query("CREATE USER user7 HOST LIKE 'local%'")

    with Scenario("I create user with host none",
                  flags=TE,
                  requirements=[RQ_SRS_006_RBAC_User_Create_Host_None("1.0")]):
        with cleanup("user7"):
            with When("I create a user with host none"):
                node.query("CREATE USER user7 HOST NONE")

    with Scenario("I create user with host local",
                  flags=TE,
                  requirements=[RQ_SRS_006_RBAC_User_Create_Host_Local("1.0")
                                ]):
        with cleanup("user7"):
            with When("I create a user with host local"):
                node.query("CREATE USER user7 HOST LOCAL")

    with Scenario("I create user with host any",
                  flags=TE,
                  requirements=[RQ_SRS_006_RBAC_User_Create_Host_Any("1.0")]):
        with cleanup("user7"):
            with When("I create a user with host any"):
                node.query("CREATE USER user7 HOST ANY")

    with Scenario("I create user with default role set to none",
                  flags=TE,
                  requirements=[
                      RQ_SRS_006_RBAC_User_Create_DefaultRole_None("1.0")
                  ]):
        with cleanup("user8"):
            with When("I create a user with no default role"):
                node.query("CREATE USER user8 DEFAULT ROLE NONE")

    with Scenario(
            "I create user with default role",
            flags=TE,
            requirements=[RQ_SRS_006_RBAC_User_Create_DefaultRole("1.0")]):
        with Given("I have a role"):
            node.query("CREATE ROLE default")
        with cleanup("user9"):
            with When("I create a user with a default role"):
                node.query("CREATE USER user9 DEFAULT ROLE default")
        with Finally("I drop the role"):
            node.query("DROP ROLE default")

    with Scenario(
            "I create user default role, role doesn't exist, throws exception",
            flags=TE,
            requirements=[RQ_SRS_006_RBAC_User_Create_DefaultRole("1.0")]):
        with cleanup("user12"):
            role = "role0"
            with Given(f"I ensure that role {role} does not exist"):
                node.query(f"DROP ROLE IF EXISTS {role}")
            with When(f"I create user with default role {role}"):
                exitcode, message = errors.role_not_found_in_disk(role)
                node.query(f"CREATE USER user12 DEFAULT ROLE {role}",
                           exitcode=exitcode,
                           message=message)
            del role

    with Scenario(
            "I create user default role, all except role doesn't exist, throws exception",
            flags=TE,
            requirements=[RQ_SRS_006_RBAC_User_Create_DefaultRole("1.0")]):
        with cleanup("user12"):
            role = "role0"
            with Given(f"I ensure that role {role} does not exist"):
                node.query(f"DROP ROLE IF EXISTS {role}")
            with When(f"I create user with default role {role}"):
                exitcode, message = errors.role_not_found_in_disk(role)
                node.query(
                    f"CREATE USER user12 DEFAULT ROLE ALL EXCEPT {role}",
                    exitcode=exitcode,
                    message=message)
            del role

    with Scenario(
            "I create user with all roles set to default",
            flags=TE,
            requirements=[RQ_SRS_006_RBAC_User_Create_DefaultRole_All("1.0")]):
        with cleanup("user10"):
            with When("I create a user with all roles as default"):
                node.query("CREATE USER user10 DEFAULT ROLE ALL")

    with Scenario("I create user with settings profile",
                  flags=TE,
                  requirements=[RQ_SRS_006_RBAC_User_Create_Settings("1.0")]):
        with cleanup("user11"):
            with When("I create a user with a settings profile"):
                node.query(
                    "CREATE USER user11 SETTINGS PROFILE default, max_memory_usage=10000000 READONLY"
                )

    with Scenario(
            "I create user settings profile, fake profile, throws exception",
            flags=TE,
            requirements=[RQ_SRS_006_RBAC_User_Create_Settings("1.0")]):
        with cleanup("user18a"):
            profile = "profile0"
            with Given(f"I ensure that profile {profile} does not exist"):
                node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}")
            with When(
                    f"I create user with Settings and set profile to fake profile {profile}"
            ):
                exitcode, message = errors.settings_profile_not_found_in_disk(
                    profile)
                node.query("CREATE USER user18a SETTINGS PROFILE profile0",
                           exitcode=exitcode,
                           message=message)
            del profile

    with Scenario(
            "I create user settings with a fake setting, throws exception",
            flags=TE,
            requirements=[RQ_SRS_006_RBAC_User_Create_Settings("1.0")]):
        with cleanup("user18b"):
            with When(
                    "I create settings profile using settings and nonexistent value"
            ):
                exitcode, message = errors.unknown_setting("fake_setting")
                node.query(
                    "CREATE USER user18b SETTINGS fake_setting = 100000001",
                    exitcode=exitcode,
                    message=message)

    with Scenario("I create user with settings without profile",
                  flags=TE,
                  requirements=[RQ_SRS_006_RBAC_User_Create_Settings("1.0")]):
        with cleanup("user12"):
            with When("I create a user with settings and no profile"):
                node.query(
                    "CREATE USER user12 SETTINGS max_memory_usage=10000000 READONLY"
                )

    with Scenario("I create user on cluster",
                  flags=TE,
                  requirements=[RQ_SRS_006_RBAC_User_Create_OnCluster("1.0")]):
        try:
            with When("I create user on cluster"):
                node.query("CREATE USER user13 ON CLUSTER sharded_cluster")
        finally:
            with Finally("I drop the user"):
                node.query("DROP USER user13 ON CLUSTER sharded_cluster")

    with Scenario("I create user on fake cluster, throws exception",
                  flags=TE,
                  requirements=[RQ_SRS_006_RBAC_User_Create_OnCluster("1.0")]):
        with When("I create user on fake cluster"):
            exitcode, message = errors.cluster_not_found("fake_cluster")
            node.query("CREATE USER user14 ON CLUSTER fake_cluster",
                       exitcode=exitcode,
                       message=message)
Ejemplo n.º 7
0
def feature(self, node="clickhouse1"):
    """Check drop role query syntax.

    ```sql
    DROP ROLE [IF EXISTS] name [,...] [ON CLUSTER cluster_name]
    ```
    """
    node = self.context.cluster.node(node)

    @contextmanager
    def setup(role):
        try:
            with Given("I have a role"):
                node.query(f"CREATE ROLE OR REPLACE {role}")
            yield
        finally:
            with Finally("I confirm the role is dropped"):
                node.query(f"DROP ROLE IF EXISTS {role}")

    def cleanup_role(role):
        with Given(f"I ensure that role {role} does not exist"):
                node.query(f"DROP ROLE IF EXISTS {role}")


    with Scenario("I drop role with no options", flags=TE, requirements=[
            RQ_SRS_006_RBAC_Role_Drop("1.0")]):
        with setup("role0"):
            with When("I drop role"):
                node.query("DROP ROLE role0")

    with Scenario("I drop role that doesn't exist, throws exception", flags=TE, requirements=[
            RQ_SRS_006_RBAC_Role_Drop("1.0")]):
        role = "role0"
        cleanup_role(role)
        with When(f"I drop role {role}"):
            exitcode, message = errors.role_not_found_in_disk(name=role)
            node.query(f"DROP ROLE {role}", exitcode=exitcode, message=message)
        del role

    with Scenario("I drop multiple roles", flags=TE, requirements=[
            RQ_SRS_006_RBAC_Role_Drop("1.0")]):
        with setup("role1"), setup("role2"):
            with When("I drop multiple roles"):
                node.query("DROP ROLE role1, role2")

    with Scenario("I drop role that does not exist, using if exists", flags=TE, requirements=[
            RQ_SRS_006_RBAC_Role_Drop_IfExists("1.0")]):
        with When("I drop role if exists"):
            node.query("DROP ROLE IF EXISTS role3")

    with Scenario("I drop multiple roles where one does not exist", flags=TE, requirements=[
            RQ_SRS_006_RBAC_Role_Drop_IfExists("1.0")]):
        with setup("role5"):
            with When("I drop multiple roles where one doesnt exist"):
                node.query("DROP ROLE IF EXISTS role3, role5")

    with Scenario("I drop multiple roles where both do not exist", flags = TE, requirements=[
            RQ_SRS_006_RBAC_Role_Drop_IfExists("1.0")]):
        with Given("I ensure role does not exist"):
            node.query("DROP ROLE IF EXISTS role6")
        with When("I drop the nonexistant roles"):
            node.query("DROP USER IF EXISTS role5, role6")

    with Scenario("I drop role on cluster", flags=TE, requirements=[
            RQ_SRS_006_RBAC_Role_Drop_Cluster("1.0")]):
        with Given("I have a role on cluster"):
            node.query("CREATE ROLE OR REPLACE role0 ON CLUSTER sharded_cluster")
        with When("I drop the role from the cluster"):
            node.query("DROP ROLE IF EXISTS role0 ON CLUSTER sharded_cluster")

    with Scenario("I drop role on fake cluster", flags=TE, requirements=[
                RQ_SRS_006_RBAC_Role_Drop_Cluster("1.0")]):
        with When("I run drop role command"):
            exitcode, message = errors.cluster_not_found("fake_cluster")
            node.query("DROP ROLE role2 ON CLUSTER fake_cluster", exitcode=exitcode, message=message)
Ejemplo n.º 8
0
def feature(self, node="clickhouse1"):
    """Check revoke query syntax.

    ```sql
    REVOKE [ON CLUSTER cluster_name] [ADMIN OPTION FOR]
        role [,...] FROM {user | role | CURRENT_USER} [,...]
             | ALL | ALL EXCEPT {user_name | role_name | CURRENT_USER} [,...]
    ```
    """
    node = self.context.cluster.node(node)

    @contextmanager
    def setup(users=2, roles=2):
        try:
            with Given("I have some users"):
                for i in range(users):
                    node.query(f"CREATE USER OR REPLACE user{i}")
            with And("I have some roles"):
                for i in range(roles):
                    node.query(f"CREATE ROLE OR REPLACE role{i}")
            yield
        finally:
            with Finally("I drop the users"):
                for i in range(users):
                    node.query(f"DROP USER IF EXISTS user{i}")
            with And("I drop the roles"):
                for i in range(roles):
                    node.query(f"DROP ROLE IF EXISTS role{i}")

    with Scenario("I revoke a role from a user",
                  requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]):
        with setup():
            with When("I revoke a role"):
                node.query("REVOKE role0 FROM user0")

    with Scenario("I revoke a nonexistent role from user",
                  requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]):
        with setup(1, 0):
            with When("I revoke nonexistent role from a user"):
                exitcode, message = errors.role_not_found_in_disk(name="role0")
                node.query("REVOKE role0 FROM user0",
                           exitcode=exitcode,
                           message=message)

    # with nonexistent object name, REVOKE assumes type role (treats user0 as role)
    with Scenario("I revoke a role from a nonexistent user",
                  requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]):
        with setup(0, 1):
            with When("I revoke role from a nonexistent user"):
                exitcode, message = errors.role_not_found_in_disk(name="user0")
                node.query("REVOKE role0 FROM user0",
                           exitcode=exitcode,
                           message=message)

    # with nonexistent object name, REVOKE assumes type role (treats user0 as role)
    with Scenario("I revoke a role from ALL EXCEPT nonexistent user",
                  requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]):
        with setup(0, 1):
            with When("I revoke role from a nonexistent user"):
                exitcode, message = errors.role_not_found_in_disk(name="user0")
                node.query("REVOKE role0 FROM ALL EXCEPT user0",
                           exitcode=exitcode,
                           message=message)

    with Scenario("I revoke a nonexistent role from a nonexistent user",
                  requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]):
        with setup(0, 0):
            with When("I revoke nonexistent role from a nonexistent user"):
                exitcode, message = errors.role_not_found_in_disk(name="user0")
                node.query("REVOKE role0 FROM user0",
                           exitcode=exitcode,
                           message=message)

    with Scenario("I revoke a role from multiple users",
                  requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]):
        with setup():
            with When("I revoke a role from multiple users"):
                node.query("REVOKE role0 FROM user0, user1")

    with Scenario("I revoke multiple roles from multiple users",
                  requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]):
        with setup():
            node.query("REVOKE role0, role1 FROM user0, user1")

    #user is default, expect exception
    with Scenario("I revoke a role from default user",
                  requirements=[
                      RQ_SRS_006_RBAC_Revoke_Role("1.0"),
                      RQ_SRS_006_RBAC_Revoke_Role_Keywords("1.0")
                  ]):
        with setup():
            with When("I revoke a role from default user"):
                exitcode, message = errors.cannot_update_default()
                node.query("REVOKE role0 FROM CURRENT_USER",
                           exitcode=exitcode,
                           message=message)

    #user is user0
    with Scenario("I revoke a role from current user",
                  requirements=[
                      RQ_SRS_006_RBAC_Revoke_Role("1.0"),
                      RQ_SRS_006_RBAC_Revoke_Role_Keywords("1.0")
                  ]):
        with setup():
            with When("I revoke a role from current user"):
                node.query("REVOKE role0 FROM CURRENT_USER",
                           settings=[("user", "user0")])

    #user is default, expect exception
    with Scenario("I revoke a role from all",
                  requirements=[
                      RQ_SRS_006_RBAC_Revoke_Role("1.0"),
                      RQ_SRS_006_RBAC_Revoke_Role_Keywords("1.0")
                  ]):
        with setup():
            with When("I revoke a role from all"):
                exitcode, message = errors.cannot_update_default()
                node.query("REVOKE role0 FROM ALL",
                           exitcode=exitcode,
                           message=message)

    #user is default, expect exception
    with Scenario("I revoke multiple roles from all",
                  requirements=[
                      RQ_SRS_006_RBAC_Revoke_Role("1.0"),
                      RQ_SRS_006_RBAC_Revoke_Role_Keywords("1.0")
                  ]):
        with setup():
            with When("I revoke multiple roles from all"):
                exitcode, message = errors.cannot_update_default()
                node.query("REVOKE role0, role1 FROM ALL",
                           exitcode=exitcode,
                           message=message)

    with Scenario("I revoke a role from all but current user",
                  requirements=[
                      RQ_SRS_006_RBAC_Revoke_Role("1.0"),
                      RQ_SRS_006_RBAC_Revoke_Role_Keywords("1.0")
                  ]):
        with setup():
            with When("I revoke a role from all except current"):
                node.query("REVOKE role0 FROM ALL EXCEPT CURRENT_USER")

    with Scenario("I revoke a role from all but default user",
                  requirements=[
                      RQ_SRS_006_RBAC_Revoke_Role("1.0"),
                      RQ_SRS_006_RBAC_Revoke_Role_Keywords("1.0")
                  ]):
        with setup():
            with When("I revoke a role from all except default"):
                node.query("REVOKE role0 FROM ALL EXCEPT default",
                           settings=[("user", "user0")])

    with Scenario("I revoke multiple roles from all but default user",
                  requirements=[
                      RQ_SRS_006_RBAC_Revoke_Role("1.0"),
                      RQ_SRS_006_RBAC_Revoke_Role_Keywords("1.0")
                  ]):
        with setup():
            with When("I revoke multiple roles from all except default"):
                node.query("REVOKE role0, role1 FROM ALL EXCEPT default",
                           settings=[("user", "user0")])

    with Scenario("I revoke a role from a role",
                  requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]):
        with setup():
            with When("I revoke a role from a role"):
                node.query("REVOKE role0 FROM role1")

    with Scenario("I revoke a role from a role and a user",
                  requirements=[RQ_SRS_006_RBAC_Revoke_Role("1.0")]):
        with setup():
            with When("I revoke a role from multiple roles"):
                node.query("REVOKE role0 FROM role1, user0")

    with Scenario("I revoke a role from a user on cluster",
                  requirements=[RQ_SRS_006_RBAC_Revoke_Role_Cluster("1.0")]):
        with Given("I have a role and a user on a cluster"):
            node.query(
                "CREATE USER OR REPLACE user0 ON CLUSTER sharded_cluster")
            node.query(
                "CREATE ROLE OR REPLACE role0 ON CLUSTER sharded_cluster")
        with When("I revoke a role from user on a cluster"):
            node.query("REVOKE ON CLUSTER sharded_cluster role0 FROM user0")
        with Finally("I drop the user and role"):
            node.query("DROP USER IF EXISTS user0 ON CLUSTER sharded_cluster")
            node.query("DROP ROLE IF EXISTS role0 ON CLUSTER sharded_cluster")

    with Scenario("I revoke a role on fake cluster, throws exception",
                  requirements=[RQ_SRS_006_RBAC_Revoke_Role_Cluster("1.0")]):
        with Given("I have a role and a user on a cluster"):
            node.query("CREATE USER OR REPLACE user0")
            node.query("CREATE ROLE OR REPLACE role0")
        with When("I revoke a role from user on a cluster"):
            exitcode, message = errors.cluster_not_found("fake_cluster")
            node.query("REVOKE ON CLUSTER fake_cluster role0 FROM user0",
                       exitcode=exitcode,
                       message=message)
        with Finally("I drop the user and role"):
            node.query("DROP USER IF EXISTS user0")
            node.query("DROP ROLE IF EXISTS role0")

    with Scenario("I revoke multiple roles from multiple users on cluster",
                  requirements=[
                      RQ_SRS_006_RBAC_Revoke_Role("1.0"),
                      RQ_SRS_006_RBAC_Revoke_Role_Cluster("1.0")
                  ]):
        with Given("I have multiple roles and multiple users on a cluster"):
            for i in range(2):
                node.query(
                    f"CREATE USER OR REPLACE user{i} ON CLUSTER sharded_cluster"
                )
                node.query(
                    f"CREATE ROLE OR REPLACE role{i} ON CLUSTER sharded_cluster"
                )
        with When("I revoke multiple roles from multiple users on cluster"):
            node.query(
                "REVOKE ON CLUSTER sharded_cluster role0, role1 FROM user0, user1"
            )
        with Finally("I drop the roles and users"):
            for i in range(2):
                node.query(
                    f"DROP USER IF EXISTS user{i} ON CLUSTER sharded_cluster")
                node.query(
                    f"DROP ROLE IF EXISTS role{i} ON CLUSTER sharded_cluster")

    with Scenario("I revoke admin option for role from a user",
                  requirements=[RQ_SRS_006_RBAC_Revoke_AdminOption("1.0")]):
        with setup():
            with When("I revoke admin option for role from a user"):
                node.query("REVOKE ADMIN OPTION FOR role0 FROM user0")

    with Scenario(
            "I revoke admin option for multiple roles from multiple users",
            requirements=[
                RQ_SRS_006_RBAC_Revoke_Role("1.0"),
                RQ_SRS_006_RBAC_Revoke_AdminOption("1.0")
            ]):
        with setup():
            with When(
                    "I revoke admin option for multiple roles from multiple users"
            ):
                node.query(
                    "REVOKE ADMIN OPTION FOR role0, role1 FROM user0, user1")
Ejemplo n.º 9
0
def feature(self, node="clickhouse1"):
    """Check alter row policy query syntax.

    ```sql
    ALTER [ROW] POLICY [IF EXISTS] name [ON CLUSTER cluster_name] ON [database.]table
    [RENAME TO new_name]
    [AS {PERMISSIVE | RESTRICTIVE}]
    [FOR SELECT]
    [USING {condition | NONE}][,...]
    [TO {role [,...] | ALL | ALL EXCEPT role [,...]}]
    ```
    """
    node = self.context.cluster.node(node)

    @contextmanager
    def cleanup(policy):
        try:
            with Given("I have a row policy"):
                node.query(f"CREATE ROW POLICY {policy} ON default.foo")
            yield
        finally:
            with Finally("I drop the row policy"):
                node.query(f"DROP ROW POLICY IF EXISTS {policy} ON default.foo")

    def cleanup_policy(policy):
        with Given(f"I ensure that policy {policy} does not exist"):
            node.query(f"DROP ROW POLICY IF EXISTS {policy} ON default.foo")

    try:
        with Given("I have a table and some roles"):
            node.query(f"CREATE TABLE default.foo (x UInt64, y String) Engine=Memory")
            node.query(f"CREATE ROLE role0")
            node.query(f"CREATE ROLE role1")

        with Scenario("I alter row policy with no options", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy0"):
                with When("I alter row policy"):
                    node.query("ALTER ROW POLICY policy0 ON default.foo")

        with Scenario("I alter row policy using short syntax with no options", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy1"):
                with When("I alter row policy short form"):
                    node.query("ALTER POLICY policy1 ON default.foo")

        with Scenario("I alter row policy, does not exist, throws exception", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            policy = "policy2"
            cleanup_policy(policy)
            with When(f"I alter row policy {policy} that doesn't exist"):
                exitcode, message = errors.row_policy_not_found_in_disk(name=f"{policy} ON default.foo")
                node.query(f"ALTER ROW POLICY {policy} ON default.foo", exitcode=exitcode, message=message)
            del policy

        with Scenario("I alter row policy if exists", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_IfExists("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy2"):
                with When("I alter row policy using if exists"):
                    node.query("ALTER ROW POLICY IF EXISTS policy2 ON default.foo")

        with Scenario("I alter row policy if exists, policy does not exist", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_IfExists("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            policy = "policy2"
            cleanup_policy(policy)
            with When(f"I alter row policy {policy} that doesn't exist"):
                node.query(f"ALTER ROW POLICY IF EXISTS {policy} ON default.foo")
            del policy

        with Scenario("I alter row policy to rename, target available", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_Rename("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy3"):
                with When("I alter row policy with rename"):
                    node.query("ALTER ROW POLICY policy3 ON default.foo RENAME TO policy3")

        with Scenario("I alter row policy to rename, target unavailable", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_Rename("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy3"):
                new_policy = "policy4"
                try:
                    with Given(f"Ensure target name {new_policy} is NOT available"):
                        node.query(f"CREATE ROW POLICY IF NOT EXISTS {new_policy} ON default.foo")
                    with When(f"I try to rename to {new_policy}"):
                        exitcode, message = errors.cannot_rename_row_policy(name="policy3 ON default.foo",
                                                                            name_new=f"{new_policy} ON default.foo")
                        node.query(f"ALTER ROW POLICY policy3 ON default.foo RENAME TO {new_policy}", exitcode=exitcode, message=message)
                finally:
                    with Finally(f"I cleanup target name {new_policy}"):
                        node.query(f"DROP ROW POLICY IF EXISTS {new_policy} ON default.foo")
            del new_policy

        with Scenario("I alter row policy to permissive", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_Access_Permissive("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy4"):
                with When("I alter row policy as permissive"):
                    node.query("ALTER ROW POLICY policy4 ON default.foo AS PERMISSIVE")

        with Scenario("I alter row policy to restrictive", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_Access_Restrictive("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy5"):
                with When("I alter row policy as restrictive"):
                    node.query("ALTER ROW POLICY policy5 ON default.foo AS RESTRICTIVE")

        with Scenario("I alter row policy for select", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_ForSelect("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy6"):
                with When("I alter row policy using for select"):
                    node.query("ALTER ROW POLICY policy6 ON default.foo FOR SELECT USING x > 10")

        with Scenario("I alter row policy using condition", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_Condition("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy6"):
                with When("I alter row policy wtih condition"):
                    node.query("ALTER ROW POLICY policy6 ON default.foo USING x > 10")

        with Scenario("I alter row policy using condition none", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_Condition_None("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy7"):
                with When("I alter row policy using no condition"):
                    node.query("ALTER ROW POLICY policy7 ON default.foo USING NONE")

        with Scenario("I alter row policy to one role", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy8"):
                with When("I alter row policy to a role"):
                    node.query("ALTER ROW POLICY policy8 ON default.foo TO role0")

        with Scenario("I alter row policy to assign to role that does not exist, throws exception", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment("1.0")]):
            role = "role2"
            with cleanup("policy8a"):
                with Given(f"I drop {role} if it exists"):
                    node.query(f"DROP ROLE IF EXISTS {role}")
                with Then(f"I alter a row policy, assign to role {role}, which does not exist"):
                    exitcode, message = errors.role_not_found_in_disk(name=role)
                    node.query(f"ALTER ROW POLICY policy8a ON default.foo TO {role}", exitcode=exitcode, message=message)
            del role

        with Scenario("I alter row policy to assign to all excpet role that does not exist, throws exception", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment("1.0")]):
            role = "role2"
            with cleanup("policy8a"):
                with Given(f"I drop {role} if it exists"):
                    node.query(f"DROP ROLE IF EXISTS {role}")
                with Then(f"I alter a row policy, assign to all except role {role}, which does not exist"):
                    exitcode, message = errors.role_not_found_in_disk(name=role)
                    node.query(f"ALTER ROW POLICY policy8a ON default.foo TO ALL EXCEPT {role}", exitcode=exitcode, message=message)
            del role

        with Scenario("I alter row policy assigned to multiple roles", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy9"):
                with When("I alter row policy to multiple roles"):
                    node.query("ALTER ROW POLICY policy9 ON default.foo TO role0, role1")

        with Scenario("I alter row policy assigned to all", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment_All("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy10"):
                with When("I alter row policy to all"):
                    node.query("ALTER ROW POLICY policy10 ON default.foo TO ALL")

        with Scenario("I alter row policy assigned to all except one role", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment_AllExcept("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy11"):
                with When("I alter row policy to all except"):
                    node.query("ALTER ROW POLICY policy11 ON default.foo TO ALL EXCEPT role0")

        with Scenario("I alter row policy assigned to all except multiple roles", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment_AllExcept("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy12"):
                with When("I alter row policy to all except multiple roles"):
                    node.query("ALTER ROW POLICY policy12 ON default.foo TO ALL EXCEPT role0, role1")

        with Scenario("I alter row policy assigned to none", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_Assignment_None("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with cleanup("policy12"):
                with When("I alter row policy to no assignment"):
                    node.query("ALTER ROW POLICY policy12 ON default.foo TO NONE")

        # Official syntax: ON CLUSTER cluster_name ON database.table
        # Working syntax: both orderings of ON CLUSTER and TABLE clauses work

        with Scenario("I alter row policy on cluster", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_OnCluster("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            try:
                with Given("I have a row policy"):
                    node.query("CREATE ROW POLICY policy13 ON CLUSTER sharded_cluster ON default.foo")
                with When("I run alter row policy command"):
                    node.query("ALTER ROW POLICY policy13 ON CLUSTER sharded_cluster ON default.foo")
            finally:
                with Finally("I drop the row policy"):
                    node.query("DROP ROW POLICY IF EXISTS policy13 ON CLUSTER sharded_cluster ON default.foo")

        with Scenario("I alter row policy on fake cluster, throws exception", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_OnCluster("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            with When("I run alter row policy command"):
                exitcode, message = errors.cluster_not_found("fake_cluster")
                node.query("ALTER ROW POLICY policy13 ON CLUSTER fake_cluster ON default.foo", exitcode=exitcode, message=message)

        with Scenario("I alter row policy on cluster after table", requirements=[
                RQ_SRS_006_RBAC_RowPolicy_Alter_OnCluster("1.0"),
                RQ_SRS_006_RBAC_RowPolicy_Alter_On("1.0")]):
            try:
                with Given("I have a row policy"):
                    node.query("CREATE ROW POLICY policy14 ON default.foo ON CLUSTER sharded_cluster")
                with When("I run create row policy command"):
                    node.query("ALTER ROW POLICY policy14 ON default.foo ON CLUSTER sharded_cluster")
            finally:
                with Finally("I drop the row policy"):
                    node.query("DROP ROW POLICY IF EXISTS policy14 ON default.foo ON CLUSTER sharded_cluster")
    finally:
        with Finally("I drop the table and the roles"):
            node.query(f"DROP TABLE IF EXISTS default.foo")
            node.query(f"DROP ROLE IF EXISTS role0, role1")
Ejemplo n.º 10
0
def feature(self, node="clickhouse1"):
    """Check drop quota query syntax.

    ```sql
    DROP QUOTA [IF EXISTS] name [,...] [ON CLUSTER cluster_name]
    ```
    """
    node = self.context.cluster.node(node)

    @contextmanager
    def cleanup(quota):
        try:
            with Given("I have a quota"):
                node.query(f"CREATE QUOTA {quota}")
            yield
        finally:
            with Finally("I drop the quota"):
                node.query(f"DROP QUOTA IF EXISTS {quota}")

    def cleanup_quota(quota):
        with Given(f"I ensure that quota {quota} does not exist"):
            node.query(f"DROP QUOTA IF EXISTS {quota}")

    with Scenario("I drop quota with no options", flags=TE, requirements=[
            RQ_SRS_006_RBAC_Quota_Drop("1.0")]):
        with cleanup("quota0"):
            with When("I run drop quota command"):
                node.query("DROP QUOTA quota0")

    with Scenario("I drop quota, does not exist, throws exception", flags=TE, requirements=[
            RQ_SRS_006_RBAC_Quota_Drop("1.0")]):
        quota = "quota0"
        cleanup_quota(quota)
        with When("I run drop quota command, throws exception"):
            exitcode, message = errors.quota_not_found_in_disk(name=quota)
            node.query(f"DROP QUOTA {quota}", exitcode=exitcode, message=message)
        del quota

    with Scenario("I drop quota if exists, quota exists", flags=TE, requirements=[
            RQ_SRS_006_RBAC_Quota_Drop_IfExists("1.0")]):
        with cleanup("quota1"):
            with When("I run drop quota command"):
                node.query("DROP QUOTA IF EXISTS quota1")

    with Scenario("I drop quota if exists, quota does not exist", flags=TE, requirements=[
            RQ_SRS_006_RBAC_Quota_Drop_IfExists("1.0")]):
        cleanup_quota("quota2")
        with When("I run drop quota command, quota does not exist"):
            node.query("DROP QUOTA IF EXISTS quota2")

    with Scenario("I drop default quota, throws error", flags=TE, requirements=[
            RQ_SRS_006_RBAC_Quota_Drop("1.0")]):
        with When("I drop default quota"):
            exitcode, message = errors.cannot_remove_quota_default()
            node.query("DROP QUOTA default", exitcode=exitcode, message=message)

    with Scenario("I drop multiple quotas", flags=TE, requirements=[
            RQ_SRS_006_RBAC_Quota_Drop("1.0")]):
        with cleanup("quota2"), cleanup("quota3"):
            with When("I run drop quota command"):
                node.query("DROP QUOTA quota2, quota3")

    with Scenario("I drop quota on cluster", flags=TE, requirements=[
            RQ_SRS_006_RBAC_Quota_Drop_Cluster("1.0")]):
        try:
            with Given("I have a quota"):
                node.query("CREATE QUOTA quota4 ON CLUSTER sharded_cluster")
            with When("I run drop quota command"):
                node.query("DROP QUOTA quota4 ON CLUSTER sharded_cluster")
        finally:
            with Finally("I drop the quota in case it still exists"):
                node.query("DROP QUOTA IF EXISTS quota4 ON CLUSTER sharded_cluster")

    with Scenario("I drop quota on fake cluster", flags=TE, requirements=[
            RQ_SRS_006_RBAC_Quota_Drop_Cluster("1.0")]):
        with When("I run drop quota command"):
            exitcode, message = errors.cluster_not_found("fake_cluster")
            node.query("DROP QUOTA quota5 ON CLUSTER fake_cluster", exitcode=exitcode, message=message)
Ejemplo n.º 11
0
def feature(self, node="clickhouse1"):
    """Check drop settings profile query syntax.

    ```sql
    DROP [SETTINGS] PROFILE [IF EXISTS] name [,...] [ON CLUSTER cluster_name]
    ```
    """
    node = self.context.cluster.node(node)

    @contextmanager
    def cleanup(profile):
        try:
            with Given("I have a settings profile"):
                node.query(f"CREATE SETTINGS PROFILE {profile}")
            yield
        finally:
            with Finally("I drop the settings profile"):
                node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}")

    def cleanup_profile(profile):
        with Given(f"I ensure that profile {profile} does not exist"):
            node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}")

    with Scenario(
        "I drop settings profile with no options",
        requirements=[RQ_SRS_006_RBAC_SettingsProfile_Drop("1.0")],
    ):
        with cleanup("profile0"):
            with When("I drop settings profile"):
                node.query("DROP SETTINGS PROFILE profile0")

    with Scenario(
        "I drop settings profile, does not exist, throws exception",
        requirements=[RQ_SRS_006_RBAC_SettingsProfile_Drop("1.0")],
    ):
        profile = "profile0"
        cleanup_profile(profile)
        with When("I drop settings profile"):
            exitcode, message = errors.settings_profile_not_found_in_disk(name=profile)
            node.query(
                "DROP SETTINGS PROFILE profile0", exitcode=exitcode, message=message
            )
        del profile

    with Scenario(
        "I drop settings profile short form",
        requirements=[RQ_SRS_006_RBAC_SettingsProfile_Drop("1.0")],
    ):
        with cleanup("profile1"):
            with When("I drop settings profile short form"):
                node.query("DROP PROFILE profile1")

    with Scenario(
        "I drop settings profile if exists, profile does exist",
        requirements=[RQ_SRS_006_RBAC_SettingsProfile_Drop_IfExists("1.0")],
    ):
        with cleanup("profile2"):
            with When("I drop settings profile if exists"):
                node.query("DROP SETTINGS PROFILE IF EXISTS profile2")

    with Scenario(
        "I drop settings profile if exists, profile does not exist",
        requirements=[RQ_SRS_006_RBAC_SettingsProfile_Drop_IfExists("1.0")],
    ):
        cleanup_profile("profile2")
        with When("I drop settings profile if exists"):
            node.query("DROP SETTINGS PROFILE IF EXISTS profile2")

    with Scenario(
        "I drop default settings profile, throws error",
        requirements=[RQ_SRS_006_RBAC_SettingsProfile_Drop("1.0")],
    ):
        with When("I drop default profile"):
            exitcode, message = errors.cannot_remove_settings_profile_default()
            node.query(
                "DROP SETTINGS PROFILE default", exitcode=exitcode, message=message
            )

    with Scenario(
        "I drop multiple settings profiles",
        requirements=[RQ_SRS_006_RBAC_SettingsProfile_Drop("1.0")],
    ):
        with cleanup("profile3"), cleanup("profile4"):
            with When("I drop multiple settings profiles"):
                node.query("DROP SETTINGS PROFILE profile3, profile4")

    with Scenario(
        "I drop settings profile on cluster",
        requirements=[RQ_SRS_006_RBAC_SettingsProfile_Drop_OnCluster("1.0")],
    ):
        try:
            with Given("I have a settings profile"):
                node.query(
                    "CREATE SETTINGS PROFILE profile5 ON CLUSTER sharded_cluster"
                )
            with When("I run drop settings profile command"):
                node.query("DROP SETTINGS PROFILE profile5 ON CLUSTER sharded_cluster")
        finally:
            with Finally("I drop the profile in case it still exists"):
                node.query(
                    "DROP SETTINGS PROFILE IF EXISTS profile5 ON CLUSTER sharded_cluster"
                )

    with Scenario(
        "I drop settings profile on fake cluster, throws exception",
        requirements=[RQ_SRS_006_RBAC_SettingsProfile_Drop_OnCluster("1.0")],
    ):
        with When("I run drop settings profile command"):
            exitcode, message = errors.cluster_not_found("fake_cluster")
            node.query(
                "DROP SETTINGS PROFILE profile6 ON CLUSTER fake_cluster",
                exitcode=exitcode,
                message=message,
            )
Ejemplo n.º 12
0
def feature(self, node="clickhouse1"):
    """Check create row policy query syntax.

    ```sql
    CREATE [ROW] POLICY [IF NOT EXISTS | OR REPLACE] policy_name [ON CLUSTER cluster_name] ON [db.]table
    [AS {PERMISSIVE | RESTRICTIVE}]
    [FOR SELECT]
    [USING condition]
    [TO {role [,...] | ALL | ALL EXCEPT role [,...]}]
    ```
    """
    node = self.context.cluster.node(node)

    @contextmanager
    def cleanup(policy, on="default.foo"):
        try:
            with Given(
                    f"I ensure the row policy does not already exist on {on}"):
                node.query(f"DROP ROW POLICY IF EXISTS {policy} ON {on}")
            yield
        finally:
            with Finally(f"I drop the row policy on {on}"):
                node.query(f"DROP ROW POLICY IF EXISTS {policy} ON {on}")

    def create_policy(policy, on="default.foo"):
        with Given(f"I ensure I do have policy {policy} on {on}"):
            node.query(f"CREATE ROW POLICY OR REPLACE {policy} ON {on}")

    try:
        with Given("I have a table and some roles"):
            node.query(
                f"CREATE TABLE default.foo (x UInt64, y String) Engine=Memory")
            node.query(f"CREATE ROLE role0")
            node.query(f"CREATE ROLE role1")

        with Scenario("I create row policy with no options",
                      flags=TE,
                      requirements=[
                          RQ_SRS_006_RBAC_RowPolicy_Create("1.0"),
                          RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                      ]):
            with cleanup("policy0"):
                with When("I create row policy"):
                    node.query("CREATE ROW POLICY policy0 ON default.foo")

        with Scenario("I create row policy using short syntax with no options",
                      flags=TE,
                      requirements=[
                          RQ_SRS_006_RBAC_RowPolicy_Create("1.0"),
                          RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                      ]):
            with cleanup("policy1"):
                with When("I create row policy short form"):
                    node.query("CREATE POLICY policy1 ON default.foo")

        with Scenario(
                "I create row policy that already exists, throws exception",
                flags=TE,
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Create("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                ]):
            policy = "policy0"
            with cleanup(policy):
                create_policy(policy)
                with When(f"I create row policy {policy}"):
                    exitcode, message = errors.cannot_insert_row_policy(
                        name=f"{policy} ON default.foo")
                    node.query(f"CREATE ROW POLICY {policy} ON default.foo",
                               exitcode=exitcode,
                               message=message)
            del policy

        with Scenario(
                "I create row policy if not exists, policy does not exist",
                flags=TE,
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Create_IfNotExists("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                ]):
            with cleanup("policy2"):
                with When("I create row policy with if not exists"):
                    node.query(
                        "CREATE ROW POLICY IF NOT EXISTS policy2 ON default.foo"
                    )

        with Scenario("I create row policy if not exists, policy does exist",
                      flags=TE,
                      requirements=[
                          RQ_SRS_006_RBAC_RowPolicy_Create_IfNotExists("1.0"),
                          RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                      ]):
            policy = "policy2"
            with cleanup(policy):
                create_policy(policy)
                with When(f"I create row policy {policy} with if not exists"):
                    node.query(
                        f"CREATE ROW POLICY IF NOT EXISTS {policy} ON default.foo"
                    )
            del policy

        with Scenario("I create row policy or replace, policy does not exist",
                      flags=TE,
                      requirements=[
                          RQ_SRS_006_RBAC_RowPolicy_Create_Replace("1.0"),
                          RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                      ]):
            with cleanup("policy3"):
                with When("I create row policy with or replace"):
                    node.query(
                        "CREATE ROW POLICY OR REPLACE policy3 ON default.foo")

        with Scenario("I create row policy or replace, policy does exist",
                      flags=TE,
                      requirements=[
                          RQ_SRS_006_RBAC_RowPolicy_Create_Replace("1.0"),
                          RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                      ]):
            policy = "policy3"
            with cleanup(policy):
                create_policy(policy)
                with When(f"I create row policy {policy} with or replace"):
                    node.query(
                        f"CREATE ROW POLICY OR REPLACE {policy} ON default.foo"
                    )
            del policy

        with Scenario(
                "I create row policy as permissive",
                flags=TE,
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Create_Access_Permissive("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                ]):
            with cleanup("policy4"):
                with When("I create row policy as permissive"):
                    node.query(
                        "CREATE ROW POLICY policy4 ON default.foo AS PERMISSIVE"
                    )

        with Scenario(
                "I create row policy as restrictive",
                flags=TE,
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Create_Access_Restrictive("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                ]):
            with cleanup("policy5"):
                with When("I create row policy as restrictive"):
                    node.query(
                        "CREATE ROW POLICY policy5 ON default.foo AS RESTRICTIVE"
                    )

        with Scenario("I create row policy for select",
                      flags=TE,
                      requirements=[
                          RQ_SRS_006_RBAC_RowPolicy_Create_ForSelect("1.0"),
                          RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0"),
                          RQ_SRS_006_RBAC_RowPolicy_Create_Condition("1.0")
                      ]):
            with cleanup("policy6"):
                with When("I create row policy with for select"):
                    node.query(
                        "CREATE ROW POLICY policy6 ON default.foo FOR SELECT USING x > 10"
                    )

        with Scenario("I create row policy using condition",
                      flags=TE,
                      requirements=[
                          RQ_SRS_006_RBAC_RowPolicy_Create_Condition("1.0"),
                          RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                      ]):
            with cleanup("policy6"):
                with When("I create row policy with condition"):
                    node.query(
                        "CREATE ROW POLICY policy6 ON default.foo USING x > 10"
                    )

        with Scenario("I create row policy assigned to one role",
                      flags=TE,
                      requirements=[
                          RQ_SRS_006_RBAC_RowPolicy_Create_Assignment("1.0"),
                          RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                      ]):
            with cleanup("policy7"):
                with When("I create row policy for one role"):
                    node.query(
                        "CREATE ROW POLICY policy7 ON default.foo TO role0")

        with Scenario(
                "I create row policy to assign to role that does not exist, throws exception",
                flags=TE,
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Create_Assignment("1.0")
                ]):
            role = "role2"
            with cleanup("policy8a"):
                with Given(f"I drop {role} if it exists"):
                    node.query(f"DROP ROLE IF EXISTS {role}")
                with Then(
                        f"I create a row policy, assign to role {role}, which does not exist"
                ):
                    exitcode, message = errors.role_not_found_in_disk(
                        name=role)
                    node.query(
                        f"CREATE ROW POLICY policy8a ON default.foo TO {role}",
                        exitcode=exitcode,
                        message=message)
            del role

        with Scenario(
                "I create row policy to assign to all excpet role that does not exist, throws exception",
                flags=TE,
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Create_Assignment("1.0")
                ]):
            role = "role2"
            with cleanup("policy8a"):
                with Given(f"I drop {role} if it exists"):
                    node.query(f"DROP ROLE IF EXISTS {role}")
                with Then(
                        f"I create a row policy, assign to all except role {role}, which does not exist"
                ):
                    exitcode, message = errors.role_not_found_in_disk(
                        name=role)
                    node.query(
                        f"CREATE ROW POLICY policy8a ON default.foo TO ALL EXCEPT {role}",
                        exitcode=exitcode,
                        message=message)
            del role

        with Scenario("I create row policy assigned to multiple roles",
                      flags=TE,
                      requirements=[
                          RQ_SRS_006_RBAC_RowPolicy_Create_Assignment("1.0"),
                          RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                      ]):
            with cleanup("policy8b"):
                with When("I create row policy for multiple roles"):
                    node.query(
                        "CREATE ROW POLICY policy8b ON default.foo TO role0, role1"
                    )

        with Scenario(
                "I create row policy assigned to all",
                flags=TE,
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Create_Assignment_All("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                ]):
            with cleanup("policy9"):
                with When("I create row policy for all"):
                    node.query(
                        "CREATE ROW POLICY policy9 ON default.foo TO ALL")

        with Scenario(
                "I create row policy assigned to all except one role",
                flags=TE,
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Create_Assignment_AllExcept(
                        "1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                ]):
            with cleanup("policy10"):
                with When("I create row policy for all except one"):
                    node.query(
                        "CREATE ROW POLICY policy10 ON default.foo TO ALL EXCEPT role0"
                    )

        with Scenario(
                "I create row policy assigned to all except multiple roles",
                flags=TE,
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Create_Assignment_AllExcept(
                        "1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                ]):
            with cleanup("policy11"):
                with When("I create row policy for all except multiple roles"):
                    node.query(
                        "CREATE ROW POLICY policy11 ON default.foo TO ALL EXCEPT role0, role1"
                    )

        with Scenario(
                "I create row policy assigned to none",
                flags=TE,
                requirements=[
                    RQ_SRS_006_RBAC_RowPolicy_Create_Assignment_None("1.0"),
                    RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                ]):
            with cleanup("policy11"):
                with When("I create row policy for none"):
                    node.query(
                        "CREATE ROW POLICY policy11 ON default.foo TO NONE")

        with Scenario("I create row policy on cluster",
                      flags=TE,
                      requirements=[
                          RQ_SRS_006_RBAC_RowPolicy_Create_OnCluster("1.0"),
                          RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                      ]):
            try:
                with When("I run create row policy command on cluster"):
                    node.query(
                        "CREATE ROW POLICY policy12 ON CLUSTER sharded_cluster ON default.foo"
                    )
            finally:
                with Finally("I drop the row policy from cluster"):
                    node.query(
                        "DROP ROW POLICY IF EXISTS policy12 ON default.foo ON CLUSTER sharded_cluster"
                    )

        with Scenario("I create row policy on fake cluster, throws exception",
                      flags=TE,
                      requirements=[
                          RQ_SRS_006_RBAC_RowPolicy_Create_OnCluster("1.0"),
                          RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                      ]):
            with When("I run create row policy command"):
                exitcode, message = errors.cluster_not_found("fake_cluster")
                node.query(
                    "CREATE ROW POLICY policy13 ON CLUSTER fake_cluster ON default.foo",
                    exitcode=exitcode,
                    message=message)

        with Scenario("I create row policy on cluster after table",
                      flags=TE,
                      requirements=[
                          RQ_SRS_006_RBAC_RowPolicy_Create_OnCluster("1.0"),
                          RQ_SRS_006_RBAC_RowPolicy_Create_On("1.0")
                      ]):
            try:
                with When("I run create row policy command on cluster"):
                    node.query(
                        "CREATE ROW POLICY policy12 ON default.foo ON CLUSTER sharded_cluster"
                    )
            finally:
                with Finally("I drop the row policy from cluster"):
                    node.query(
                        "DROP ROW POLICY IF EXISTS policy12 ON default.foo ON CLUSTER sharded_cluster"
                    )
    finally:
        with Finally("I drop the table and the roles"):
            node.query(f"DROP TABLE IF EXISTS default.foo")
            node.query(f"DROP ROLE IF EXISTS role0, role1")
Ejemplo n.º 13
0
def feature(self, node="clickhouse1"):
    """Check revoke privilege syntax.

    ```sql
    REVOKE [ON CLUSTER cluster_name] privilege
    [(column_name [,...])] [,...]
    ON {db.table|db.*|*.*|table|*}
    FROM {user | CURRENT_USER} [,...] | ALL | ALL EXCEPT {user | CURRENT_USER} [,...]
    ```
    """
    node = self.context.cluster.node(node)

    Scenario(run=revoke_privileges)

    with Scenario("I revoke privilege ON CLUSTER", requirements=[
            RQ_SRS_006_RBAC_Revoke_Privilege_Cluster("1.0"),
            RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]):
        with setup(node):
            with When("I revoke privilege ON CLUSTER"):
                node.query("REVOKE ON CLUSTER sharded_cluster NONE FROM user0")

    with Scenario("I revoke privilege ON fake CLUSTER, throws exception", requirements=[
            RQ_SRS_006_RBAC_Revoke_Privilege_Cluster("1.0"),
            RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]):
        with setup(node):
            with When("I revoke privilege ON CLUSTER"):
                exitcode, message = errors.cluster_not_found("fake_cluster")
                node.query("REVOKE ON CLUSTER fake_cluster NONE FROM user0",
                            exitcode=exitcode, message=message)

    with Scenario("I revoke privilege from multiple users and roles", requirements=[
            RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"),
            RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]):
        with setup(node):
            with When("I revoke privilege from multiple users"):
                node.query("REVOKE NONE FROM user0, user1, role1")

    with Scenario("I revoke privilege from current user", requirements=[
            RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"),
            RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]):
        with setup(node):
            with When("I revoke privilege from current user"):
                node.query("REVOKE NONE FROM CURRENT_USER", settings = [("user","user0")])

    with Scenario("I revoke privilege from all users", requirements=[
            RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"),
            RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]):
        with setup(node):
            with When("I revoke privilege from all users"):
                exitcode, message = errors.cannot_update_default()
                node.query("REVOKE NONE FROM ALL", exitcode=exitcode,message=message)

    with Scenario("I revoke privilege from default user", requirements=[
            RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"),
            RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]):
        with setup(node):
            with When("I revoke privilege from default user"):
                exitcode, message = errors.cannot_update_default()
                node.query("REVOKE NONE FROM default", exitcode=exitcode,message=message)

    #By default, ClickHouse treats unnamed object as role
    with Scenario("I revoke privilege from nonexistent role, throws exception", requirements=[
            RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"),
            RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]):
        role = "role5"
        with Given(f"I ensure that role {role} does not exist"):
            node.query(f"DROP ROLE IF EXISTS {role}")
        with When(f"I revoke privilege from nonexistent role {role}"):
            exitcode, message = errors.role_not_found_in_disk(role)
            node.query(f"REVOKE NONE FROM {role}", exitcode=exitcode,message=message)

    with Scenario("I revoke privilege from ALL EXCEPT nonexistent role, throws exception", requirements=[
            RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"),
            RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]):
        role = "role5"
        with Given(f"I ensure that role {role} does not exist"):
            node.query(f"DROP ROLE IF EXISTS {role}")
        with When(f"I revoke privilege from nonexistent role {role}"):
            exitcode, message = errors.role_not_found_in_disk(role)
            node.query(f"REVOKE NONE FROM ALL EXCEPT {role}", exitcode=exitcode,message=message)

    with Scenario("I revoke privilege from all except some users and roles", requirements=[
            RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"),
            RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]):
        with setup(node):
            with When("I revoke privilege all except some users"):
                node.query("REVOKE NONE FROM ALL EXCEPT default, user0, role1")

    with Scenario("I revoke privilege from all except current user", requirements=[
            RQ_SRS_006_RBAC_Revoke_Privilege_From("1.0"),
            RQ_SRS_006_RBAC_Revoke_Privilege_None("1.0")]):
        with setup(node):
            with When("I revoke privilege from all except current user"):
                node.query("REVOKE NONE FROM ALL EXCEPT CURRENT_USER")
Ejemplo n.º 14
0
def feature(self, node="clickhouse1"):
    """Check grant query syntax.

    ```sql
    GRANT ON CLUSTER [cluster_name] role [,...] TO {user | another_role | CURRENT_USER} [,...] [WITH ADMIN OPTION]
    ```
    """
    node = self.context.cluster.node(node)

    @contextmanager
    def setup(users=0, roles=0):
        try:
            with Given("I have some users and roles"):
                for i in range(users):
                    node.query(f"CREATE USER OR REPLACE user{i}")
                for j in range(roles):
                    node.query(f"CREATE ROLE OR REPLACE role{j}")
            yield
        finally:
            with Finally("I drop the users and roles"):
                for i in range(users):
                    node.query(f"DROP USER IF EXISTS user{i}")
                for j in range(roles):
                    node.query(f"DROP ROLE IF EXISTS role{j}")

    with Scenario("I grant a role to a user",
                  requirements=[RQ_SRS_006_RBAC_Grant_Role("1.0")]):
        with setup(1, 1):
            with When("I grant a role"):
                node.query("GRANT role0 TO user0")

    with Scenario(
            "I grant a nonexistent role to user",
            requirements=[RQ_SRS_006_RBAC_Grant_Role("1.0")],
    ):
        with setup(1, 0):
            with When("I grant nonexistent role to a user"):
                exitcode, message = errors.role_not_found_in_disk(name="role0")
                node.query("GRANT role0 TO user0",
                           exitcode=exitcode,
                           message=message)

    # with nonexistent object name, GRANT assumes type role (treats user0 as role)
    with Scenario(
            "I grant a role to a nonexistent user",
            requirements=[RQ_SRS_006_RBAC_Grant_Role("1.0")],
    ):
        with setup(0, 1):
            with When("I grant role to a nonexistent user"):
                exitcode, message = errors.role_not_found_in_disk(name="user0")
                node.query("GRANT role0 TO user0",
                           exitcode=exitcode,
                           message=message)

    with Scenario(
            "I grant a nonexistent role to a nonexistent user",
            requirements=[RQ_SRS_006_RBAC_Grant_Role("1.0")],
    ):
        with setup(0, 0):
            with When("I grant nonexistent role to a nonexistent user"):
                exitcode, message = (errors.role_not_found_in_disk(
                    name="user0") if check_clickhouse_version(">=21.09")(self)
                                     else errors.role_not_found_in_disk(
                                         name="role0"))
                node.query("GRANT role0 TO user0",
                           exitcode=exitcode,
                           message=message)

    with Scenario(
            "I grant a role to multiple users",
            requirements=[RQ_SRS_006_RBAC_Grant_Role("1.0")],
    ):
        with setup(2, 1):
            with When("I grant role to a multiple users"):
                node.query("GRANT role0 TO user0, user1")

    with Scenario(
            "I grant multiple roles to multiple users",
            requirements=[RQ_SRS_006_RBAC_Grant_Role("1.0")],
    ):
        with setup(2, 2):
            with When("I grant multiple roles to multiple users"):
                node.query("GRANT role0, role1 TO user0, user1")

    with Scenario(
            "I grant role to current user",
            requirements=[RQ_SRS_006_RBAC_Grant_Role_CurrentUser("1.0")],
    ):
        with setup(1, 1):
            with Given("I have a user with access management privilege"):
                node.query("GRANT ACCESS MANAGEMENT ON *.* TO user0")
            with When("I grant role to current user"):
                node.query("GRANT role0 TO CURRENT_USER",
                           settings=[("user", "user0")])

    with Scenario(
            "I grant role to default user, throws exception",
            requirements=[RQ_SRS_006_RBAC_Grant_Role_CurrentUser("1.0")],
    ):
        with setup(1, 1):
            with When("I grant role to default user"):
                exitcode, message = errors.cannot_update_default()
                node.query("GRANT role0 TO CURRENT_USER",
                           exitcode=exitcode,
                           message=message)

    with Scenario(
            "I grant role to user with admin option",
            requirements=[RQ_SRS_006_RBAC_Grant_Role_AdminOption("1.0")],
    ):
        with setup(1, 1):
            with When("I grant role to a user with admin option"):
                node.query("GRANT role0 TO user0 WITH ADMIN OPTION")

    with Scenario(
            "I grant role to user on cluster",
            requirements=[RQ_SRS_006_RBAC_Grant_Role_OnCluster("1.0")],
    ):
        try:
            with Given("I have a user and a role on a cluster"):
                node.query(
                    "CREATE USER OR REPLACE user0 ON CLUSTER sharded_cluster")
                node.query(
                    "CREATE ROLE OR REPLACE role0 ON CLUSTER sharded_cluster")
            with When("I grant the role to the user"):
                node.query("GRANT ON CLUSTER sharded_cluster role0 TO user0")
        finally:
            with Finally("I drop the user and role"):
                node.query(
                    "DROP USER IF EXISTS user0 ON CLUSTER sharded_cluster")
                node.query(
                    "DROP ROLE IF EXISTS role0 ON CLUSTER sharded_cluster")

    with Scenario(
            "I grant role to user on fake cluster, throws exception",
            requirements=[RQ_SRS_006_RBAC_Grant_Role_OnCluster("1.0")],
    ):
        with setup(1, 1):
            with When("I grant the role to the user"):
                exitcode, message = errors.cluster_not_found("fake_cluster")
                node.query(
                    "GRANT ON CLUSTER fake_cluster role0 TO user0",
                    exitcode=exitcode,
                    message=message,
                )
Ejemplo n.º 15
0
def feature(self, node="clickhouse1"):
    """Check drop user query syntax.

    ```sql
    DROP USER [IF EXISTS] name [,...] [ON CLUSTER cluster_name]
    ```
    """
    node = self.context.cluster.node(node)

    @contextmanager
    def setup(user):
        try:
            with Given("I have a user"):
                node.query(f"CREATE USER {user}")
            yield
        finally:
            with Finally("I drop the user"):
                node.query(f"DROP USER IF EXISTS {user}")

    def cleanup_user(user):
        with Given(f"I ensure that user {user} does not exist"):
            node.query(f"DROP USER IF EXISTS {user}")

    with Scenario("I drop user with no options",
                  requirements=[RQ_SRS_006_RBAC_User_Drop("1.0")]):
        with setup("user0"):
            with When("I drop user"):
                node.query("DROP USER user0")

    with Scenario(
            "I drop user, does not exist, throws exception",
            requirements=[RQ_SRS_006_RBAC_User_Drop("1.0")],
    ):
        user = "******"
        cleanup_user(user)
        with When(f"I drop user {user}"):
            exitcode, message = errors.user_not_found_in_disk(name=user)
            node.query(f"DROP USER {user}", exitcode=exitcode, message=message)
        del user

    with Scenario("I drop multiple users",
                  requirements=[RQ_SRS_006_RBAC_User_Drop("1.0")]):
        with setup("user1"), setup("user2"):
            with When("I drop multiple users"):
                node.query("DROP USER user1, user2")

    with Scenario(
            "I drop user if exists, user does exist",
            requirements=[RQ_SRS_006_RBAC_User_Drop_IfExists("1.0")],
    ):
        with setup("user3"):
            with When("I drop user that exists"):
                node.query("DROP USER IF EXISTS user3")

    with Scenario(
            "I drop user if exists, user does not exist",
            requirements=[RQ_SRS_006_RBAC_User_Drop_IfExists("1.0")],
    ):
        cleanup_user("user3")
        with When("I drop nonexistant user"):
            node.query("DROP USER IF EXISTS user3")

    with Scenario(
            "I drop default user, throws error",
            requirements=[RQ_SRS_006_RBAC_User_Drop("1.0")],
    ):
        with When("I drop user"):
            exitcode, message = errors.cannot_remove_user_default()
            node.query("DROP USER default", exitcode=exitcode, message=message)

    with Scenario(
            "I drop multiple users where one does not exist",
            requirements=[RQ_SRS_006_RBAC_User_Drop_IfExists("1.0")],
    ):
        with setup("user3"):
            with When("I drop multiple users where one does not exist"):
                node.query("DROP USER IF EXISTS user3, user4")

    with Scenario(
            "I drop multiple users where both do not exist",
            requirements=[RQ_SRS_006_RBAC_User_Drop_IfExists("1.0")],
    ):
        with When("I drop the nonexistant users"):
            node.query("DROP USER IF EXISTS user5, user6")

    with Scenario(
            "I drop user from specific cluster",
            requirements=[RQ_SRS_006_RBAC_User_Drop_OnCluster("1.0")],
    ):
        try:
            with Given("I have a user on cluster"):
                node.query("CREATE USER user4 ON CLUSTER sharded_cluster")
            with When("I drop a user from the cluster"):
                node.query("DROP USER user4 ON CLUSTER sharded_cluster")
        finally:
            with Finally("I make sure the user is dropped"):
                node.query(
                    "DROP USER IF EXISTS user4 ON CLUSTER sharded_cluster")

    with Scenario(
            "I drop user from fake cluster",
            requirements=[RQ_SRS_006_RBAC_User_Drop_OnCluster("1.0")],
    ):
        with When("I drop a user from the fake cluster"):
            exitcode, message = errors.cluster_not_found("fake_cluster")
            node.query(
                "DROP USER user5 ON CLUSTER fake_cluster",
                exitcode=exitcode,
                message=message,
            )
Ejemplo n.º 16
0
def feature(self, node="clickhouse1"):
    """Check alter user query syntax.

    ```sql
    ALTER USER [IF EXISTS] name [ON CLUSTER cluster_name]
    [RENAME TO new_name]
    [IDENTIFIED [WITH {PLAINTEXT_PASSWORD|SHA256_PASSWORD|DOUBLE_SHA1_PASSWORD}] BY {'password'|'hash'}]
    [[ADD|DROP] HOST {LOCAL | NAME 'name' | REGEXP 'name_regexp' | IP 'address' | LIKE 'pattern'} [,...] | ANY | NONE]
    [DEFAULT ROLE role [,...] | ALL | ALL EXCEPT role [,...] ]
    [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...]
    ```
    """
    node = self.context.cluster.node(node)

    @contextmanager
    def setup(user):
        try:
            with Given("I have a user"):
                node.query(f"CREATE USER OR REPLACE {user}")
            yield
        finally:
            with Finally("I drop the user"):
                node.query(f"DROP USER IF EXISTS {user}")

    with Scenario("I alter user, base command",
                  requirements=[RQ_SRS_006_RBAC_User_Alter("1.0")]):
        with setup("user0"):
            with When("I alter user"):
                node.query("ALTER USER user0")

    with Scenario(
            "I alter user that does not exist without if exists, throws exception",
            requirements=[RQ_SRS_006_RBAC_User_Alter("1.0")]):
        with When("I run alter user command, expecting error 192"):
            exitcode, message = errors.user_not_found_in_disk(name="user0")
            node.query(f"ALTER USER user0", exitcode=exitcode, message=message)

    with Scenario("I alter user with if exists",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_IfExists("1.0")]):
        with setup("user0"):
            with When(f"I alter user with if exists"):
                node.query(f"ALTER USER IF EXISTS user0")

    with Scenario("I alter user that does not exist with if exists",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_IfExists("1.0")]):
        user = "******"
        with Given("I don't have a user"):
            node.query(f"DROP USER IF EXISTS {user}")
        with When(f"I alter user {user} with if exists"):
            node.query(f"ALTER USER IF EXISTS {user}")
        del user

    with Scenario("I alter user on a cluster",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_Cluster("1.0")]):
        with Given("I have a user on a cluster"):
            node.query(
                "CREATE USER OR REPLACE user0 ON CLUSTER sharded_cluster")
        with When("I alter user on a cluster"):
            node.query("ALTER USER user0 ON CLUSTER sharded_cluster")
        with Finally("I drop user from cluster"):
            node.query("DROP USER IF EXISTS user0 ON CLUSTER sharded_cluster")

    with Scenario("I alter user on a fake cluster, throws exception",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_Cluster("1.0")]):
        with When("I alter user on a fake cluster"):
            exitcode, message = errors.cluster_not_found("fake_cluster")
            node.query("ALTER USER user0 ON CLUSTER fake_cluster",
                       exitcode=exitcode,
                       message=message)

    with Scenario("I alter user to rename, target available",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_Rename("1.0")]):
        with setup("user15"):
            with When("I alter user name"):
                node.query("ALTER USER user15 RENAME TO user15")

    with Scenario("I alter user to rename, target unavailable",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_Rename("1.0")]):
        with setup("user15"):
            new_user = "******"
            try:
                with Given(f"Ensure target name {new_user} is NOT available"):
                    node.query(f"CREATE USER IF NOT EXISTS {new_user}")
                with When(f"I try to rename to {new_user}"):
                    exitcode, message = errors.cannot_rename_user(
                        name="user15", name_new=new_user)
                    node.query(f"ALTER USER user15 RENAME TO {new_user}",
                               exitcode=exitcode,
                               message=message)
            finally:
                with Finally(f"I cleanup target name {new_user}"):
                    node.query(f"DROP USER IF EXISTS {new_user}")
            del new_user

    with Scenario("I alter user password plaintext password",
                  requirements=[
                      RQ_SRS_006_RBAC_User_Alter_Password_PlainText("1.0")
                  ]):
        with setup("user1"):
            with When("I alter user with plaintext password"):
                node.query(
                    "ALTER USER user1 IDENTIFIED WITH PLAINTEXT_PASSWORD BY 'mypassword'",
                    step=When)

    with Scenario("I alter user password to sha256",
                  requirements=[
                      RQ_SRS_006_RBAC_User_Alter_Password_Sha256Password("1.0")
                  ]):
        with setup("user2"):
            with When("I alter user with sha256_password"):
                password = hashlib.sha256(
                    "mypassword".encode("utf-8")).hexdigest()
                node.query(
                    f"ALTER USER user2 IDENTIFIED WITH SHA256_PASSWORD BY '{password}'",
                    step=When)

    with Scenario(
            "I alter user password to double_sha1_password",
            requirements=[
                RQ_SRS_006_RBAC_User_Alter_Password_DoubleSha1Password("1.0")
            ]):
        with setup("user3"):
            with When("I alter user with double_sha1_password"):

                def hash(password):
                    return hashlib.sha1(password.encode("utf-8")).hexdigest()

                password = hash(hash("mypassword"))
                node.query(
                    f"ALTER USER user3 IDENTIFIED WITH DOUBLE_SHA1_PASSWORD BY '{password}'",
                    step=When)

    with Scenario("I alter user host local",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_Host_Local("1.0")]):
        with setup("user4"):
            with When("I alter user with host local"):
                node.query("ALTER USER user4 HOST LOCAL")

    with Scenario("I alter user host name",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_Host_Name("1.0")]):
        with setup("user5"):
            with When("I alter user with host name"):
                node.query(
                    "ALTER USER user5 HOST NAME 'localhost', NAME 'clickhouse.com'"
                )

    with Scenario("I alter user host regexp",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_Host_Regexp("1.0")
                                ]):
        with setup("user6"):
            with When("I alter user with host regexp"):
                node.query(
                    "ALTER USER user6 HOST REGEXP 'lo..*host', 'lo*host'")

    with Scenario("I alter user host ip",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_Host_IP("1.0")]):
        with setup("user7"):
            with When("I alter user with host ip"):
                node.query(
                    "ALTER USER user7 HOST IP '127.0.0.1', IP '127.0.0.2'")

    with Scenario("I alter user host like",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_Host_Like("1.0")]):
        with setup("user8"):
            with When("I alter user with host like"):
                node.query("ALTER USER user8 HOST LIKE '%.clickhouse.com'")

    with Scenario("I alter user host any",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_Host_Any("1.0")]):
        with setup("user9"):
            with When("I alter user with host any"):
                node.query("ALTER USER user9 HOST ANY")

    with Scenario("I alter user host many hosts",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_Host_Like("1.0")]):
        with setup("user11"):
            with When("I alter user with multiple hosts"):
                node.query("ALTER USER user11 HOST LIKE '%.clickhouse.com', \
                    IP '127.0.0.2', NAME 'localhost', REGEXP 'lo*host'")

    with Scenario("I alter user default role set to none",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_Host_None("1.0")]):
        with setup("user12"):
            with When("I alter user with default role none"):
                node.query("ALTER USER user12 DEFAULT ROLE NONE")

    with Scenario(
            "I alter user default role set to all",
            requirements=[RQ_SRS_006_RBAC_User_Alter_DefaultRole_All("1.0")]):
        with setup("user13"):
            with When("I alter user with all roles set to default"):
                node.query("ALTER USER user13 DEFAULT ROLE ALL")

    @contextmanager
    def setup_role(role):
        try:
            with Given(f"I have a role {role}"):
                node.query(f"CREATE ROLE OR REPLACE {role}")
            yield
        finally:
            with Finally(f"I drop the role {role}", flags=TE):
                node.query(f"DROP ROLE IF EXISTS {role}")

    with Scenario("I alter user default role",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_DefaultRole("1.0")
                                ]):
        with setup("user14"), setup_role("role2"):
            with Given("I have a user with a role"):
                node.query("GRANT role2 TO user14")
            with When("I alter user default role"):
                node.query("ALTER USER user14 DEFAULT ROLE role2")

    with Scenario("I alter user default role, setting default role",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_DefaultRole("1.0")
                                ]):
        with setup("user14a"), setup_role("default"):
            with Given("I grant default role to the user"):
                node.query("GRANT default TO user14a")
            with When("I alter user default role"):
                node.query("ALTER USER user14a DEFAULT ROLE default")

    with Scenario(
            "I alter user default role, role doesn't exist, throws exception",
            requirements=[RQ_SRS_006_RBAC_User_Alter_DefaultRole("1.0")]):
        with setup("user12"):
            role = "role0"
            with Given(f"I ensure that role {role} does not exist"):
                node.query(f"DROP ROLE IF EXISTS {role}")
            with When(f"I alter user with default role {role}"):
                exitcode, message = errors.role_not_found_in_disk(role)
                node.query(f"ALTER USER user12 DEFAULT ROLE {role}",
                           exitcode=exitcode,
                           message=message)
            del role

    with Scenario(
            "I alter user default role, all except role doesn't exist, throws exception",
            requirements=[RQ_SRS_006_RBAC_User_Alter_DefaultRole("1.0")]):
        with setup("user12"):
            role = "role0"
            with Given(f"I ensure that role {role} does not exist"):
                node.query(f"DROP ROLE IF EXISTS {role}")
            with When(f"I alter user with default role {role}"):
                exitcode, message = errors.role_not_found_in_disk(role)
                node.query(f"ALTER USER user12 DEFAULT ROLE ALL EXCEPT {role}",
                           exitcode=exitcode,
                           message=message)
            del role

    with Scenario("I alter user default role multiple",
                  requirements=[RQ_SRS_006_RBAC_User_Alter_DefaultRole("1.0")
                                ]):
        with setup("user15"), setup_role("second"), setup_role("third"):
            with Given("I have a user with multiple roles"):
                node.query("GRANT second,third TO user15")
            with When("I alter user default role to second, third"):
                node.query("ALTER USER user15 DEFAULT ROLE second, third")

    with Scenario("I alter user default role set to all except",
                  requirements=[
                      RQ_SRS_006_RBAC_User_Alter_DefaultRole_AllExcept("1.0")
                  ]):
        with setup("user16"), setup_role("second"):
            with Given("I have a user with a role"):
                node.query("GRANT second TO user16")
            with When("I alter user default role"):
                node.query("ALTER USER user16 DEFAULT ROLE ALL EXCEPT second")

    with Scenario("I alter user default role multiple all except",
                  requirements=[
                      RQ_SRS_006_RBAC_User_Alter_DefaultRole_AllExcept("1.0")
                  ]):
        with setup("user17"), setup_role("second"), setup_role("third"):
            with Given("I have a user with multiple roles"):
                node.query("GRANT second,third TO user17")
            with When("I alter user default role to all except second"):
                node.query("ALTER USER user17 DEFAULT ROLE ALL EXCEPT second")

    with Scenario("I alter user settings profile", requirements=[
            RQ_SRS_006_RBAC_User_Alter_Settings("1.0"),  \
            RQ_SRS_006_RBAC_User_Alter_Settings_Profile("1.0")]):
        with setup("user18"):
            try:
                with Given("I have a profile"):
                    node.query(f"CREATE SETTINGS PROFILE profile10")
                with When(
                        "I alter user with settings and set profile to profile1"
                ):
                    node.query(
                        "ALTER USER user18 SETTINGS PROFILE profile10, max_memory_usage = 100 MIN 0 MAX 1000 READONLY"
                    )
            finally:
                with Finally("I drop the profile"):
                    node.query(f"DROP SETTINGS PROFILE profile10")

    with Scenario(
            "I alter user settings profile, fake profile, throws exception",
            requirements=[
                RQ_SRS_006_RBAC_User_Alter_Settings("1.0"),
                RQ_SRS_006_RBAC_User_Alter_Settings_Profile("1.0")
            ]):
        with setup("user18a"):
            profile = "profile0"
            with Given(f"I ensure that profile {profile} does not exist"):
                node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}")
            with When(
                    f"I alter user with Settings and set profile to fake profile {profile}"
            ):
                exitcode, message = errors.settings_profile_not_found_in_disk(
                    profile)
                node.query("ALTER USER user18a SETTINGS PROFILE profile0",
                           exitcode=exitcode,
                           message=message)
            del profile

    with Scenario(
            "I alter user settings with a fake setting, throws exception",
            requirements=[RQ_SRS_006_RBAC_User_Alter_Settings("1.0")]):
        with setup("user18b"):
            with When(
                    "I alter settings profile using settings and nonexistent value"
            ):
                exitcode, message = errors.unknown_setting("fake_setting")
                node.query(
                    "ALTER USER user18b SETTINGS fake_setting = 100000001",
                    exitcode=exitcode,
                    message=message)

    with Scenario("I alter user settings without profile (no equals)",
                  requirements=[
                      RQ_SRS_006_RBAC_User_Alter_Settings("1.0"),
                      RQ_SRS_006_RBAC_User_Alter_Settings_Min("1.0"),
                      RQ_SRS_006_RBAC_User_Alter_Settings_Max("1.0")
                  ]):
        with setup("user19"):
            with When(
                    "I alter user with settings without profile using no equals"
            ):
                node.query(
                    "ALTER USER user19 SETTINGS max_memory_usage=10000000 MIN 100000 MAX 1000000000 READONLY"
                )

    #equals sign (=) syntax verify
    with Scenario("I alter user settings without profile (yes equals)",
                  requirements=[
                      RQ_SRS_006_RBAC_User_Alter_Settings("1.0"),
                      RQ_SRS_006_RBAC_User_Alter_Settings_Min("1.0"),
                      RQ_SRS_006_RBAC_User_Alter_Settings_Max("1.0")
                  ]):
        with setup("user20"):
            with When(
                    "I alter user with settings without profile using equals"):
                node.query(
                    "ALTER USER user20 SETTINGS max_memory_usage=10000000 MIN=100000 MAX=1000000000 READONLY"
                )

    #Add requirement to host: add/drop
    with Scenario(
            "I alter user to add host",
            requirements=[RQ_SRS_006_RBAC_User_Alter_Host_AddDrop("1.0")]):
        with setup("user21"):
            with When("I alter user by adding local host"):
                node.query("ALTER USER user21 ADD HOST LOCAL")
            with And("I alter user by adding no host"):
                node.query("ALTER USER user21 ADD HOST NONE")
            with And("I alter user by adding host like"):
                node.query("ALTER USER user21 ADD HOST LIKE 'local%'")
            with And("I alter user by adding host ip"):
                node.query("ALTER USER user21 ADD HOST IP '127.0.0.1'")
            with And("I alter user by adding host name"):
                node.query("ALTER USER user21 ADD HOST NAME 'localhost'")

    with Scenario(
            "I alter user to remove host",
            requirements=[RQ_SRS_006_RBAC_User_Alter_Host_AddDrop("1.0")]):
        with setup("user22"):
            with When("I alter user by removing local host"):
                node.query("ALTER USER user22 DROP HOST LOCAL")
            with And("I alter user by removing no host"):
                node.query("ALTER USER user22 DROP HOST NONE")
            with And("I alter user by removing like host"):
                node.query("ALTER USER user22 DROP HOST LIKE 'local%'")
            with And("I alter user by removing host ip"):
                node.query("ALTER USER user22 DROP HOST IP '127.0.0.1'")
            with And("I alter user by removing host name"):
                node.query("ALTER USER user22 DROP HOST NAME 'localhost'")
Ejemplo n.º 17
0
def feature(self, node="clickhouse1"):
    """Check alter role query syntax.

    ```sql
    ALTER ROLE [IF EXISTS] name [ON CLUSTER cluster_name]
    [RENAME TO new_name]
    [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value] [READONLY|WRITABLE] | PROFILE 'profile_name'] [,...]
    ```
    """
    node = self.context.cluster.node(node)

    @contextmanager
    def setup(role, profile=None):
        try:
            with Given("I have a role"):
                node.query(f"CREATE ROLE OR REPLACE {role}")
            if profile != None:  # create profile when name is given
                with Given("And I have a profile"):
                    node.query(f"CREATE SETTINGS PROFILE OR REPLACE {profile}")
            yield
        finally:
            with Finally("I drop the role"):
                node.query(f"DROP ROLE IF EXISTS {role}")
            if profile != "":
                with Finally("I drop the profile"):
                    node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}")

    def cleanup_role(role):
        with Given(f"I ensure that role {role} does not exist"):
            node.query(f"DROP ROLE IF EXISTS {role}")

    with Scenario("I alter role with no options",
                  requirements=[RQ_SRS_006_RBAC_Role_Alter("1.0")]):
        with setup("role0"):
            with When("I alter role"):
                node.query("ALTER ROLE role0")

    with Scenario(
            "I alter role that does not exist, throws exception",
            requirements=[RQ_SRS_006_RBAC_Role_Alter("1.0")],
    ):
        role = "role0"
        cleanup_role(role)
        with When(f"I alter role {role} that does not exist"):
            exitcode, message = errors.role_not_found_in_disk(name=role)
            node.query(f"ALTER ROLE {role}",
                       exitcode=exitcode,
                       message=message)
        del role

    with Scenario(
            "I alter role if exists, role does exist",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_IfExists("1.0")],
    ):
        with setup("role1"):
            with When("I alter role with if exists"):
                node.query("ALTER ROLE IF EXISTS role1")

    with Scenario(
            "I alter role if exists, role does not exist",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_IfExists("1.0")],
    ):
        role = "role0"
        cleanup_role(role)
        with When(f"I alter role {role} that does not exist"):
            node.query(f"ALTER ROLE IF EXISTS {role}")
        del role

    with Scenario(
            "I alter role on cluster",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_Cluster("1.0")],
    ):
        try:
            with Given("I have a role on a cluster"):
                node.query("CREATE ROLE role1 ON CLUSTER sharded_cluster")
            with When("I run alter role on a cluster"):
                node.query("ALTER ROLE role1 ON CLUSTER sharded_cluster")
            with And("I rename role on a cluster"):
                node.query(
                    "ALTER ROLE role1 ON CLUSTER sharded_cluster RENAME TO role2"
                )
            with And("I alter role with settings on a cluster"):
                node.query(
                    "ALTER ROLE role2 ON CLUSTER sharded_cluster SETTINGS max_memory_usage=10000000 READONLY"
                )
        finally:
            with Finally("I drop the role"):
                node.query(
                    "DROP ROLE IF EXISTS role1,role2 ON CLUSTER sharded_cluster"
                )

    with Scenario(
            "I alter role on nonexistent cluster, throws exception",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_Cluster("1.0")],
    ):
        with When("I run alter role on a cluster"):
            exitcode, message = errors.cluster_not_found("fake_cluster")
            node.query(
                "ALTER ROLE role1 ON CLUSTER fake_cluster",
                exitcode=exitcode,
                message=message,
            )

    with Scenario(
            "I alter role to rename, new name is available",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_Rename("1.0")],
    ):
        with setup("role2"):
            new_role = "role3"
            try:
                with Given(f"Ensure target name {new_role} is available"):
                    node.query(f"DROP ROLE IF EXISTS {new_role}")
                with When(f"I try to rename to {new_role}"):
                    node.query(f"ALTER ROLE role2 RENAME TO {new_role}")
            finally:
                with Finally(f"I cleanup new name {new_role}"):
                    node.query(f"DROP ROLE IF EXISTS {new_role}")
            del new_role

    with Scenario(
            "I alter role to rename, new name is not available, throws exception",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_Rename("1.0")],
    ):
        with setup("role2a"):
            new_role = "role3a"
            try:
                with Given(f"Ensure target name {new_role} is NOT available"):
                    node.query(f"CREATE ROLE IF NOT EXISTS {new_role}")
                with When(f"I try to rename to {new_role}"):
                    exitcode, message = errors.cannot_rename_role(
                        name="role2a", name_new=new_role)
                    node.query(
                        f"ALTER ROLE role2a RENAME TO {new_role}",
                        exitcode=exitcode,
                        message=message,
                    )
            finally:
                with Finally(f"I cleanup target name {new_role}"):
                    node.query(f"DROP ROLE IF EXISTS {new_role}")
            del new_role

    with Scenario(
            "I alter role settings profile",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")],
    ):
        with setup("role4"):
            with When("I alter role with settings profile"):
                node.query(
                    "ALTER ROLE role4 SETTINGS PROFILE default, max_memory_usage=10000000 READONLY"
                )

    with Scenario(
            "I alter role settings profile, profile does not exist, throws exception",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")],
    ):
        with setup("role4a"):
            with Given("I ensure profile profile0 does not exist"):
                node.query("DROP SETTINGS PROFILE IF EXISTS profile0")
            with When(
                    "I alter role with settings profile that does not exist"):
                exitcode, message = errors.settings_profile_not_found_in_disk(
                    "profile0")
                node.query(
                    "ALTER ROLE role4a SETTINGS PROFILE profile0",
                    exitcode=exitcode,
                    message=message,
                )

    with Scenario(
            "I alter role settings profile multiple",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")],
    ):
        with setup("role4b", profile="profile0"):
            with When("I alter role with multiple profiles"):
                node.query(
                    "ALTER ROLE role4b SETTINGS PROFILE default, PROFILE profile0, \
                    max_memory_usage=10000000 READONLY")

    with Scenario(
            "I alter role settings without profile",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")],
    ):
        with setup("role5"):
            with When("I alter role with settings and no profile"):
                node.query(
                    "ALTER ROLE role5 SETTINGS max_memory_usage=10000000 READONLY"
                )

    with Scenario(
            "I alter role settings, variable does not exist, throws exception",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")],
    ):
        with setup("role5a"):
            with When("I alter role using settings and nonexistent value"):
                exitcode, message = errors.unknown_setting("fake_setting")
                node.query(
                    "ALTER ROLE role5a SETTINGS fake_setting = 100000001",
                    exitcode=exitcode,
                    message=message,
                )

    with Scenario(
            "I alter role settings without profile multiple",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")],
    ):
        with setup("role6"):
            with When("I alter role with multiple settings and no profile"):
                node.query(
                    "ALTER ROLE role6 SETTINGS max_memory_usage=10000000 READONLY, \
                    max_rows_to_read MIN 20 MAX 25")

    with Scenario(
            "I alter role settings with multiple profiles multiple variables",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")],
    ):
        with setup("role7", profile="profile1"):
            with When("I alter role with multiple settings and profiles"):
                node.query(
                    "ALTER ROLE role7 SETTINGS PROFILE default, PROFILE profile1, \
                    max_memory_usage=10000000 READONLY, max_rows_to_read MIN 20 MAX 25"
                )

    with Scenario(
            "I alter role settings readonly",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")],
    ):
        with setup("role8"):
            with When("I alter role with readonly"):
                node.query(
                    "ALTER ROLE role8 SETTINGS max_memory_usage READONLY")

    with Scenario(
            "I alter role settings writable",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")],
    ):
        with setup("role9"):
            with When("I alter role with writable"):
                node.query(
                    "ALTER ROLE role9 SETTINGS max_memory_usage WRITABLE")

    with Scenario(
            "I alter role settings min, with and without = sign",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")],
    ):
        with setup("role10"):
            with When("I set min, no equals"):
                node.query(
                    "ALTER ROLE role10 SETTINGS max_memory_usage MIN 200")
            with When("I set min, yes equals"):
                node.query(
                    "ALTER ROLE role10 SETTINGS max_memory_usage MIN = 200")

    with Scenario(
            "I alter role settings max, with and without = sign",
            requirements=[RQ_SRS_006_RBAC_Role_Alter_Settings("1.0")],
    ):
        with setup("role11"):
            with When("I set max, no equals"):
                node.query(
                    "ALTER ROLE role11 SETTINGS max_memory_usage MAX 2000")
            with When("I set max, yes equals"):
                node.query(
                    "ALTER ROLE role11 SETTINGS max_memory_usage MAX = 200")
Ejemplo n.º 18
0
def feature(self, node="clickhouse1"):
    """Check grant privilege syntax.

    ```sql
    GRANT [ON CLUSTER cluster_name]
    privilege {SELECT | SELECT(columns) | INSERT | ALTER | CREATE | DROP | TRUNCATE | OPTIMIZE | SHOW | KILL QUERY | ACCESS MANAGEMENT | SYSTEM | INTROSPECTION | SOURCES | dictGet | NONE |ALL     [PRIVILEGES]} [, ...]
    ON {*.* | database.* | database.table | * | table}
    TO {user | role | CURRENT_USER} [,...]
    [WITH GRANT OPTION]
    ```
    """
    node = self.context.cluster.node(node)

    Scenario(run=grant_privileges)

    # with nonexistant object name, GRANT assumes type role
    with Scenario("I grant privilege to role that does not exist",
                  flags=TE,
                  requirements=[RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")]):
        with Given("I ensure that role does not exist"):
            node.query("DROP ROLE IF EXISTS role0")
        with When("I grant privilege ON CLUSTER"):
            exitcode, message = errors.role_not_found_in_disk(name="role0")
            node.query("GRANT NONE TO role0",
                       exitcode=exitcode,
                       message=message)

    with Scenario("I grant privilege ON CLUSTER",
                  flags=TE,
                  requirements=[
                      RQ_SRS_006_RBAC_Grant_Privilege_OnCluster("1.0"),
                      RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")
                  ]):
        with setup(node):
            with When("I grant privilege ON CLUSTER"):
                node.query("GRANT ON CLUSTER sharded_cluster NONE TO user0")

    with Scenario(
            "I grant privilege on fake cluster, throws exception",
            flags=TE,
            requirements=[RQ_SRS_006_RBAC_Grant_Privilege_OnCluster("1.0")]):
        with setup(node):
            with When("I grant privilege ON CLUSTER"):
                exitcode, message = errors.cluster_not_found("fake_cluster")
                node.query("GRANT ON CLUSTER fake_cluster NONE TO user0",
                           exitcode=exitcode,
                           message=message)

    with Scenario("I grant privilege to multiple users and roles",
                  flags=TE,
                  requirements=[
                      RQ_SRS_006_RBAC_Grant_Privilege_To("1.0"),
                      RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")
                  ]):
        with setup(node):
            with When("I grant privilege to several users"):
                node.query("GRANT NONE TO user0, user1, role1")

    with Scenario("I grant privilege to current user",
                  flags=TE,
                  requirements=[
                      RQ_SRS_006_RBAC_Grant_Privilege_ToCurrentUser("1.0"),
                      RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")
                  ]):
        with setup(node):
            with When("I grant privilege to current user"):
                node.query("GRANT NONE TO CURRENT_USER",
                           settings=[("user", "user0")])

    with Scenario("I grant privilege NONE to default user, throws exception",
                  flags=TE,
                  requirements=[
                      RQ_SRS_006_RBAC_Grant_Privilege_ToCurrentUser("1.0"),
                      RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")
                  ]):
        with setup(node):
            with When("I grant privilege to current user"):
                exitcode, message = errors.cannot_update_default()
                node.query("GRANT NONE TO CURRENT_USER",
                           exitcode=exitcode,
                           message=message)

    with Scenario("I grant privilege with grant option",
                  flags=TE,
                  requirements=[
                      RQ_SRS_006_RBAC_Grant_Privilege_GrantOption("1.0"),
                      RQ_SRS_006_RBAC_Grant_Privilege_None("1.0")
                  ]):
        with setup(node):
            with When("I grant privilege with grant option"):
                node.query("GRANT NONE ON *.* TO user0 WITH GRANT OPTION")
Ejemplo n.º 19
0
def feature(self, node="clickhouse1"):
    """Check create settings profile query syntax.

    ```sql
    CREATE [SETTINGS] PROFILE [IF NOT EXISTS | OR REPLACE] name [ON CLUSTER cluster_name]
    [SETTINGS variable [= value] [MIN [=] min_value] [MAX [=] max_value]
        [READONLY] | [INHERIT|PROFILE 'profile_name']] [,...]
    [TO {role [,...] | ALL | ALL EXCEPT role [,...]}]
    ```
    """
    node = self.context.cluster.node(node)

    @contextmanager
    def cleanup(profile):
        try:
            with Given(f"I ensure the profile {profile} does not exist"):
                node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}")
            yield
        finally:
            with Finally("I drop the profile"):
                node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}")

    def create_profile(profile):
        with Given(f"I ensure I do have profile {profile}"):
            node.query(f"CREATE SETTINGS PROFILE OR REPLACE {profile}")

    try:
        with Given("I have a user and a role"):
            node.query(f"CREATE USER user0")
            node.query(f"CREATE ROLE role0")

        with Scenario(
                "I create settings profile with no options",
                requirements=[RQ_SRS_006_RBAC_SettingsProfile_Create("1.0")]):
            with cleanup("profile0"):
                with When("I create settings profile"):
                    node.query("CREATE SETTINGS PROFILE profile0")

        with Scenario(
                "I create settings profile that already exists, throws exception",
                requirements=[RQ_SRS_006_RBAC_SettingsProfile_Create("1.0")]):
            profile = "profile0"
            with cleanup(profile):
                create_profile(profile)
                with When(
                        f"I create settings profile {profile} that already exists"
                ):
                    exitcode, message = errors.cannot_insert_settings_profile(
                        name=profile)
                    node.query(f"CREATE SETTINGS PROFILE {profile}",
                               exitcode=exitcode,
                               message=message)
            del profile

        with Scenario(
                "I create settings profile if not exists, profile does not exist",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_IfNotExists("1.0")
                ]):
            with cleanup("profile1"):
                with When("I create settings profile with if not exists"):
                    node.query(
                        "CREATE SETTINGS PROFILE IF NOT EXISTS profile1")

        with Scenario(
                "I create settings profile if not exists, profile does exist",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_IfNotExists("1.0")
                ]):
            profile = "profile1"
            with cleanup(profile):
                create_profile(profile)
                with When(
                        f"I create settings profile {profile} with if not exists"
                ):
                    node.query(
                        f"CREATE SETTINGS PROFILE IF NOT EXISTS {profile}")
            del profile

        with Scenario(
                "I create settings profile or replace, profile does not exist",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Replace("1.0")
                ]):
            with cleanup("profile2"):
                with When("I create settings policy with or replace"):
                    node.query("CREATE SETTINGS PROFILE OR REPLACE profile2")

        with Scenario(
                "I create settings profile or replace, profile does exist",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Replace("1.0")
                ]):
            with cleanup("profile2"):
                create_profile("profile2")
                with When("I create settings policy with or replace"):
                    node.query("CREATE SETTINGS PROFILE OR REPLACE profile2")

        with Scenario(
                "I create settings profile short form",
                requirements=[RQ_SRS_006_RBAC_SettingsProfile_Create("1.0")]):
            with cleanup("profile3"):
                with When("I create settings profile short form"):
                    node.query("CREATE PROFILE profile3")

        with Scenario(
                "I create settings profile with a setting value",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Variables("1.0"),
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Value(
                        "1.0")
                ]):
            with cleanup("profile4"):
                with When("I create settings profile with settings"):
                    node.query(
                        "CREATE SETTINGS PROFILE profile4 SETTINGS max_memory_usage = 100000001"
                    )

        with Scenario(
                "I create settings profile with a setting value, does not exist, throws exception",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Variables("1.0"),
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Value(
                        "1.0")
                ]):
            with When(
                    "I create settings profile using settings and nonexistent value"
            ):
                exitcode, message = errors.unknown_setting("fake_setting")
                node.query(
                    "CREATE SETTINGS PROFILE profile0 SETTINGS fake_setting = 100000001",
                    exitcode=exitcode,
                    message=message)

        with Scenario(
                "I create settings profile with a min setting value",
                requirements=
            [
                RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints(
                    "1.0")
            ]):
            with cleanup("profile5"), cleanup("profile6"):
                with When(
                        "I create settings profile with min setting with and without equals"
                ):
                    node.query(
                        "CREATE SETTINGS PROFILE profile5 SETTINGS max_memory_usage MIN 100000001"
                    )
                    node.query(
                        "CREATE SETTINGS PROFILE profile6 SETTINGS max_memory_usage MIN = 100000001"
                    )

        with Scenario(
                "I create settings profile with a max setting value",
                requirements=
            [
                RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints(
                    "1.0")
            ]):
            with cleanup("profile7"), cleanup("profile8"):
                with When(
                        "I create settings profile with max setting with and without equals"
                ):
                    node.query(
                        "CREATE SETTINGS PROFILE profile7 SETTINGS max_memory_usage MAX 100000001"
                    )
                    node.query(
                        "CREATE SETTINGS PROFILE profile8 SETTINGS max_memory_usage MAX = 100000001"
                    )

        with Scenario(
                "I create settings profile with min and max setting values",
                requirements=
            [
                RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints(
                    "1.0")
            ]):
            with cleanup("profile9"):
                with When(
                        "I create settings profile with min and max setting"):
                    node.query(
                        "CREATE SETTINGS PROFILE profile9 SETTINGS max_memory_usage MIN 100000001 MAX 200000001"
                    )

        with Scenario(
                "I create settings profile with a readonly setting",
                requirements=
            [
                RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints(
                    "1.0")
            ]):
            with cleanup("profile10"):
                with When("I create settings profile with readonly"):
                    node.query(
                        "CREATE SETTINGS PROFILE profile10 SETTINGS max_memory_usage READONLY"
                    )

        with Scenario(
                "I create settings profile with a writable setting",
                requirements=
            [
                RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints(
                    "1.0")
            ]):
            with cleanup("profile21"):
                with When("I create settings profile with writable"):
                    node.query(
                        "CREATE SETTINGS PROFILE profile21 SETTINGS max_memory_usage WRITABLE"
                    )

        with Scenario("I create settings profile with inherited settings",
                      requirements=[
                          RQ_SRS_006_RBAC_SettingsProfile_Create_Inherit("1.0")
                      ]):
            with cleanup("profile11"):
                with When("I create settings profile with inherit"):
                    node.query(
                        "CREATE SETTINGS PROFILE profile11 SETTINGS INHERIT 'default'"
                    )

        with Scenario(
                "I create settings profile with inherit/from profile, fake profile, throws exception",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Inherit("1.0")
                ]):
            profile = "profile3"
            with Given(f"I ensure that profile {profile} does not exist"):
                node.query(f"DROP SETTINGS PROFILE IF EXISTS {profile}")
            sources = {"INHERIT", "PROFILE"}
            for source in sources:
                with When(
                        f"I create settings profile {source} from nonexistant parent"
                ):
                    exitcode, message = errors.settings_profile_not_found_in_disk(
                        profile)
                    node.query(
                        f"CREATE PROFILE profile0 SETTINGS {source} {profile}",
                        exitcode=exitcode,
                        message=message)
            del profile

        with Scenario(
                "I create settings profile with inherited settings other form",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Inherit("1.0")
                ]):
            with cleanup("profile12"):
                with When("I create settings profile with inherit short form"):
                    node.query(
                        "CREATE PROFILE profile12 SETTINGS PROFILE 'default'")

        with Scenario(
                "I create settings profile with multiple settings",
                requirements=
            [
                RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints(
                    "1.0")
            ]):
            with cleanup("profile13"):
                with When("I create settings profile with multiple settings"):
                    node.query(
                        "CREATE SETTINGS PROFILE profile13"
                        " SETTINGS max_memory_usage = 100000001"
                        " SETTINGS max_memory_usage_for_user = 100000001")

        with Scenario(
                "I create settings profile with multiple settings short form",
                requirements=
            [
                RQ_SRS_006_RBAC_SettingsProfile_Create_Variables_Constraints(
                    "1.0")
            ]):
            with cleanup("profile14"):
                with When(
                        "I create settings profile with multiple settings short form"
                ):
                    node.query("CREATE SETTINGS PROFILE profile14"
                               " SETTINGS max_memory_usage = 100000001,"
                               " max_memory_usage_for_user = 100000001")

        with Scenario(
                "I create settings profile assigned to one role",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment("1.0")
                ]):
            with cleanup("profile15"):
                with When("I create settings profile for a role"):
                    node.query("CREATE SETTINGS PROFILE profile15 TO role0")

        with Scenario(
                "I create settings profile to assign to role that does not exist, throws exception",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment("1.0")
                ]):
            role = "role1"
            with Given(f"I drop {role} if it exists"):
                node.query(f"DROP ROLE IF EXISTS {role}")
            with Then(
                    f"I create a settings profile, assign to role {role}, which does not exist"
            ):
                exitcode, message = errors.role_not_found_in_disk(name=role)
                node.query(f"CREATE SETTINGS PROFILE profile0 TO {role}",
                           exitcode=exitcode,
                           message=message)
            del role

        with Scenario(
                "I create settings profile to assign to all except role that does not exist, throws exception",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment("1.0")
                ]):
            role = "role1"
            with Given(f"I drop {role} if it exists"):
                node.query(f"DROP ROLE IF EXISTS {role}")
            with Then(
                    f"I create a settings profile, assign to all except role {role}, which does not exist"
            ):
                exitcode, message = errors.role_not_found_in_disk(name=role)
                node.query(
                    f"CREATE SETTINGS PROFILE profile0 TO ALL EXCEPT {role}",
                    exitcode=exitcode,
                    message=message)
            del role

        with Scenario(
                "I create settings profile assigned to multiple roles",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment("1.0")
                ]):
            with cleanup("profile16"):
                with When("I create settings profile for multiple roles"):
                    node.query(
                        "CREATE SETTINGS PROFILE profile16 TO role0, user0")

        with Scenario(
                "I create settings profile assigned to all",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment_All(
                        "1.0")
                ]):
            with cleanup("profile17"):
                with When("I create settings profile for all"):
                    node.query("CREATE SETTINGS PROFILE profile17 TO ALL")

        with Scenario(
                "I create settings profile assigned to all except one role",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment_AllExcept(
                        "1.0")
                ]):
            with cleanup("profile18"):
                with When("I create settings profile for all except one role"):
                    node.query(
                        "CREATE SETTINGS PROFILE profile18 TO ALL EXCEPT role0"
                    )

        with Scenario(
                "I create settings profile assigned to all except multiple roles",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment_AllExcept(
                        "1.0")
                ]):
            with cleanup("profile19"):
                with When(
                        "I create settings profile for all except multiple roles"
                ):
                    node.query(
                        "CREATE SETTINGS PROFILE profile19 TO ALL EXCEPT role0, user0"
                    )

        with Scenario(
                "I create settings profile assigned to none",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_Assignment_None(
                        "1.0")
                ]):
            with cleanup("profile22"):
                with When("I create settings profile for none"):
                    node.query("CREATE SETTINGS PROFILE profile22 TO NONE")

        with Scenario(
                "I create settings profile on cluster",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_OnCluster("1.0")
                ]):
            try:
                with When("I run create settings profile command"):
                    node.query(
                        "CREATE SETTINGS PROFILE profile20 ON CLUSTER sharded_cluster"
                    )
                    node.query(
                        "CREATE SETTINGS PROFILE OR REPLACE profile20 ON CLUSTER sharded_cluster SETTINGS max_memory_usage = 100000001"
                    )
                    node.query(
                        "CREATE SETTINGS PROFILE OR REPLACE profile20 ON CLUSTER sharded_cluster SETTINGS INHERIT 'default'"
                    )
                    node.query(
                        "CREATE SETTINGS PROFILE OR REPLACE profile20 ON CLUSTER sharded_cluster TO ALL"
                    )
            finally:
                with Finally("I drop the settings profile"):
                    node.query(
                        "DROP SETTINGS PROFILE IF EXISTS profile20 ON CLUSTER sharded_cluster"
                    )

        with Scenario(
                "I create settings profile on fake cluster, throws exception",
                requirements=[
                    RQ_SRS_006_RBAC_SettingsProfile_Create_OnCluster("1.0")
                ]):
            with When("I run create settings profile command"):
                exitcode, message = errors.cluster_not_found("fake_cluster")
                node.query(
                    "CREATE SETTINGS PROFILE profile1 ON CLUSTER fake_cluster",
                    exitcode=exitcode,
                    message=message)
    finally:
        with Finally("I drop all the users and roles"):
            node.query(f"DROP USER IF EXISTS user0")
            node.query(f"DROP ROLE IF EXISTS role0")