diff --git a/include/common/tgrant.h b/include/common/tgrant.h index 5a2ed580454..7e7162204e2 100644 --- a/include/common/tgrant.h +++ b/include/common/tgrant.h @@ -56,6 +56,10 @@ typedef enum { TSDB_GRANT_VIEW, TSDB_GRANT_MULTI_TIER, TSDB_GRANT_BACKUP_RESTORE, + TSDB_GRANT_OBJECT_STORAGE, + TSDB_GRANT_ACTIVE_ACTIVE, + TSDB_GRANT_DUAL_REPLICA_HA, + TSDB_GRANT_DB_ENCRYPTION, } EGrantType; int32_t checkAndGetCryptKey(const char *encryptCode, const char *machineId, char **key); diff --git a/include/util/taoserror.h b/include/util/taoserror.h index 03a024bb8c7..dafdac9649d 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -327,6 +327,7 @@ int32_t* taosGetErrno(); #define TSDB_CODE_MND_DB_IN_CREATING TAOS_DEF_ERROR_CODE(0, 0x0396) // #define TSDB_CODE_MND_INVALID_SYS_TABLENAME TAOS_DEF_ERROR_CODE(0, 0x039A) #define TSDB_CODE_MND_ENCRYPT_NOT_ALLOW_CHANGE TAOS_DEF_ERROR_CODE(0, 0x039B) +#define TSDB_CODE_MND_DB_ENCRYPT_GRANT_EXPIRED TAOS_DEF_ERROR_CODE(0, 0x039C) // mnode-node #define TSDB_CODE_MND_MNODE_ALREADY_EXIST TAOS_DEF_ERROR_CODE(0, 0x03A0) diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 8b7901e2a75..f4999ed368f 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -296,6 +296,7 @@ char tsS3AccessKeySecret[TSDB_FQDN_LEN] = ""; char tsS3BucketName[TSDB_FQDN_LEN] = ""; char tsS3AppId[TSDB_FQDN_LEN] = ""; int8_t tsS3Enabled = false; +int8_t tsS3EnabledCfg = false; int8_t tsS3Oss = false; int8_t tsS3StreamEnabled = false; @@ -375,6 +376,7 @@ int32_t taosSetS3Cfg(SConfig *pCfg) { #if defined(USE_COS) || defined(USE_S3) #ifdef TD_ENTERPRISE /*if (tsDiskCfgNum > 1) */ tsS3Enabled = true; + tsS3EnabledCfg = true; #endif tsS3StreamEnabled = true; #endif diff --git a/source/dnode/mgmt/node_mgmt/src/dmEnv.c b/source/dnode/mgmt/node_mgmt/src/dmEnv.c index 12712d65853..8e760c28be2 100644 --- a/source/dnode/mgmt/node_mgmt/src/dmEnv.c +++ b/source/dnode/mgmt/node_mgmt/src/dmEnv.c @@ -17,6 +17,7 @@ #include "dmMgmt.h" #include "audit.h" #include "libs/function/tudf.h" +#include "tgrant.h" #define DM_INIT_AUDIT() \ do { \ @@ -150,6 +151,7 @@ static bool dmCheckDataDirVersion() { extern int32_t s3Begin(); extern void s3End(); +extern int8_t tsS3Enabled; #endif diff --git a/source/dnode/mnode/impl/src/mndDb.c b/source/dnode/mnode/impl/src/mndDb.c index 6d638dab3b2..f254fb16a52 100644 --- a/source/dnode/mnode/impl/src/mndDb.c +++ b/source/dnode/mnode/impl/src/mndDb.c @@ -821,6 +821,10 @@ static int32_t mndCheckDbEncryptKey(SMnode *pMnode, SCreateDbReq *pReq) { #ifdef TD_ENTERPRISE if (pReq->encryptAlgorithm == TSDB_ENCRYPT_ALGO_NONE) goto _exit; + if (grantCheck(TSDB_GRANT_DB_ENCRYPTION) != 0) { + code = TSDB_CODE_MND_DB_ENCRYPT_GRANT_EXPIRED; + goto _exit; + } if (tsEncryptionKeyStat != ENCRYPT_KEY_STAT_LOADED) { code = TSDB_CODE_MND_INVALID_ENCRYPT_KEY; mError("db:%s, failed to check encryption key:%" PRIi8 " in mnode leader since it's not loaded", pReq->db, @@ -903,6 +907,13 @@ static int32_t mndProcessCreateDbReq(SRpcMsg *pReq) { goto _OVER; } + if (createReq.replications == 2) { + if ((terrno = grantCheck(TSDB_GRANT_DUAL_REPLICA_HA)) != 0) { + code = terrno; + goto _OVER; + } + } + if ((code = mndCheckDbEncryptKey(pMnode, &createReq)) != 0) { terrno = code; goto _OVER; @@ -1163,6 +1174,12 @@ static int32_t mndProcessAlterDbReq(SRpcMsg *pReq) { goto _OVER; } + if (alterReq.replications == 2) { + if ((code = grantCheck(TSDB_GRANT_DUAL_REPLICA_HA)) != 0) { + goto _OVER; + } + } + int32_t numOfTopics = 0; if (mndGetNumOfTopics(pMnode, pDb->name, &numOfTopics) != 0) { goto _OVER; diff --git a/source/dnode/vnode/src/tsdb/tsdbRetention.c b/source/dnode/vnode/src/tsdb/tsdbRetention.c index 5a138d2bed9..f4344296b44 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRetention.c +++ b/source/dnode/vnode/src/tsdb/tsdbRetention.c @@ -757,6 +757,16 @@ static int32_t tsdbDoS3MigrateAsync(void *arg) { int32_t tsdbS3Migrate(STsdb *tsdb, int64_t now, int32_t sync) { int32_t code = 0; + extern int8_t tsS3EnabledCfg; + + int32_t expired = grantCheck(TSDB_GRANT_OBJECT_STORAGE); + if (expired && tsS3Enabled) { + tsdbWarn("s3 grant expired: %d", expired); + tsS3Enabled = false; + } else if (!expired && tsS3EnabledCfg) { + tsS3Enabled = true; + } + if (!tsS3Enabled) { return code; } diff --git a/source/util/src/terror.c b/source/util/src/terror.c index add01b3188c..ad811cc8916 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -259,6 +259,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_IN_CREATING, "Database in creating TAOS_DEFINE_ERROR(TSDB_CODE_MND_ENCRYPT_NOT_ALLOW_CHANGE, "Encryption is not allowed to be changed after database is created") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INCONSIST_ENCRYPT_KEY, "Inconsistent encryption key") TAOS_DEFINE_ERROR(TSDB_CODE_MND_INVALID_ENCRYPT_KEY, "The cluster has not been set properly for database encryption") +TAOS_DEFINE_ERROR(TSDB_CODE_MND_DB_ENCRYPT_GRANT_EXPIRED, "The database encryption function grant expired") // mnode-node TAOS_DEFINE_ERROR(TSDB_CODE_MND_MNODE_ALREADY_EXIST, "Mnode already exists") diff --git a/tests/system-test/0-others/information_schema.py b/tests/system-test/0-others/information_schema.py index 2924ebd3881..944b2fbb1ef 100644 --- a/tests/system-test/0-others/information_schema.py +++ b/tests/system-test/0-others/information_schema.py @@ -269,13 +269,17 @@ def ins_dnodes_check(self): def ins_grants_check(self): grant_name_dict = { - 'stream':'stream', - 'subscription':'subscription', - 'view':'view', - 'audit':'audit', - 'csv':'csv', - 'storage':'multi_tier_storage', - 'backup_restore':'backup_restore', + 'stream':'Stream', + 'subscription':'Subscription', + 'view':'View', + 'audit':'Audit', + 'csv':'CSV', + 'storage':'Multi-Tier Storage', + 'backup_restore':'Data Backup & Restore', + 'object_storage':'Object Storage', + 'active_active':'Active-Active', + 'dual_replica':'Dual-Replica HA', + 'db_encryption':'Database Encryption', 'opc_da':'OPC_DA', 'opc_ua':'OPC_UA', 'pi':'Pi', @@ -285,7 +289,10 @@ def ins_grants_check(self): 'avevahistorian':'avevaHistorian', 'opentsdb':'OpenTSDB', 'td2.6':'TDengine2.6', - 'td3.0':'TDengine3.0' + 'td3.0':'TDengine3.0', + 'mysql':'MySQL', + 'postgres':'PostgreSQL', + 'oracle':'Oracle', } tdSql.execute('drop database if exists db2') @@ -297,7 +304,7 @@ def ins_grants_check(self): if result[i][0] in grant_name_dict: tdSql.checkEqual(result[i][1], grant_name_dict[result[i][0]]) index += 1 - tdSql.checkEqual(index, 17) + tdSql.checkEqual(index, 24) tdSql.query(f'select * from information_schema.ins_grants_logs') result = tdSql.queryResult tdSql.checkEqual(True, len(result) >= 0)