Skip to content

feat(query): task support ownership #15458

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/common/cloud_control/proto/task.proto
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ message ShowTasksRequest {// every owner has a roles list like ["role1", "role2"
int32 result_limit = 4;
repeated string owners = 5; // all available roles under current client
repeated string task_ids = 6; // all task ids which permit to access for given user
repeated string task_names = 7; // all task names which permit to access for given user
}

message ShowTasksResponse {
Expand Down Expand Up @@ -170,6 +171,7 @@ message ShowTaskRunsRequest {
repeated string owners = 6;
repeated string task_ids = 7;
string task_name = 8;
repeated string task_names = 9;

optional int32 page_size = 90; // 100 by default
optional int64 next_page_token = 91;
Expand Down
3 changes: 3 additions & 0 deletions src/common/exception/src/exception_code.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,9 @@ build_exceptions! {

// sequence
SequenceError(3101),

// Task
UnknownTask(3201),
}

// Storage errors [3001, 4000].
Expand Down
11 changes: 10 additions & 1 deletion src/meta/app/src/principal/ownership_object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ pub enum OwnershipObject {
UDF {
name: String,
},

Task {
name: String,
},
}

impl OwnershipObject {
Expand Down Expand Up @@ -97,6 +101,7 @@ impl KeyCodec for OwnershipObject {
}
OwnershipObject::Stage { name } => b.push_raw("stage-by-name").push_str(name),
OwnershipObject::UDF { name } => b.push_raw("udf-by-name").push_str(name),
OwnershipObject::Task { name } => b.push_raw("task-by-name").push_str(name),
}
}

Expand Down Expand Up @@ -143,9 +148,13 @@ impl KeyCodec for OwnershipObject {
let name = p.next_str()?;
Ok(OwnershipObject::UDF { name })
}
"task-by-name" => {
let name = p.next_str()?;
Ok(OwnershipObject::Task { name })
}
_ => Err(kvapi::KeyError::InvalidSegment {
i: p.index(),
expect: "database-by-id|database-by-catalog-id|table-by-id|table-by-catalog-id|stage-by-name|udf-by-name"
expect: "database-by-id|database-by-catalog-id|table-by-id|table-by-catalog-id|stage-by-name|udf-by-name|task-by-name"
.to_string(),
got: q.to_string(),
}),
Expand Down
16 changes: 16 additions & 0 deletions src/meta/app/src/principal/tenant_ownership_object_ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,22 @@ mod tests {
let parsed = TenantOwnershipObjectIdent::from_str_key(&key).unwrap();
assert_eq!(role_grantee, parsed);
}

// task
{
let role_grantee = TenantOwnershipObjectIdent::new_unchecked(
Tenant::new_literal("test"),
OwnershipObject::Task {
name: "t1".to_string(),
},
);

let key = role_grantee.to_string_key();
assert_eq!("__fd_object_owners/test/task-by-name/t1", key);

let parsed = TenantOwnershipObjectIdent::from_str_key(&key).unwrap();
assert_eq!(role_grantee, parsed);
}
}

#[test]
Expand Down
11 changes: 10 additions & 1 deletion src/meta/app/src/principal/user_grant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ pub enum GrantObject {
TableById(String, u64, u64),
UDF(String),
Stage(String),
Task(String),
}

impl GrantObject {
Expand Down Expand Up @@ -62,6 +63,7 @@ impl GrantObject {
(GrantObject::Table(_, _, _), _) => false,
(GrantObject::Stage(lstage), GrantObject::Stage(rstage)) => lstage == rstage,
(GrantObject::UDF(udf), GrantObject::UDF(rudf)) => udf == rudf,
(GrantObject::Task(task), GrantObject::Task(rtask)) => task == rtask,
_ => false,
}
}
Expand All @@ -82,12 +84,18 @@ impl GrantObject {
GrantObject::Stage(_) => {
UserPrivilegeSet::available_privileges_on_stage(available_ownership)
}
GrantObject::Task(_) => {
UserPrivilegeSet::available_privileges_on_task(available_ownership)
}
}
}

pub fn catalog(&self) -> Option<String> {
match self {
GrantObject::Global | GrantObject::Stage(_) | GrantObject::UDF(_) => None,
GrantObject::Global
| GrantObject::Stage(_)
| GrantObject::UDF(_)
| GrantObject::Task(_) => None,
GrantObject::Database(cat, _) | GrantObject::DatabaseById(cat, _) => Some(cat.clone()),
GrantObject::Table(cat, _, _) | GrantObject::TableById(cat, _, _) => Some(cat.clone()),
}
Expand All @@ -108,6 +116,7 @@ impl fmt::Display for GrantObject {
}
GrantObject::UDF(udf) => write!(f, "UDF {udf}"),
GrantObject::Stage(stage) => write!(f, "STAGE {stage}"),
GrantObject::Task(task) => write!(f, "task {task}"),
}
}
}
Expand Down
19 changes: 18 additions & 1 deletion src/meta/app/src/principal/user_privilege.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ pub enum UserPrivilegeType {
Write = 1 << 19,
// Privilege to Create database
CreateDatabase = 1 << 20,
// Privilege to Create task
CreateTask = 1 << 21,
// Discard Privilege Type
Set = 1 << 4,
}
Expand All @@ -102,6 +104,7 @@ const ALL_PRIVILEGES: BitFlags<UserPrivilegeType> = make_bitflags!(
| Read
| Write
| CreateDatabase
| CreateTask
}
);

Expand Down Expand Up @@ -129,6 +132,7 @@ impl Display for UserPrivilegeType {
UserPrivilegeType::Read => "Read",
UserPrivilegeType::Write => "Write",
UserPrivilegeType::CreateDatabase => "CREATE DATABASE",
UserPrivilegeType::CreateTask => "CREATE TASK",
})
}
}
Expand Down Expand Up @@ -166,6 +170,9 @@ impl From<databend_common_ast::ast::UserPrivilegeType> for UserPrivilegeType {
databend_common_ast::ast::UserPrivilegeType::CreateDatabase => {
UserPrivilegeType::CreateDatabase
}
databend_common_ast::ast::UserPrivilegeType::CreateTask => {
UserPrivilegeType::CreateTask
}
databend_common_ast::ast::UserPrivilegeType::Set => UserPrivilegeType::Set,
}
}
Expand Down Expand Up @@ -199,10 +206,12 @@ impl UserPrivilegeSet {
let database_privs = Self::available_privileges_on_database(false);
let stage_privs_without_ownership = Self::available_privileges_on_stage(false);
let udf_privs_without_ownership = Self::available_privileges_on_udf(false);
let privs = make_bitflags!(UserPrivilegeType::{ Usage | Super | CreateUser | DropUser | CreateRole | DropRole | CreateDatabase | Grant | CreateDataMask });
let task_privs_without_ownership = Self::available_privileges_on_task(false);
let privs = make_bitflags!(UserPrivilegeType::{ Usage | Super | CreateUser | DropUser | CreateRole | DropRole | CreateDatabase | Grant | CreateDataMask | CreateTask });
(database_privs.privileges
| privs
| stage_privs_without_ownership.privileges
| task_privs_without_ownership.privileges
| udf_privs_without_ownership.privileges)
.into()
}
Expand Down Expand Up @@ -240,6 +249,14 @@ impl UserPrivilegeSet {
}
}

pub fn available_privileges_on_task(available_ownership: bool) -> Self {
if available_ownership {
make_bitflags!(UserPrivilegeType::{ Drop | Alter | Ownership }).into()
} else {
make_bitflags!(UserPrivilegeType::{ Drop | Alter }).into()
}
}

// TODO: remove this, as ALL has different meanings on different objects
pub fn all_privileges() -> Self {
ALL_PRIVILEGES.into()
Expand Down
8 changes: 8 additions & 0 deletions src/meta/proto-conv/src/ownership_from_to_protobuf_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ impl FromToProto for mt::principal::OwnershipObject {
Some(pb::ownership_object::Object::Stage(
pb::ownership_object::OwnershipStageObject { stage },
)) => Ok(mt::principal::OwnershipObject::Stage { name: stage }),
Some(pb::ownership_object::Object::Task(
pb::ownership_object::OwnershipTaskObject { task },
)) => Ok(mt::principal::OwnershipObject::Task { name: task }),
_ => Err(Incompatible {
reason: "OwnershipObject cannot be None".to_string(),
}),
Expand Down Expand Up @@ -115,6 +118,11 @@ impl FromToProto for mt::principal::OwnershipObject {
pb::ownership_object::OwnershipUdfObject { udf: name.clone() },
))
}
mt::principal::OwnershipObject::Task { name } => {
Some(pb::ownership_object::Object::Task(
pb::ownership_object::OwnershipTaskObject { task: name.clone() },
))
}
mt::principal::OwnershipObject::Stage { name } => Some(
pb::ownership_object::Object::Stage(pb::ownership_object::OwnershipStageObject {
stage: name.clone(),
Expand Down
6 changes: 6 additions & 0 deletions src/meta/proto-conv/src/user_from_to_protobuf_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,9 @@ impl FromToProto for mt::principal::GrantObject {
Some(pb::grant_object::Object::Stage(pb::grant_object::GrantStageObject { stage })) => {
Ok(mt::principal::GrantObject::Stage(stage))
}
Some(pb::grant_object::Object::Task(pb::grant_object::GrantTaskObject { task })) => {
Ok(mt::principal::GrantObject::Task(task))
}
_ => Err(Incompatible {
reason: "GrantObject cannot be None".to_string(),
}),
Expand Down Expand Up @@ -225,6 +228,9 @@ impl FromToProto for mt::principal::GrantObject {
stage: stage.clone(),
},
)),
mt::principal::GrantObject::Task(task) => Some(pb::grant_object::Object::Task(
pb::grant_object::GrantTaskObject { task: task.clone() },
)),
};
Ok(pb::GrantObject {
ver: VER,
Expand Down
1 change: 1 addition & 0 deletions src/meta/proto-conv/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ const META_CHANGE_LOG: &[(u64, &str)] = &[
(88, "2024-04-17: Add: SequenceMeta"),
(89, "2024-04-19: Add: geometry_output_format settings"),
(90, "2024-05-13: Refactor: After reader_check_msg success, RoleInfo::from_pb should not return err"),
(91, "2024-05-09: Add: GrantTaskObject"),
// Dear developer:
// If you're gonna add a new metadata version, you'll have to add a test for it.
// You could just copy an existing test file(e.g., `../tests/it/v024_table_meta.rs`)
Expand Down
2 changes: 1 addition & 1 deletion src/meta/proto-conv/tests/it/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,4 @@ mod v086_table_index;
mod v087_user_option_disabled;
mod v088_sequence_meta;
mod v089_geometry_output_format;
mod v090_role_info;
mod v091_role_info;
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ use crate::common;
//

#[test]
fn test_decode_v90_role() -> anyhow::Result<()> {
let role_info_v90 = vec![
fn test_decode_v91_role() -> anyhow::Result<()> {
let role_info_v91 = vec![
10, 2, 114, 49, 18, 6, 160, 6, 90, 168, 6, 24, 160, 6, 90, 168, 6, 24,
];

Expand All @@ -41,7 +41,7 @@ fn test_decode_v90_role() -> anyhow::Result<()> {
grants: UserGrantSet::new(vec![], HashSet::new()),
};
common::test_pb_from_to(func_name!(), want())?;
common::test_load_old(func_name!(), role_info_v90.as_slice(), 90, want())?;
common::test_load_old(func_name!(), role_info_v91.as_slice(), 90, want())?;

Ok(())
}
5 changes: 5 additions & 0 deletions src/meta/protos/proto/ownership.proto
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,15 @@ message OwnershipObject {
string stage = 1;
}

message OwnershipTaskObject {
string task = 1;
}

oneof object {
OwnershipDatabaseObject database = 1;
OwnershipTableObject table = 2;
OwnershipUdfObject udf = 3;
OwnershipStageObject stage = 4;
OwnershipTaskObject task = 5;
}
}
5 changes: 5 additions & 0 deletions src/meta/protos/proto/user.proto
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ message GrantObject {
string udf = 1;
}

message GrantTaskObject {
string task = 1;
}

message GrantStageObject {
string stage = 1;
}
Expand All @@ -84,6 +88,7 @@ message GrantObject {
GrantStageObject stage = 5;
GrantDatabaseIdObject databasebyid = 6;
GrantTableIdObject tablebyid = 7;
GrantTaskObject task = 8;
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/query/ast/src/ast/statements/principal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ pub enum UserPrivilegeType {
Write,
// Privilege to Create database
CreateDatabase,
// Privilege to Create database
CreateTask,
// Discard Privilege Type
Set,
}
Expand Down Expand Up @@ -184,6 +186,7 @@ impl Display for UserPrivilegeType {
UserPrivilegeType::Read => "Read",
UserPrivilegeType::Write => "Write",
UserPrivilegeType::CreateDatabase => "CREATE DATABASE",
UserPrivilegeType::CreateTask => "CREATE TASK",
})
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/query/ast/src/ast/statements/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ impl Display for AccountMgrSource {
}
AccountMgrLevel::UDF(udf) => write!(f, " UDF {udf}")?,
AccountMgrLevel::Stage(stage) => write!(f, " STAGE {stage}")?,
AccountMgrLevel::Task(task) => write!(f, " TASK {task}")?,
}
}
AccountMgrSource::ALL { level, .. } => {
Expand All @@ -199,6 +200,7 @@ impl Display for AccountMgrSource {
}
AccountMgrLevel::UDF(udf) => write!(f, " UDF {udf}")?,
AccountMgrLevel::Stage(stage) => write!(f, " STAGE {stage}")?,
AccountMgrLevel::Task(task) => write!(f, " TASK {task}")?,
}
}
}
Expand All @@ -213,6 +215,7 @@ pub enum AccountMgrLevel {
Table(#[drive(skip)] Option<String>, #[drive(skip)] String),
UDF(#[drive(skip)] String),
Stage(#[drive(skip)] String),
Task(#[drive(skip)] String),
}

#[derive(Debug, Clone, PartialEq, Eq, Drive, DriveMut)]
Expand Down
Loading