This is an automated email from the ASF dual-hosted git repository.
shaofengshi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/gravitino.git
The following commit(s) were added to refs/heads/main by this push:
new eba65cd86 [#5162] Add basic role commands to Gravitino CLI (#5291)
eba65cd86 is described below
commit eba65cd8648a4e10294e9b748a03d17b27d9b861
Author: Justin Mclean <[email protected]>
AuthorDate: Wed Nov 13 17:26:29 2024 +1100
[#5162] Add basic role commands to Gravitino CLI (#5291)
### What changes were proposed in this pull request?
Add basic role commands to Gravitino CLI
### Why are the changes needed?
For the CLI to support roles.
Fix: #5162
### Does this PR introduce _any_ user-facing change?
No, but it adds roles to the CLI.
### How was this patch tested?
Compiled and tested locally.
---
.../org/apache/gravitino/cli/CommandEntities.java | 2 +
.../org/apache/gravitino/cli/ErrorMessages.java | 2 +
.../apache/gravitino/cli/GravitinoCommandLine.java | 25 +++++++
.../org/apache/gravitino/cli/GravitinoOptions.java | 4 +-
.../apache/gravitino/cli/commands/CreateRole.java | 65 ++++++++++++++++++
.../apache/gravitino/cli/commands/DeleteRole.java | 80 ++++++++++++++++++++++
.../apache/gravitino/cli/commands/ListRoles.java | 62 +++++++++++++++++
.../apache/gravitino/cli/commands/RoleDetails.java | 73 ++++++++++++++++++++
.../apache/gravitino/cli/TestCommandEntities.java | 2 +
docs/cli.md | 63 ++++++++++++-----
10 files changed, 359 insertions(+), 19 deletions(-)
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/CommandEntities.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/CommandEntities.java
index 12d869c42..a68703a13 100644
--- a/clients/cli/src/main/java/org/apache/gravitino/cli/CommandEntities.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/CommandEntities.java
@@ -34,6 +34,7 @@ public class CommandEntities {
public static final String USER = "user";
public static final String GROUP = "group";
public static final String TAG = "tag";
+ public static final String ROLE = "role";
private static final HashSet<String> VALID_ENTITIES = new HashSet<>();
@@ -46,6 +47,7 @@ public class CommandEntities {
VALID_ENTITIES.add(USER);
VALID_ENTITIES.add(GROUP);
VALID_ENTITIES.add(TAG);
+ VALID_ENTITIES.add(ROLE);
}
/**
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/ErrorMessages.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/ErrorMessages.java
index f599964c9..0ad750f2c 100644
--- a/clients/cli/src/main/java/org/apache/gravitino/cli/ErrorMessages.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/ErrorMessages.java
@@ -39,6 +39,8 @@ public class ErrorMessages {
public static final String GROUP_EXISTS = "Group already exists.";
public static final String UNKNOWN_TAG = "Unknown tag.";
public static final String TAG_EXISTS = "Tag already exists.";
+ public static final String UNKNOWN_ROLE = "Unknown role.";
+ public static final String ROLE_EXISTS = "Role already exists.";
public static final String INVALID_SET_COMMAND =
"Unsupported combination of options either use --name or --property and
--value.";
public static final String INVALID_REMOVE_COMMAND =
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoCommandLine.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoCommandLine.java
index b544a6b80..630828bdb 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoCommandLine.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoCommandLine.java
@@ -29,12 +29,14 @@ import org.apache.gravitino.cli.commands.ClientVersion;
import org.apache.gravitino.cli.commands.CreateCatalog;
import org.apache.gravitino.cli.commands.CreateGroup;
import org.apache.gravitino.cli.commands.CreateMetalake;
+import org.apache.gravitino.cli.commands.CreateRole;
import org.apache.gravitino.cli.commands.CreateSchema;
import org.apache.gravitino.cli.commands.CreateTag;
import org.apache.gravitino.cli.commands.CreateUser;
import org.apache.gravitino.cli.commands.DeleteCatalog;
import org.apache.gravitino.cli.commands.DeleteGroup;
import org.apache.gravitino.cli.commands.DeleteMetalake;
+import org.apache.gravitino.cli.commands.DeleteRole;
import org.apache.gravitino.cli.commands.DeleteSchema;
import org.apache.gravitino.cli.commands.DeleteTable;
import org.apache.gravitino.cli.commands.DeleteTag;
@@ -48,6 +50,7 @@ import org.apache.gravitino.cli.commands.ListEntityTags;
import org.apache.gravitino.cli.commands.ListGroups;
import org.apache.gravitino.cli.commands.ListMetalakeProperties;
import org.apache.gravitino.cli.commands.ListMetalakes;
+import org.apache.gravitino.cli.commands.ListRoles;
import org.apache.gravitino.cli.commands.ListSchema;
import org.apache.gravitino.cli.commands.ListSchemaProperties;
import org.apache.gravitino.cli.commands.ListTables;
@@ -59,6 +62,7 @@ import
org.apache.gravitino.cli.commands.RemoveCatalogProperty;
import org.apache.gravitino.cli.commands.RemoveMetalakeProperty;
import org.apache.gravitino.cli.commands.RemoveSchemaProperty;
import org.apache.gravitino.cli.commands.RemoveTagProperty;
+import org.apache.gravitino.cli.commands.RoleDetails;
import org.apache.gravitino.cli.commands.SchemaAudit;
import org.apache.gravitino.cli.commands.SchemaDetails;
import org.apache.gravitino.cli.commands.ServerVersion;
@@ -181,6 +185,8 @@ public class GravitinoCommandLine {
handleGroupCommand();
} else if (entity.equals(CommandEntities.TAG)) {
handleTagCommand();
+ } else if (entity.equals(CommandEntities.ROLE)) {
+ handleRoleCommand();
}
}
@@ -443,6 +449,25 @@ public class GravitinoCommandLine {
}
}
+ /** Handles the command execution for Roles based on command type and the
command line options. */
+ protected void handleRoleCommand() {
+ String url = getUrl();
+ FullName name = new FullName(line);
+ String metalake = name.getMetalakeName();
+ String role = line.getOptionValue(GravitinoOptions.ROLE);
+
+ if (CommandActions.DETAILS.equals(command)) {
+ new RoleDetails(url, ignore, metalake, role).handle();
+ } else if (CommandActions.LIST.equals(command)) {
+ new ListRoles(url, ignore, metalake).handle();
+ } else if (CommandActions.CREATE.equals(command)) {
+ new CreateRole(url, ignore, metalake, role).handle();
+ } else if (CommandActions.DELETE.equals(command)) {
+ boolean force = line.hasOption(GravitinoOptions.FORCE);
+ new DeleteRole(url, ignore, force, metalake, role).handle();
+ }
+ }
+
/**
* Handles the command execution for Columns based on command type and the
command line options.
*/
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoOptions.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoOptions.java
index cb6cfc43d..63668fd3a 100644
--- a/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoOptions.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/GravitinoOptions.java
@@ -40,6 +40,7 @@ public class GravitinoOptions {
public static final String USER = "user";
public static final String GROUP = "group";
public static final String TAG = "tag";
+ public static final String ROLE = "role";
public static final String AUDIT = "audit";
public static final String FORCE = "force";
@@ -62,7 +63,7 @@ public class GravitinoOptions {
options.addOption(createSimpleOption("a", AUDIT, "display audit
information"));
// Create/update options
- options.addOption(createArgOption("r", RENAME, "new entity name"));
+ options.addOption(createArgOption(null, RENAME, "new entity name"));
options.addOption(createArgOption("c", COMMENT, "entity comment"));
options.addOption(createArgOption("P", PROPERTY, "property name"));
options.addOption(createArgOption("V", VALUE, "property value"));
@@ -72,6 +73,7 @@ public class GravitinoOptions {
options.addOption(createArgOption("l", USER, "user name"));
options.addOption(createArgOption("g", GROUP, "group name"));
options.addOption(createArgOption("t", TAG, "tag name"));
+ options.addOption(createArgOption("r", ROLE, "role name"));
// Properties option can have multiple values
Option properties =
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/CreateRole.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/CreateRole.java
new file mode 100644
index 000000000..d3b71f45a
--- /dev/null
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/CreateRole.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.gravitino.cli.commands;
+
+import java.util.Collections;
+import org.apache.gravitino.cli.ErrorMessages;
+import org.apache.gravitino.client.GravitinoClient;
+import org.apache.gravitino.exceptions.NoSuchMetalakeException;
+import org.apache.gravitino.exceptions.RoleAlreadyExistsException;
+
+public class CreateRole extends Command {
+ protected String metalake;
+ protected String role;
+
+ /**
+ * Create a new role.
+ *
+ * @param url The URL of the Gravitino server.
+ * @param ignoreVersions If true don't check the client/server versions
match.
+ * @param metalake The name of the metalake.
+ * @param role The name of the role.
+ */
+ public CreateRole(String url, boolean ignoreVersions, String metalake,
String role) {
+ super(url, ignoreVersions);
+ this.metalake = metalake;
+ this.role = role;
+ }
+
+ /** Create a new role. */
+ @Override
+ public void handle() {
+ try {
+ GravitinoClient client = buildClient(metalake);
+ client.createRole(role, null, Collections.EMPTY_LIST);
+ } catch (NoSuchMetalakeException err) {
+ System.err.println(ErrorMessages.UNKNOWN_METALAKE);
+ return;
+ } catch (RoleAlreadyExistsException err) {
+ System.err.println(ErrorMessages.ROLE_EXISTS);
+ return;
+ } catch (Exception exp) {
+ System.err.println(exp.getMessage());
+ return;
+ }
+
+ System.out.println(role + " created");
+ }
+}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/DeleteRole.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/DeleteRole.java
new file mode 100644
index 000000000..0338c0c37
--- /dev/null
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/DeleteRole.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.gravitino.cli.commands;
+
+import org.apache.gravitino.cli.AreYouSure;
+import org.apache.gravitino.cli.ErrorMessages;
+import org.apache.gravitino.client.GravitinoClient;
+import org.apache.gravitino.exceptions.NoSuchMetalakeException;
+import org.apache.gravitino.exceptions.NoSuchRoleException;
+
+public class DeleteRole extends Command {
+
+ protected String metalake;
+ protected String role;
+ protected boolean force;
+
+ /**
+ * Delete a role.
+ *
+ * @param url The URL of the Gravitino server.
+ * @param ignoreVersions If true don't check the client/server versions
match.
+ * @param force Force operation.
+ * @param metalake The name of the metalake.
+ * @param role The name of the role.
+ */
+ public DeleteRole(
+ String url, boolean ignoreVersions, boolean force, String metalake,
String role) {
+ super(url, ignoreVersions);
+ this.metalake = metalake;
+ this.force = force;
+ this.role = role;
+ }
+
+ /** Delete a role. */
+ @Override
+ public void handle() {
+ boolean deleted = false;
+
+ if (!AreYouSure.really(force)) {
+ return;
+ }
+
+ try {
+ GravitinoClient client = buildClient(metalake);
+ deleted = client.deleteRole(role);
+ } catch (NoSuchMetalakeException err) {
+ System.err.println(ErrorMessages.UNKNOWN_METALAKE);
+ return;
+ } catch (NoSuchRoleException err) {
+ System.err.println(ErrorMessages.UNKNOWN_ROLE);
+ return;
+ } catch (Exception exp) {
+ System.err.println(exp.getMessage());
+ return;
+ }
+
+ if (deleted) {
+ System.out.println(role + " deleted.");
+ } else {
+ System.out.println(role + " not deleted.");
+ }
+ }
+}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListRoles.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListRoles.java
new file mode 100644
index 000000000..cca26336e
--- /dev/null
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/ListRoles.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.gravitino.cli.commands;
+
+import org.apache.gravitino.cli.ErrorMessages;
+import org.apache.gravitino.client.GravitinoClient;
+import org.apache.gravitino.exceptions.NoSuchMetalakeException;
+
+/* Lists all roles in a metalake. */
+public class ListRoles extends Command {
+
+ protected String metalake;
+
+ /**
+ * Lists all groups in a metalake.
+ *
+ * @param url The URL of the Gravitino server.
+ * @param ignoreVersions If true don't check the client/server versions
match.
+ * @param metalake The name of the metalake.
+ */
+ public ListRoles(String url, boolean ignoreVersions, String metalake) {
+ super(url, ignoreVersions);
+ this.metalake = metalake;
+ }
+
+ /** Lists all roles in a metalake. */
+ @Override
+ public void handle() {
+ String[] roles = new String[0];
+ try {
+ GravitinoClient client = buildClient(metalake);
+ roles = client.listRoleNames();
+ } catch (NoSuchMetalakeException err) {
+ System.err.println(ErrorMessages.UNKNOWN_METALAKE);
+ return;
+ } catch (Exception exp) {
+ System.err.println(exp.getMessage());
+ return;
+ }
+
+ String all = String.join(",", roles);
+
+ System.out.println(all.toString());
+ }
+}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/RoleDetails.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/RoleDetails.java
new file mode 100644
index 000000000..613ee60d2
--- /dev/null
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/RoleDetails.java
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.gravitino.cli.commands;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import org.apache.gravitino.authorization.SecurableObject;
+import org.apache.gravitino.cli.ErrorMessages;
+import org.apache.gravitino.client.GravitinoClient;
+import org.apache.gravitino.exceptions.NoSuchMetalakeException;
+import org.apache.gravitino.exceptions.NoSuchUserException;
+
+public class RoleDetails extends Command {
+
+ protected String metalake;
+ protected String role;
+
+ /**
+ * Displays the securable objects in a role.
+ *
+ * @param url The URL of the Gravitino server.
+ * @param ignoreVersions If true don't check the client/server versions
match.
+ * @param metalake The name of the metalake.
+ * @param role The name of the role.
+ */
+ public RoleDetails(String url, boolean ignoreVersions, String metalake,
String role) {
+ super(url, ignoreVersions);
+ this.metalake = metalake;
+ this.role = role;
+ }
+
+ /** Displays the securable objects of a specified role. */
+ @Override
+ public void handle() {
+ List<SecurableObject> objects = null;
+
+ try {
+ GravitinoClient client = buildClient(metalake);
+ objects = client.getRole(role).securableObjects();
+ } catch (NoSuchMetalakeException err) {
+ System.err.println(ErrorMessages.UNKNOWN_METALAKE);
+ return;
+ } catch (NoSuchUserException err) {
+ System.err.println(ErrorMessages.UNKNOWN_GROUP);
+ return;
+ } catch (Exception exp) {
+ System.err.println(exp.getMessage());
+ return;
+ }
+
+ // TODO expand in securable objects PR
+ String all =
objects.stream().map(SecurableObject::name).collect(Collectors.joining(","));
+
+ System.out.println(all.toString());
+ }
+}
diff --git
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestCommandEntities.java
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestCommandEntities.java
index cd2a55e2a..50743c1f3 100644
---
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestCommandEntities.java
+++
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestCommandEntities.java
@@ -38,6 +38,8 @@ public class TestCommandEntities {
assertTrue(
CommandEntities.isValidEntity(CommandEntities.TABLE), "TABLE should be
a valid entity");
assertTrue(CommandEntities.isValidEntity(CommandEntities.TAG), "TAG should
be a valid entity");
+ assertTrue(
+ CommandEntities.isValidEntity(CommandEntities.ROLE), "ROLE should be a
valid entity");
}
@Test
diff --git a/docs/cli.md b/docs/cli.md
index 14b14cf24..42c306674 100644
--- a/docs/cli.md
+++ b/docs/cli.md
@@ -29,24 +29,25 @@ The general structure for running commands with the
Gravitino CLI is `gcli entit
```bash
usage: gcli [metalake|catalog|schema|table|column]
[list|details|create|delete|update|set|remove|properties] [options]
Options
- -a,--audit display audit information
- -c,--comment <arg> entity comment
- -g,--group <arg> group name
- -h,--help command help information
- -i,--ignore ignore client/sever version check
- -l,--user <arg> user name
- -m,--metalake <arg> metalake name
- -n,--name <arg> full entity name (dot separated)
- -P,--property <arg> property name
- -p,--properties <arg> property name/value pairs
- -r,--rename <arg> new entity name
- -s,--server Gravitino server version
- -t,--tag <arg> tag name
- -u,--url <arg> Gravitino URL (default: http://localhost:8090)
- -v,--version Gravitino client version
- -V,--value <arg> property value
- -z,--provider <arg> provider one of hadoop, hive, mysql, postgres,
- iceberg, kafka
+ -a,--audit display audit information
+ -c,--comment <arg> entity comment
+ -f,--force force operation
+ -g,--group <arg> group name
+ -h,--help command help information
+ -i,--ignore ignore client/sever version check
+ -l,--user <arg> user name
+ -m,--metalake <arg> metalake name
+ -n,--name <arg> full entity name (dot separated)
+ -P,--property <arg> property name
+ -r,--role <arg> role name
+ --rename <arg> new entity name
+ -s,--server Gravitino server version
+ -t,--tag <arg> tag name
+ -u,--url <arg> Gravitino URL (default: http://localhost:8090)
+ -v,--version Gravitino client version
+ -V,--value <arg> property value
+ -z,--provider <arg> provider one of hadoop, hive, mysql, postgres,
+ iceberg, kafka
```
## Commands
@@ -503,3 +504,29 @@ gcli tag update --tag tagA --rename newTag
```bash
gcli tag update --tag tagA --comment "new comment"
```
+
+### Role commands
+
+#### Display role details
+
+```bash
+gcli role details --role admin
+```
+
+#### List all roles
+
+```bash
+gcli role list
+```
+
+#### Create a role
+
+```bash
+gcli role create --role admin
+ ```
+
+#### Delete a role
+
+```bash
+gcli role delete --role admin
+ ```