Skip to content

Commit

Permalink
Add backupRBAC and restoreRBAC API (#400)
Browse files Browse the repository at this point in the history
Signed-off-by: ryjiang <[email protected]>
  • Loading branch information
shanghaikid authored Dec 26, 2024
1 parent 1750962 commit 4058848
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 7 deletions.
56 changes: 54 additions & 2 deletions milvus/grpc/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ import {
listRoleReq,
CreatePrivilegeGroupReq,
DropPrivilegeGroupReq,
OperatePrivilegeGroupReq,
AddPrivilegesToGroupReq,
RemovePrivilegesFromGroupReq,
OperatePrivilegeV2Request,
GrantPrivilegeV2Request,
RevokePrivilegeV2Request,
BackupRBACRequest,
RestoreRBACRequest,
OperatePrivilegeGroupType,
GrpcTimeOut,
ListCredUsersResponse,
Expand All @@ -35,8 +35,10 @@ import {
SelectGrantResponse,
HasRoleResponse,
ListPrivilegeGroupsResponse,
BackupRBACResponse,
promisify,
stringToBase64,
RBACMeta,
} from '../';

export class User extends Resource {
Expand Down Expand Up @@ -922,4 +924,54 @@ export class User extends Resource {

return promise;
}

/**
* backup RBAC data in Milvus.
* @param {BackupRBACRequest} data - The data object.
* @param {number} [data.timeout] - An optional duration of time in milliseconds to allow for the RPC. If it is set to undefined, the client keeps waiting until the server responds or error occurs. Default is undefined.
*
* @returns {Promise<BackupRBACResponse>} The response object.
*
* @example
* ```javascript
* await milvusClient.BackupRBAC();
* ```
*
*/
async backupRBAC(data?: BackupRBACRequest): Promise<BackupRBACResponse> {
const promise = await promisify(
this.channelPool,
'BackupRBAC',
data || {},
data?.timeout || this.timeout
);

return promise;
}

/**
* restore RBAC data in Milvus.
* @param {RestoreRBACRequest} data - The data object.
* @param {RBACMeta} data.RBAC_meta - The rbac meta data returned from the backupRBAC API.
* @param {number} [data.timeout] - An optional duration of time in milliseconds to allow for the RPC. If it is set to undefined, the client keeps waiting until the server responds or error occurs. Default is undefined.
*
* @returns {Promise<ResStatus>} The response object.
*
* @example
* ```javascript
* await milvusClient.restoreRBAC({
* RBAC_meta: rbacMeta,
* });
* ```
*/
async restoreRBAC(data: RestoreRBACRequest): Promise<ResStatus> {
const promise = await promisify(
this.channelPool,
'RestoreRBAC',
data,
data.timeout || this.timeout
);

return promise;
}
}
27 changes: 22 additions & 5 deletions milvus/types/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
OperatePrivilegeGroupType,
OperatePrivilegeType,
} from '../';
import exp from 'constants';

// base
export interface usernameReq extends GrpcTimeOut {
Expand Down Expand Up @@ -63,6 +64,18 @@ export type RoleResult = {
role: RoleEntity;
entities: GrantEntity[];
};
export type PrivelegeGroup = {
group_name: string; // name
privileges: PrivilegeEntity[]; // privileges
};

export type RBACMeta = {
users: User[];
roles: RoleEntity[];
grants: GrantEntity[];
privilege_groups: PrivelegeGroup[];
};

export interface SelectRoleResponse extends resStatusResponse {
results: RoleResult[];
}
Expand Down Expand Up @@ -115,11 +128,6 @@ export interface DropPrivilegeGroupReq extends GrpcTimeOut {
group_name: string; // required, name
}

export type PrivelegeGroup = {
group_name: string; // name
privileges: PrivilegeEntity[]; // privileges
};

export interface ListPrivilegeGroupsResponse extends resStatusResponse {
privilege_groups: PrivelegeGroup[]; // privilege groups
}
Expand All @@ -139,3 +147,12 @@ export interface RemovePrivilegesFromGroupReq extends GrpcTimeOut {
group_name: string; // required, group name
privileges: PrivilegesTypes[]; // required, privileges
}

export interface BackupRBACRequest extends GrpcTimeOut {}
export interface RestoreRBACRequest extends GrpcTimeOut {
RBAC_meta: RBACMeta; // required, RBAC meta
}

export interface BackupRBACResponse extends resStatusResponse {
RBAC_meta: RBACMeta; // RBAC meta
}
48 changes: 48 additions & 0 deletions test/grpc/User.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
Roles,
Privileges,
RbacObjects,
RBACMeta,
} from '../../milvus';
import { timeoutTest } from '../tools';
import { IP, genCollectionParams, GENERATE_NAME } from '../tools';
Expand Down Expand Up @@ -339,10 +340,57 @@ describe(`User Api`, () => {
expect(grp.privileges.map(p => p.name)).toContain(Privileges.Search);
});

let backupRBACMeta: RBACMeta;
it(`should backup RBAC meta`, async () => {
const res = await authClient.backupRBAC();
expect(res.status.error_code).toEqual(ErrorCode.SUCCESS);
// it should have one privilege group
expect(res.RBAC_meta.privilege_groups.length).toEqual(1);
backupRBACMeta = res.RBAC_meta;
});

it(`drop a privilege group`, async () => {
const res = await authClient.dropPrivilegeGroup({
group_name: PRIVILEGE_GRP_NAME,
});
expect(res.error_code).toEqual(ErrorCode.SUCCESS);
});

it(`restore RBAC meta`, async () => {
// make sure no privilege group
const pgrp = await authClient.listPrivilegeGroups();
// try to find the group
const theGrp = pgrp.privilege_groups.find(
g => g.group_name === PRIVILEGE_GRP_NAME
);
expect(theGrp).toBeUndefined();

// restore meta
const res = await authClient.restoreRBAC({
RBAC_meta: backupRBACMeta,
});
expect(res.error_code).toEqual(ErrorCode.SUCCESS);

// recheck
const listRes = await authClient.listPrivilegeGroups();
const grp = listRes.privilege_groups.find(
g => g.group_name === PRIVILEGE_GRP_NAME
)!;

expect(grp.group_name).toEqual(PRIVILEGE_GRP_NAME);
expect(grp.privileges.map(p => p.name)).toContain(Privileges.Search);

// // restore again should be ok
// const res2 = await authClient.restoreRBAC({
// RBAC_meta: backupRBACMeta,
// });
// console.log('res2', res2);
// expect(res2.error_code).toEqual(ErrorCode.SUCCESS);

// drop it again
const dropRes = await authClient.dropPrivilegeGroup({
group_name: PRIVILEGE_GRP_NAME,
});
expect(dropRes.error_code).toEqual(ErrorCode.SUCCESS);
});
});

0 comments on commit 4058848

Please sign in to comment.