This is an automated email from the ASF dual-hosted git repository.
jshao 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 d8b4407e3 [#5281] Add owner support to Gravitino CLI (#5293)
d8b4407e3 is described below
commit d8b4407e31d92608f02ac7023c96e2996ad4d0db
Author: Justin Mclean <[email protected]>
AuthorDate: Wed Nov 27 17:35:27 2024 +1100
[#5281] Add owner support to Gravitino CLI (#5293)
### What changes were proposed in this pull request?
Add owner support to Gravitino CLI
### Why are the changes needed?
To continue adding to the CLI.
Fix: #5281
### Does this PR introduce _any_ user-facing change?
No, but it expands on the CLI.
### How was this patch tested?
Compiled and tested locally.
---
.../org/apache/gravitino/cli/ErrorMessages.java | 6 +-
.../apache/gravitino/cli/GravitinoCommandLine.java | 37 ++++++-
.../org/apache/gravitino/cli/GravitinoOptions.java | 4 +-
.../main/java/org/apache/gravitino/cli/Main.java | 2 +-
.../apache/gravitino/cli/TestableCommandLine.java | 18 +++
.../gravitino/cli/commands/OwnerDetails.java | 94 ++++++++++++++++
.../apache/gravitino/cli/commands/SetOwner.java | 101 +++++++++++++++++
.../apache/gravitino/cli/TestOwnerCommands.java | 122 +++++++++++++++++++++
docs/cli.md | 25 ++++-
9 files changed, 402 insertions(+), 7 deletions(-)
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 6836bd203..3c7870968 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
@@ -44,8 +44,12 @@ public class ErrorMessages {
public static final String TAG_EMPTY = "Error: Must configure --tag option.";
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.";
+ "Unsupported combination of options either use --name, --user, --group
or --property and --value.";
public static final String INVALID_REMOVE_COMMAND =
"Unsupported combination of options either use --name or --property.";
+ public static final String INVALID_OWNER_COMMAND =
+ "Unsupported combination of options either use --user or --group.";
+ public static final String UNSUPPORTED_ACTION = "Entity doesn't support this
action.";
}
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 1cdbfaf25..a4b41b12e 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
@@ -112,7 +112,9 @@ public class GravitinoCommandLine extends
TestableCommandLine {
/** Executes the appropriate command based on the command type. */
private void executeCommand() {
- if (entity.equals(CommandEntities.COLUMN)) {
+ if (line.hasOption(GravitinoOptions.OWNER)) {
+ handleOwnerCommand();
+ } else if (entity.equals(CommandEntities.COLUMN)) {
handleColumnCommand();
} else if (entity.equals(CommandEntities.TABLE)) {
handleTableCommand();
@@ -331,6 +333,8 @@ public class GravitinoCommandLine extends
TestableCommandLine {
if (role != null) {
newAddRoleToUser(url, ignore, metalake, user, role).handle();
}
+ } else {
+ System.err.println(ErrorMessages.UNSUPPORTED_ACTION);
}
}
@@ -360,6 +364,8 @@ public class GravitinoCommandLine extends
TestableCommandLine {
if (role != null) {
newAddRoleToGroup(url, ignore, metalake, group, role).handle();
}
+ } else {
+ System.err.println(ErrorMessages.UNSUPPORTED_ACTION);
}
}
@@ -392,7 +398,7 @@ public class GravitinoCommandLine extends
TestableCommandLine {
String value = line.getOptionValue(GravitinoOptions.VALUE);
if (property != null && value != null) {
newSetTagProperty(url, ignore, metalake, getOneTag(tags), property,
value).handle();
- } else if (name != null && property == null && value == null) {
+ } else if (property == null && value == null) {
newTagEntity(url, ignore, metalake, name, tags).handle();
}
} else if (CommandActions.REMOVE.equals(command)) {
@@ -456,6 +462,33 @@ public class GravitinoCommandLine extends
TestableCommandLine {
}
}
+ /**
+ * Handles the command execution for Objects based on command type and the
command line options.
+ */
+ private void handleOwnerCommand() {
+ String url = getUrl();
+ FullName name = new FullName(line);
+ String metalake = name.getMetalakeName();
+ String entityName = line.getOptionValue(GravitinoOptions.NAME);
+
+ if (CommandActions.DETAILS.equals(command)) {
+ newOwnerDetails(url, ignore, metalake, entityName, entity).handle();
+ } else if (CommandActions.SET.equals(command)) {
+ String owner = line.getOptionValue(GravitinoOptions.USER);
+ String group = line.getOptionValue(GravitinoOptions.GROUP);
+
+ if (owner != null && group == null) {
+ newSetOwner(url, ignore, metalake, entityName, entity, owner,
false).handle();
+ } else if (owner == null && group != null) {
+ newSetOwner(url, ignore, metalake, entityName, entity, group,
true).handle();
+ } else {
+ System.err.println(ErrorMessages.INVALID_SET_COMMAND);
+ }
+ } else {
+ System.err.println(ErrorMessages.UNSUPPORTED_ACTION);
+ }
+ }
+
/**
* Retrieves the Gravitinno URL from the command line options or the
GRAVITINO_URL environment
* variable or the Gravitio config file.
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 8f017ba72..dd9fedd7a 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 OWNER = "owner";
public static final String ROLE = "role";
public static final String AUDIT = "audit";
public static final String INDEX = "index";
@@ -78,7 +79,8 @@ public class GravitinoOptions {
"z", PROVIDER, "provider one of hadoop, hive, mysql, postgres,
iceberg, kafka"));
options.addOption(createArgOption("l", USER, "user name"));
options.addOption(createArgOption("g", GROUP, "group name"));
- options.addOption(createArgsOption("t", TAG, "tag name"));
+ options.addOption(createArgOption("t", TAG, "tag name"));
+ options.addOption(createSimpleOption("o", OWNER, "entity owner"));
options.addOption(createArgOption("r", ROLE, "role name"));
// Properties option can have multiple values
diff --git a/clients/cli/src/main/java/org/apache/gravitino/cli/Main.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/Main.java
index 0d0eaddf7..e81362b20 100644
--- a/clients/cli/src/main/java/org/apache/gravitino/cli/Main.java
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/Main.java
@@ -25,7 +25,7 @@ import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
-/* Entry point for teh Gravitino command line. */
+/* Entry point for the Gravitino command line. */
public class Main {
public static void main(String[] args) {
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/TestableCommandLine.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/TestableCommandLine.java
index 9a4882b3a..94435160d 100644
---
a/clients/cli/src/main/java/org/apache/gravitino/cli/TestableCommandLine.java
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/TestableCommandLine.java
@@ -59,6 +59,7 @@ import org.apache.gravitino.cli.commands.ListTagProperties;
import org.apache.gravitino.cli.commands.ListUsers;
import org.apache.gravitino.cli.commands.MetalakeAudit;
import org.apache.gravitino.cli.commands.MetalakeDetails;
+import org.apache.gravitino.cli.commands.OwnerDetails;
import org.apache.gravitino.cli.commands.RemoveCatalogProperty;
import org.apache.gravitino.cli.commands.RemoveMetalakeProperty;
import org.apache.gravitino.cli.commands.RemoveRoleFromGroup;
@@ -71,6 +72,7 @@ import org.apache.gravitino.cli.commands.SchemaDetails;
import org.apache.gravitino.cli.commands.ServerVersion;
import org.apache.gravitino.cli.commands.SetCatalogProperty;
import org.apache.gravitino.cli.commands.SetMetalakeProperty;
+import org.apache.gravitino.cli.commands.SetOwner;
import org.apache.gravitino.cli.commands.SetSchemaProperty;
import org.apache.gravitino.cli.commands.SetTagProperty;
import org.apache.gravitino.cli.commands.TableAudit;
@@ -424,4 +426,20 @@ public class TestableCommandLine {
String url, boolean ignore, String metalake, String catalog, String
schema, String table) {
return new ListColumns(url, ignore, metalake, catalog, schema, table);
}
+
+ protected SetOwner newSetOwner(
+ String url,
+ boolean ignore,
+ String metalake,
+ String entity,
+ String entityType,
+ String owner,
+ boolean isGroup) {
+ return new SetOwner(url, ignore, metalake, entity, entityType, owner,
isGroup);
+ }
+
+ protected OwnerDetails newOwnerDetails(
+ String url, boolean ignore, String metalake, String entity, String
entityType) {
+ return new OwnerDetails(url, ignore, metalake, entity, entityType);
+ }
}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/OwnerDetails.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/OwnerDetails.java
new file mode 100644
index 000000000..52cb45572
--- /dev/null
+++
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/OwnerDetails.java
@@ -0,0 +1,94 @@
+/*
+ * 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.Optional;
+import org.apache.gravitino.MetadataObject;
+import org.apache.gravitino.MetadataObjects;
+import org.apache.gravitino.authorization.Owner;
+import org.apache.gravitino.cli.CommandEntities;
+import org.apache.gravitino.cli.ErrorMessages;
+import org.apache.gravitino.client.GravitinoClient;
+import org.apache.gravitino.exceptions.NoSuchMetadataObjectException;
+import org.apache.gravitino.exceptions.NoSuchMetalakeException;
+
+public class OwnerDetails extends Command {
+
+ protected final String metalake;
+ protected final String entity;
+ protected final MetadataObject.Type entityType;
+
+ /**
+ * Displays the owner of an entity.
+ *
+ * @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 entity The name of the entity.
+ * @param entityType The type entity.
+ */
+ public OwnerDetails(
+ String url, boolean ignoreVersions, String metalake, String entity,
String entityType) {
+ super(url, ignoreVersions);
+ this.metalake = metalake;
+ this.entity = entity;
+
+ if (entityType.equals(CommandEntities.METALAKE)) {
+ this.entityType = MetadataObject.Type.METALAKE;
+ } else if (entityType.equals(CommandEntities.CATALOG)) {
+ this.entityType = MetadataObject.Type.CATALOG;
+ } else if (entityType.equals(CommandEntities.SCHEMA)) {
+ this.entityType = MetadataObject.Type.SCHEMA;
+ } else if (entityType.equals(CommandEntities.TABLE)) {
+ this.entityType = MetadataObject.Type.TABLE;
+ } else if (entityType.equals(CommandEntities.COLUMN)) {
+ this.entityType = MetadataObject.Type.COLUMN;
+ } else {
+ this.entityType = null;
+ }
+ }
+
+ /** Displays the owner of an entity. */
+ @Override
+ public void handle() {
+ Optional<Owner> owner = null;
+ MetadataObject metadata = MetadataObjects.parse(entity, entityType);
+
+ try {
+ GravitinoClient client = buildClient(metalake);
+ owner = client.getOwner(metadata);
+ } catch (NoSuchMetalakeException err) {
+ System.err.println(ErrorMessages.UNKNOWN_METALAKE);
+ return;
+ } catch (NoSuchMetadataObjectException err) {
+ System.err.println(ErrorMessages.UNKNOWN_ENTITY);
+ return;
+ } catch (Exception exp) {
+ System.err.println(exp.getMessage());
+ return;
+ }
+
+ if (owner.isPresent()) {
+ System.out.println(owner.get().name());
+ } else {
+ System.out.println("No owner");
+ }
+ }
+}
diff --git
a/clients/cli/src/main/java/org/apache/gravitino/cli/commands/SetOwner.java
b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/SetOwner.java
new file mode 100644
index 000000000..b10d7eea6
--- /dev/null
+++ b/clients/cli/src/main/java/org/apache/gravitino/cli/commands/SetOwner.java
@@ -0,0 +1,101 @@
+/*
+ * 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.MetadataObject;
+import org.apache.gravitino.MetadataObjects;
+import org.apache.gravitino.authorization.Owner;
+import org.apache.gravitino.cli.CommandEntities;
+import org.apache.gravitino.cli.ErrorMessages;
+import org.apache.gravitino.client.GravitinoClient;
+import org.apache.gravitino.exceptions.NoSuchMetadataObjectException;
+import org.apache.gravitino.exceptions.NoSuchMetalakeException;
+
+public class SetOwner extends Command {
+
+ protected final String metalake;
+ protected final String entity;
+ protected final MetadataObject.Type entityType;
+ protected final String owner;
+ protected final boolean isGroup;
+
+ /**
+ * Sets the owner of an entity.
+ *
+ * @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 entity The name of the entity.
+ * @param entityType The type entity.
+ * @param owner The name of the new owner.
+ * @param isGroup True if the owner is a group, false if it is not.
+ */
+ public SetOwner(
+ String url,
+ boolean ignoreVersions,
+ String metalake,
+ String entity,
+ String entityType,
+ String owner,
+ boolean isGroup) {
+ super(url, ignoreVersions);
+ this.metalake = metalake;
+ this.entity = entity;
+ this.owner = owner;
+ this.isGroup = isGroup;
+
+ if (entityType.equals(CommandEntities.METALAKE)) {
+ this.entityType = MetadataObject.Type.METALAKE;
+ } else if (entityType.equals(CommandEntities.CATALOG)) {
+ this.entityType = MetadataObject.Type.CATALOG;
+ } else if (entityType.equals(CommandEntities.SCHEMA)) {
+ this.entityType = MetadataObject.Type.SCHEMA;
+ } else if (entityType.equals(CommandEntities.TABLE)) {
+ this.entityType = MetadataObject.Type.TABLE;
+ } else if (entityType.equals(CommandEntities.COLUMN)) {
+ this.entityType = MetadataObject.Type.COLUMN;
+ } else {
+ this.entityType = null;
+ }
+ }
+
+ /** Sets the owner of an entity. */
+ @Override
+ public void handle() {
+ MetadataObject metadata = MetadataObjects.parse(entity, entityType);
+ Owner.Type ownerType = isGroup ? Owner.Type.GROUP : Owner.Type.USER;
+
+ try {
+ GravitinoClient client = buildClient(metalake);
+ client.setOwner(metadata, owner, ownerType);
+ } catch (NoSuchMetalakeException err) {
+ System.err.println(ErrorMessages.UNKNOWN_METALAKE);
+ return;
+ } catch (NoSuchMetadataObjectException err) {
+ System.err.println(ErrorMessages.UNKNOWN_ENTITY);
+ return;
+ } catch (Exception exp) {
+ System.err.println(exp.getMessage());
+ return;
+ }
+
+ System.out.println("Set owner to " + owner);
+ }
+}
diff --git
a/clients/cli/src/test/java/org/apache/gravitino/cli/TestOwnerCommands.java
b/clients/cli/src/test/java/org/apache/gravitino/cli/TestOwnerCommands.java
new file mode 100644
index 000000000..0c2b2cf91
--- /dev/null
+++ b/clients/cli/src/test/java/org/apache/gravitino/cli/TestOwnerCommands.java
@@ -0,0 +1,122 @@
+/*
+ * 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;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Options;
+import org.apache.gravitino.cli.commands.OwnerDetails;
+import org.apache.gravitino.cli.commands.SetOwner;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+class TestOwnerCommands {
+ private CommandLine mockCommandLine;
+ private Options mockOptions;
+
+ @BeforeEach
+ void setUp() {
+ mockCommandLine = mock(CommandLine.class);
+ mockOptions = mock(Options.class);
+ }
+
+ @Test
+ void testSetOwnerUserCommand() {
+ SetOwner mockSetOwner = mock(SetOwner.class);
+
when(mockCommandLine.hasOption(GravitinoOptions.METALAKE)).thenReturn(true);
+
when(mockCommandLine.getOptionValue(GravitinoOptions.METALAKE)).thenReturn("metalake_demo");
+ when(mockCommandLine.hasOption(GravitinoOptions.NAME)).thenReturn(true);
+
when(mockCommandLine.getOptionValue(GravitinoOptions.NAME)).thenReturn("postgres");
+ when(mockCommandLine.hasOption(GravitinoOptions.USER)).thenReturn(true);
+
when(mockCommandLine.getOptionValue(GravitinoOptions.USER)).thenReturn("admin");
+ when(mockCommandLine.hasOption(GravitinoOptions.GROUP)).thenReturn(false);
+ when(mockCommandLine.hasOption(GravitinoOptions.OWNER)).thenReturn(true);
+ GravitinoCommandLine commandLine =
+ spy(
+ new GravitinoCommandLine(
+ mockCommandLine, mockOptions, CommandEntities.CATALOG,
CommandActions.SET));
+ doReturn(mockSetOwner)
+ .when(commandLine)
+ .newSetOwner(
+ GravitinoCommandLine.DEFAULT_URL,
+ false,
+ "metalake_demo",
+ "postgres",
+ "catalog",
+ "admin",
+ false);
+ commandLine.handleCommandLine();
+ verify(mockSetOwner).handle();
+ }
+
+ @Test
+ void testSetOwnerGroupCommand() {
+ SetOwner mockSetOwner = mock(SetOwner.class);
+
when(mockCommandLine.hasOption(GravitinoOptions.METALAKE)).thenReturn(true);
+
when(mockCommandLine.getOptionValue(GravitinoOptions.METALAKE)).thenReturn("metalake_demo");
+ when(mockCommandLine.hasOption(GravitinoOptions.NAME)).thenReturn(true);
+
when(mockCommandLine.getOptionValue(GravitinoOptions.NAME)).thenReturn("postgres");
+ when(mockCommandLine.hasOption(GravitinoOptions.GROUP)).thenReturn(true);
+
when(mockCommandLine.getOptionValue(GravitinoOptions.GROUP)).thenReturn("ITdept");
+ when(mockCommandLine.hasOption(GravitinoOptions.USER)).thenReturn(false);
+ when(mockCommandLine.hasOption(GravitinoOptions.OWNER)).thenReturn(true);
+ GravitinoCommandLine commandLine =
+ spy(
+ new GravitinoCommandLine(
+ mockCommandLine, mockOptions, CommandEntities.CATALOG,
CommandActions.SET));
+ doReturn(mockSetOwner)
+ .when(commandLine)
+ .newSetOwner(
+ GravitinoCommandLine.DEFAULT_URL,
+ false,
+ "metalake_demo",
+ "postgres",
+ "catalog",
+ "ITdept",
+ true);
+ commandLine.handleCommandLine();
+ verify(mockSetOwner).handle();
+ }
+
+ @Test
+ void testOwnerDetailsCommand() {
+ OwnerDetails mockOwnerDetails = mock(OwnerDetails.class);
+
when(mockCommandLine.hasOption(GravitinoOptions.METALAKE)).thenReturn(true);
+
when(mockCommandLine.getOptionValue(GravitinoOptions.METALAKE)).thenReturn("metalake_demo");
+ when(mockCommandLine.hasOption(GravitinoOptions.NAME)).thenReturn(true);
+
when(mockCommandLine.getOptionValue(GravitinoOptions.NAME)).thenReturn("postgres");
+ when(mockCommandLine.hasOption(GravitinoOptions.OWNER)).thenReturn(true);
+ GravitinoCommandLine commandLine =
+ spy(
+ new GravitinoCommandLine(
+ mockCommandLine, mockOptions, CommandEntities.CATALOG,
CommandActions.DETAILS));
+ doReturn(mockOwnerDetails)
+ .when(commandLine)
+ .newOwnerDetails(
+ GravitinoCommandLine.DEFAULT_URL, false, "metalake_demo",
"postgres", "catalog");
+ commandLine.handleCommandLine();
+ verify(mockOwnerDetails).handle();
+ }
+}
diff --git a/docs/cli.md b/docs/cli.md
index e37e92e10..dbbbca7cb 100644
--- a/docs/cli.md
+++ b/docs/cli.md
@@ -10,7 +10,7 @@ license: 'This software is licensed under the Apache License
version 2.'
This document provides guidance on managing metadata within Apache Gravitino
using the Command Line Interface (CLI). The CLI offers a terminal based
alternative to using code or the REST interface for metadata management.
-Currently, the CLI allows users to view metadata information for metalakes,
catalogs, schemas, and tables. Future updates will expand on these capabilities
to include roles, users, and tags.
+Currently, the CLI allows users to view metadata information for metalakes,
catalogs, schemas, tables, users groups and tags. Future updates will expand on
these capabilities to include roles, topics and filesets.
## Running the CLI
@@ -27,7 +27,8 @@ Or you use the `gcli.sh` script found in the
`clients/cli/bin/` directory to run
The general structure for running commands with the Gravitino CLI is `gcli
entity command [options]`.
```bash
- usage: gcli [metalake|catalog|schema|table|column]
[list|details|create|delete|update|set|remove|properties|revoke|grant] [options]
+ [options]
+ usage: gcli [metalake|catalog|schema|table|column|user|group|tag]
[list|details|create|delete|update|set|remove|properties|revoke|grant] [options]
Options
-a,--audit display audit information
-c,--comment <arg> entity comment
@@ -522,6 +523,26 @@ gcli tag update --tag tagA --rename newTag
gcli tag update --tag tagA --comment "new comment"
```
+### Owners commands
+
+#### List an owner
+
+```bash
+gcli catalog details --owner --name postgres
+```
+
+#### Set an owner to a user
+
+```bash
+gcli catalog set --owner --user admin --name postgres
+```
+
+#### Set an owner to a group
+
+```bash
+gcli catalog set --owner --group groupA --name postgres
+```
+
### Role commands
#### Display role details