如何实现除了默认角色以外,在MWAA中实现编程式RBAC?

0

【以下的问题经过翻译处理】 你好,

我们希望通过编程方式向MWAA添加角色和权限。目前,这只能通过API实现,但所有端点都被拒绝。是否有突破口可以以编程方式创建角色并向其附加权限?

对于我们的情况,这是必需的,以使MWAA能够独立为多个租户提供服务,而不需要多个MWAA实例。

谢谢!

profile picture
专家
已提问 5 个月前19 查看次数
1 回答
0

【以下的回答经过翻译处理】 你可以通过DAG直接连接到数据库来完成大多数Airflow中的操作。以下是一个例子,它将复制一个现有的角色(如果新角色不存在),然后通过用户名将用户指派给该角色。然后,您可以修改新角色以获取您想要的特定权限。

from airflow.decorators import dag, task
from datetime import datetime
import os
from airflow import settings
from sqlalchemy import text

DAG_ID = os.path.basename(__file__).replace(".py", "")

NEW_ROLE = "My New Role"
SOURCE_ROLE = "Viewer"
USER_NAME = "MyUsername"

SQL_QUERY = """
DO $$
DECLARE
    new_role_name CONSTANT VARCHAR(64) := '{0}'; -- new role name
    source_role_name CONSTANT VARCHAR(64) := '{1}'; -- role to copy from
    user_name CONSTANT VARCHAR(64) := '{2}'; -- user to assign role to
    new_role_id integer;
    source_role_id integer;
    new_user_id integer;
BEGIN
    IF NOT EXISTS (SELECT id from ab_role WHERE name = source_role_name) THEN
        RAISE EXCEPTION 'Role "%" does not exist.', source_role_name;
    else
        SELECT id from ab_role WHERE name = source_role_name INTO source_role_id;
        RAISE INFO 'Source role ID is %', source_role_id;

        IF NOT EXISTS (SELECT id from ab_role WHERE name = new_role_name) THEN
            RAISE INFO 'Creating role "%"...', new_role_name;
            INSERT INTO ab_role(name) VALUES(new_role_name);

            SELECT id from ab_role WHERE name = new_role_name INTO new_role_id;
            RAISE INFO 'New role ID is %', new_role_id;

            INSERT INTO ab_permission_view_role
                (permission_view_id, role_id)
            SELECT a.permission_view_id, new_role_id AS role_id FROM ab_permission_view_role AS a WHERE a.role_id=source_role_id;
        else
            RAISE WARNING 'Role "%" exists...skipping create', new_role_name;
            SELECT id from ab_role WHERE name = new_role_name INTO new_role_id;
        END IF;

        IF EXISTS (SELECT id from ab_user WHERE username LIKE user_name limit 1) THEN
            SELECT id from ab_user WHERE username LIKE user_name limit 1 INTO new_user_id;
            RAISE INFO 'Assigning role to user id %...', new_user_id;
            INSERT INTO ab_user_role(user_id, role_id) VALUES(new_user_id, new_role_id);
        else
            RAISE WARNING 'Could not find user "%"...skipping role assignment', user_name;
        END IF;
    END IF;
END
$$ LANGUAGE plpgsql;
"""

@task()
def execute_sql_fn(sql):
    try:
        session = settings.Session()
        result = session.execute(text(sql)).all()

        return result
    except Exception as e:
        print(e)
        return None
    
@dag(
    dag_id=DAG_ID,
    schedule_interval=None,     
    start_date=datetime(2022, 1, 1),
    )
def sql_dag():
    t = execute_sql_fn(SQL_QUERY.format(NEW_ROLE,SOURCE_ROLE,USER_NAME))

my_sql_dag = sql_dag()

profile picture
专家
已回答 5 个月前

您未登录。 登录 发布回答。

一个好的回答可以清楚地解答问题和提供建设性反馈,并能促进提问者的职业发展。

回答问题的准则