From 512fcdc4e25dce8dfcb36704242a8aec5a10f4e2 Mon Sep 17 00:00:00 2001 From: Eric Bollengier Date: Fri, 28 Jan 2022 16:56:49 +0100 Subject: [PATCH] Add command to list metadata owners for a given tenant --- bacula/src/cats/bdb.h | 1 + bacula/src/cats/cats.c | 18 +++++---- bacula/src/cats/sql_list.c | 77 +++++++++++++++++++++++++++++++++++-- bacula/src/dird/ua_cmds.c | 2 +- bacula/src/dird/ua_output.c | 16 +++++--- 5 files changed, 97 insertions(+), 17 deletions(-) diff --git a/bacula/src/cats/bdb.h b/bacula/src/cats/bdb.h index 65043aef8..8357f42a3 100644 --- a/bacula/src/cats/bdb.h +++ b/bacula/src/cats/bdb.h @@ -289,6 +289,7 @@ public: void bdb_list_snapshot_records(JCR *jcr, SNAPSHOT_DBR *sdbr, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type); void bdb_list_files(JCR *jcr, FILE_DBR *fr, DB_RESULT_HANDLER *sendit, void *ctx); + void bdb_list_metadata_owner_records(JCR *jcr, META_DBR *meta_r, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type); void bdb_list_metadata_records(JCR *jcr, META_DBR *meta_r, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type); /* sql_update.c */ bool bdb_update_job_start_record(JCR *jcr, JOB_DBR *jr); diff --git a/bacula/src/cats/cats.c b/bacula/src/cats/cats.c index fd8dcf57c..178262ce0 100644 --- a/bacula/src/cats/cats.c +++ b/bacula/src/cats/cats.c @@ -687,12 +687,6 @@ bool META_DBR::check() bsnprintf(errmsg, sizeof(errmsg), _("Type is not set")); return false; } - - if (!Owner[0]) { - bsnprintf(errmsg, sizeof(errmsg), _("Owner is not set")); - return false; - } - if (!Tenant[0]) { bsnprintf(errmsg, sizeof(errmsg), _("Tenant not set")); return false; @@ -762,6 +756,12 @@ void META_DBR::create_db_filter(JCR *jcr, BDB *db, POOLMEM **where) pm_strcat(where, ") "); } + if (ClientName[0] != 0) { + db_escape_string(jcr, jcr->db, esc.c_str(), ClientName, strlen(ClientName)); + Mmsg(tmp, " Client.Name='%s'", esc.c_str()); + append_filter(where, tmp.c_str()); + } + if (ConversationId[0] != 0) { db_escape_string(jcr, jcr->db, esc.c_str(), ConversationId, strlen(ConversationId)); Mmsg(tmp, " MetaEmail.EmailConversationId = '%s'", esc.c_str()); @@ -808,7 +808,11 @@ void META_DBR::create_db_filter(JCR *jcr, BDB *db, POOLMEM **where) if (Owner[0]) { db_escape_string(jcr, jcr->db, esc.c_str(), Owner, strlen(Owner)); - Mmsg(tmp, " Meta%s.%sOwner = '%s'", Type, Type, esc.c_str()); + if (strchr(Owner, '%')) { + Mmsg(tmp, " Meta%s.%sOwner ILIKE '%s'", Type, Type, esc.c_str()); + } else { + Mmsg(tmp, " Meta%s.%sOwner = '%s'", Type, Type, esc.c_str()); + } append_filter(where, tmp.c_str()); } diff --git a/bacula/src/cats/sql_list.c b/bacula/src/cats/sql_list.c index 2c2173781..d0454b87a 100644 --- a/bacula/src/cats/sql_list.c +++ b/bacula/src/cats/sql_list.c @@ -1295,11 +1295,85 @@ void BDB::bdb_list_tag_records(JCR *jcr, TAG_DBR *tag, DB_LIST_HANDLER *result_h bdb_unlock(); } +/* List Owner in the metadata table */ +void BDB::bdb_list_metadata_owner_records(JCR *jcr, META_DBR *meta_r, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) +{ + POOL_MEM esc(PM_MESSAGE), tmp(PM_MESSAGE), where(PM_MESSAGE), join(PM_MESSAGE); + + bdb_lock(); + meta_r->create_db_filter(jcr, this, where.handle()); + const char *where_filter = get_acls(DB_ACL_BIT(DB_ACL_JOB) | + DB_ACL_BIT(DB_ACL_CLIENT), strcmp(where.c_str(), "") == 0); + + const char *join_filter = (*where_filter && meta_r->ClientName[0] == 0) ? + get_acl_join_filter(DB_ACL_BIT(DB_ACL_CLIENT)) : ""; + + if (meta_r->ClientName[0] != 0) { + Mmsg(join, " JOIN Job ON (Job.JobId = Meta%s.JobId) JOIN Client USING (ClientId) ", meta_r->Type); + + } else if (*where_filter) { // We add manually the Job join filter part + Mmsg(join, " JOIN Job ON (Job.JobId = Meta%s.JobId) ", meta_r->Type); + } + + if (where_filter && *where_filter) { + pm_strcat(where, where_filter); + } + + if (join_filter && *join_filter) { + pm_strcat(join, join_filter); + } + + if (meta_r->limit > 0) { + Mmsg(tmp, " LIMIT %d ", meta_r->limit); + pm_strcat(where, tmp.c_str()); + } + + if (meta_r->offset > 0) { + Mmsg(tmp, " OFFSET %ld ", meta_r->offset); + pm_strcat(where, tmp.c_str()); + } + + switch (type) { + case JSON_LIST: + case VERT_LIST: + case HORZ_LIST: + Mmsg(cmd, + "SELECT DISTINCT %sOwner " + "FROM Meta%s %s %s", + meta_r->Type, meta_r->Type, join.c_str(), where.c_str()); + break; + default: + break; + } + Dmsg1(DT_SQL|50, "%s\n", cmd); + if (!QueryDB(jcr, cmd)) { + Jmsg(jcr, M_ERROR, 0, _("Query %s failed!\n"), cmd); + bdb_unlock(); + return; + } + if (strcmp(meta_r->Type, "Email") == 0) { + Mmsg(esc, "metadataemail"); + } else { + Mmsg(esc, "metaattachment"); + } + + list_result(jcr, this, esc.c_str(), sendit, ctx, type); + + sql_free_result(); + bdb_unlock(); +} + /* * List plugin objects (search is based on object provided) */ void BDB::bdb_list_metadata_records(JCR *jcr, META_DBR *meta_r, DB_LIST_HANDLER *sendit, void *ctx, e_list_type type) { + if (!meta_r->Owner[0] || strchr(meta_r->Owner, '%')) { + /* List Owners */ + bdb_list_metadata_owner_records(jcr, meta_r, sendit, ctx, type); + return; + } + POOL_MEM esc(PM_MESSAGE), tmp(PM_MESSAGE), where(PM_MESSAGE), join(PM_MESSAGE); bdb_lock(); //TODO add ACL part @@ -1313,9 +1387,6 @@ void BDB::bdb_list_metadata_records(JCR *jcr, META_DBR *meta_r, DB_LIST_HANDLER get_acl_join_filter(DB_ACL_BIT(DB_ACL_CLIENT)) : ""; if (meta_r->ClientName[0] != 0) { - bdb_escape_string(jcr, esc.c_str(), meta_r->ClientName, strlen(meta_r->ClientName)); - Mmsg(tmp, " Client.Name='%s'", esc.c_str()); - append_filter(where.handle(), tmp.c_str()); Mmsg(join, " JOIN Job ON (Job.JobId = Meta%s.JobId) JOIN Client USING (ClientId) ", meta_r->Type); } else if (*where_filter) { // We add manually the Job join filter part diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 67e22d535..20c4a3ffb 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -138,7 +138,7 @@ static struct cmdstruct commands[] = { /* C "\tevents [type= | limit= | order= | days= | start= | end= |\n" "\t\t source= | code= | type= ]\n" "\tobjects [jobid= client= type= | category= | status= | limit= | order= ]\n" - "\tmetadata type= tenant= owner=\n" + "\tmetadata type= tenant= [owner=]\n" "\t [jobid= client= order= limit= orderby=