blob: e362e74bc79adc518c1c20039271cf5443811907 [file] [log] [blame]
#
# 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.
#
import io
import unittest
from functools import reduce
from typing import List, Any, Callable, Dict, cast
from unittest.mock import patch, MagicMock
from apache_polaris.cli.command import Command
from apache_polaris.cli.command.policies import PoliciesCommand
from apache_polaris.cli.options.parser import Parser
from apache_polaris.sdk.management import PolarisDefaultApi
INVALID_ARGS = 2
class TestCliParsing(unittest.TestCase):
def test_invalid_commands(self) -> None:
with self.assertRaises(SystemExit) as cm:
Parser.parse(["not-real-command!", "list"])
self.assertEqual(cm.exception.code, INVALID_ARGS)
with self.assertRaises(SystemExit) as cm:
Parser.parse(["catalogs", "not-real-subcommand"])
self.assertEqual(cm.exception.code, INVALID_ARGS)
with self.assertRaises(SystemExit) as cm:
Parser.parse(["catalogs", "create"]) # missing required input
self.assertEqual(cm.exception.code, INVALID_ARGS)
with self.assertRaises(SystemExit) as cm:
Parser.parse(
["catalogs", "create", "catalog_name", "--type", "BANANA"]
) # invalid catalog type
self.assertEqual(cm.exception.code, INVALID_ARGS)
with self.assertRaises(SystemExit) as cm:
Parser.parse(
["catalogs", "create", "catalog_name", "--set-property", "foo=bar"]
) # can't use --set-property on create
self.assertEqual(cm.exception.code, INVALID_ARGS)
with self.assertRaises(SystemExit) as cm:
Parser.parse(["catalogs", "get", "catalog_name", "--fake-flag"])
self.assertEqual(cm.exception.code, INVALID_ARGS)
with self.assertRaises(SystemExit) as cm:
Parser.parse(
["catalogs", "update", "catalog_name", "--property", "foo=bar"]
)
self.assertEqual(cm.exception.code, INVALID_ARGS)
with self.assertRaises(SystemExit) as cm:
Parser.parse(
[
"catalogs",
"create",
"catalog_name",
"--type",
"EXTERNAL",
"--remote-url",
"gone",
]
) # remote-url deprecated
self.assertEqual(cm.exception.code, INVALID_ARGS)
with self.assertRaises(SystemExit) as cm:
Parser.parse(["principals", "create", "name", "--type", "bad"])
self.assertEqual(cm.exception.code, INVALID_ARGS)
with self.assertRaises(SystemExit) as cm:
Parser.parse(["principals", "update", "name", "--client-id", "something"])
self.assertEqual(cm.exception.code, INVALID_ARGS)
with self.assertRaises(SystemExit) as cm:
Parser.parse(
[
"privileges",
"catalog",
"--catalog",
"c",
"--catalog-role",
"r",
"privilege",
"grant",
]
)
self.assertEqual(cm.exception.code, INVALID_ARGS)
with self.assertRaises(SystemExit) as cm:
Parser.parse(
[
"privileges",
"--catalog",
"c",
"--catalog-role",
"r",
"catalog",
"grant",
"privilege",
"--namespace",
"unexpected!",
]
)
self.assertEqual(cm.exception.code, INVALID_ARGS)
def _check_usage_output(self, f: Callable[[], Any], needle: str = "usage:") -> None:
with (
patch("sys.stdout", new_callable=io.StringIO) as mock_stdout,
patch("sys.stderr", new_callable=io.StringIO),
):
with self.assertRaises(SystemExit) as cm:
f()
self.assertEqual(cm.exception.code, 0)
help_output = str(mock_stdout.getvalue())
self.assertIn("usage:", help_output)
print(help_output)
def test_usage(self) -> None:
self._check_usage_output(lambda: Parser.parse(["--help"]))
self._check_usage_output(lambda: Parser.parse(["catalogs", "--help"]))
self._check_usage_output(lambda: Parser.parse(["catalogs", "create", "--help"]))
self._check_usage_output(
lambda: Parser.parse(["catalogs", "create", "something", "--help"])
)
def test_extended_usage(self) -> None:
self._check_usage_output(
lambda: Parser._build_parser().parse_args(["--help"], "input:")
)
self._check_usage_output(
lambda: Parser._build_parser().parse_args(["catalogs", "--help"], "input:")
)
self._check_usage_output(
lambda: Parser._build_parser().parse_args(
["catalogs", "create", "--help"], "input:"
)
)
self._check_usage_output(
lambda: Parser._build_parser().parse_args(
["catalogs", "create", "c", "--help"], "input:"
)
)
self._check_usage_output(
lambda: Parser._build_parser().parse_args(
["privileges", "table", "grant", "--help"], "input:"
)
)
self._check_usage_output(
lambda: Parser.parse(["catalogs", "create", "something", "--help"]),
"input:",
)
def test_parsing_valid_commands(self) -> None:
Parser.parse(["catalogs", "create", "catalog_name"])
Parser.parse(["catalogs", "create", "catalog_name", "--type", "internal"])
Parser.parse(["catalogs", "create", "catalog_name", "--type", "INTERNAL"])
Parser.parse(["catalogs", "list"])
Parser.parse(["catalogs", "get", "catalog_name"])
Parser.parse(["principals", "list"])
Parser.parse(["--host", "some-host", "catalogs", "list"])
Parser.parse(
["--base-url", "https://customservice.com/subpath", "catalogs", "list"]
)
Parser.parse(
[
"privileges",
"catalog",
"grant",
"--catalog",
"foo",
"--catalog-role",
"bar",
"TABLE_READ_DATA",
]
)
Parser.parse(
[
"privileges",
"table",
"grant",
"--catalog",
"foo",
"--catalog-role",
"bar",
"--namespace",
"n",
"--table",
"t",
"TABLE_READ_DATA",
]
)
Parser.parse(
[
"privileges",
"table",
"revoke",
"--catalog",
"foo",
"--catalog-role",
"bar",
"--namespace",
"n",
"--table",
"t",
"TABLE_READ_DATA",
]
)
# These commands are valid for parsing, but may cause errors within the command itself
def test_parse_argparse_valid_commands(self) -> None:
Parser.parse(["catalogs", "create", "catalog_name", "--type", "internal"])
Parser.parse(
[
"privileges",
"table",
"grant",
"--namespace",
"n",
"--table",
"t",
"TABLE_READ_DATA",
]
)
Parser.parse(
[
"privileges",
"catalog",
"grant",
"--catalog",
"c",
"--catalog-role",
"r",
"fake-privilege",
]
)
def test_commands(self) -> None:
def build_mock_client() -> MagicMock:
client = MagicMock(spec=PolarisDefaultApi)
client.call_tracker = dict()
def capture_method(method_name: str) -> Callable[..., None]:
def _capture(*args: Any, **kwargs: Any) -> None:
client.call_tracker["_method"] = method_name
for i, arg in enumerate(args):
client.call_tracker[i] = arg
return _capture
for method_name in dir(client):
if callable(
getattr(client, method_name)
) and not method_name.startswith("__"):
setattr(
client,
method_name,
MagicMock(
name=method_name, side_effect=capture_method(method_name)
),
)
return client
mock_client = build_mock_client()
def mock_execute(input: List[str]) -> Dict[Any, Any]:
mock_client.call_tracker = dict()
# Assuming Parser and Command are used to parse input and generate commands
options = Parser.parse(input)
command = Command.from_options(options)
try:
command.execute(mock_client)
except AttributeError as e:
# Some commands may fail due to the mock, but the results should still match expectations
print(f"Suppressed error: {e}")
return mock_client.call_tracker
def check_exception(f: Callable[[], Any], exception_str: str) -> None:
throws = True
try:
f()
throws = False
except Exception as e:
self.assertIn(exception_str, str(e))
self.assertTrue(throws, "Exception should be raised")
def check_arguments(
result: Dict[Any, Any], method_name: str, args: Dict[Any, Any] = {}
) -> None:
self.assertEqual(method_name, result["_method"])
def get(obj: Any, arg_string: str) -> Any:
attributes = arg_string.split(".")
return reduce(getattr, attributes, obj)
for arg, value in args.items():
index, path = arg
if path is not None:
self.assertEqual(value, get(result[index], path))
else:
self.assertEqual(value, result[index])
# Test various failing commands:
check_exception(
lambda: mock_execute(["catalogs", "create", "my-catalog"]), "--storage-type"
)
check_exception(
lambda: mock_execute(
["catalogs", "create", "my-catalog", "--storage-type", "gcs"]
),
"--default-base-location",
)
check_exception(
lambda: mock_execute(["catalog-roles", "get", "foo"]), "--catalog"
)
check_exception(
lambda: mock_execute(
["catalogs", "update", "foo", "--set-property", "bad-format"]
),
"bad-format",
)
check_exception(
lambda: mock_execute(
[
"privileges",
"catalog",
"grant",
"--catalog",
"foo",
"--catalog-role",
"bar",
"TABLE_READ_MORE_BOOKS",
]
),
"catalog privilege: TABLE_READ_MORE_BOOKS",
)
check_exception(
lambda: mock_execute(
[
"catalogs",
"create",
"my-catalog",
"--storage-type",
"gcs",
"--allowed-location",
"a",
"--allowed-location",
"b",
"--role-arn",
"ra",
"--default-base-location",
"x",
]
),
"gcs",
)
check_exception(
lambda: mock_execute(
[
"catalogs",
"create",
"my-catalog",
"--type",
"external",
"--storage-type",
"file",
"--default-base-location",
"dbl",
"--catalog-connection-type",
"hive",
"--catalog-authentication-type",
"implicit",
]
),
"--hive-warehouse",
)
# Test various correct commands:
check_arguments(
mock_execute(
[
"catalogs",
"create",
"my-catalog",
"--storage-type",
"gcs",
"--default-base-location",
"x",
]
),
"create_catalog",
{
(0, "catalog.name"): "my-catalog",
(0, "catalog.storage_config_info.storage_type"): "GCS",
(0, "catalog.properties.default_base_location"): "x",
},
)
check_arguments(
mock_execute(
[
"catalogs",
"create",
"my-catalog",
"--type",
"external",
"--storage-type",
"gcs",
"--default-base-location",
"dbl",
]
),
"create_catalog",
{
(0, "catalog.name"): "my-catalog",
(0, "catalog.type"): "EXTERNAL",
},
)
check_arguments(
mock_execute(
[
"catalogs",
"create",
"my-catalog",
"--storage-type",
"s3",
"--allowed-location",
"a",
"--allowed-location",
"b",
"--role-arn",
"ra",
"--external-id",
"ei",
"--default-base-location",
"x",
]
),
"create_catalog",
{
(0, "catalog.name"): "my-catalog",
(0, "catalog.storage_config_info.storage_type"): "S3",
(0, "catalog.properties.default_base_location"): "x",
(0, "catalog.storage_config_info.allowed_locations"): ["a", "b"],
},
)
check_arguments(
mock_execute(
[
"catalogs",
"create",
"my-catalog",
"--storage-type",
"s3",
"--allowed-location",
"a",
"--role-arn",
"ra",
"--region",
"us-west-2",
"--external-id",
"ei",
"--default-base-location",
"x",
]
),
"create_catalog",
{
(0, "catalog.name"): "my-catalog",
(0, "catalog.storage_config_info.storage_type"): "S3",
(0, "catalog.properties.default_base_location"): "x",
(0, "catalog.storage_config_info.allowed_locations"): ["a"],
(0, "catalog.storage_config_info.region"): "us-west-2",
},
)
check_arguments(
mock_execute(
[
"catalogs",
"create",
"my-catalog",
"--storage-type",
"gcs",
"--allowed-location",
"a",
"--allowed-location",
"b",
"--service-account",
"sa",
"--default-base-location",
"x",
]
),
"create_catalog",
{
(0, "catalog.name"): "my-catalog",
(0, "catalog.storage_config_info.storage_type"): "GCS",
(0, "catalog.properties.default_base_location"): "x",
(0, "catalog.storage_config_info.allowed_locations"): ["a", "b"],
(0, "catalog.storage_config_info.gcs_service_account"): "sa",
},
)
check_arguments(mock_execute(["catalogs", "list"]), "list_catalogs")
check_arguments(
mock_execute(
["--base-url", "https://customservice.com/subpath", "catalogs", "list"]
),
"list_catalogs",
)
check_arguments(
mock_execute(["catalogs", "delete", "foo"]),
"delete_catalog",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(["catalogs", "get", "foo"]),
"get_catalog",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(["catalogs", "update", "foo", "--default-base-location", "x"]),
"get_catalog",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(["catalogs", "update", "foo", "--set-property", "key=value"]),
"get_catalog",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(
["catalogs", "update", "foo", "--set-property", "listkey=k1=v1,k2=v2"]
),
"get_catalog",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(["catalogs", "update", "foo", "--remove-property", "key"]),
"get_catalog",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(
[
"catalogs",
"update",
"foo",
"--set-property",
"key=value",
"--default-base-location",
"x",
]
),
"get_catalog",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(
[
"catalogs",
"update",
"foo",
"--set-property",
"key=value",
"--default-base-location",
"x",
"--region",
"us-west-1",
]
),
"get_catalog",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(["principals", "create", "foo", "--property", "key=value"]),
"create_principal",
{
(0, "principal.name"): "foo",
(0, "principal.client_id"): None,
(0, "principal.properties"): {"key": "value"},
},
)
check_arguments(
mock_execute(["principals", "delete", "foo"]),
"delete_principal",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(["principals", "get", "foo"]),
"get_principal",
{
(0, None): "foo",
},
)
check_arguments(mock_execute(["principals", "list"]), "list_principals")
check_arguments(
mock_execute(["principals", "rotate-credentials", "foo"]),
"rotate_credentials",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(
["principals", "update", "foo", "--set-property", "key=value"]
),
"get_principal",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(["principals", "update", "foo", "--remove-property", "key"]),
"get_principal",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(["principal-roles", "create", "foo"]),
"create_principal_role",
{
(0, "principal_role.name"): "foo",
},
)
check_arguments(
mock_execute(["principal-roles", "delete", "foo"]),
"delete_principal_role",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(["principal-roles", "delete", "foo"]),
"delete_principal_role",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(["principal-roles", "get", "foo"]),
"get_principal_role",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(["principal-roles", "get", "foo"]),
"get_principal_role",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(["principal-roles", "list"]), "list_principal_roles"
)
check_arguments(
mock_execute(["principal-roles", "list", "--principal", "foo"]),
"list_principal_roles_assigned",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(
["principal-roles", "update", "foo", "--set-property", "key=value"]
),
"get_principal_role",
{(0, None): "foo"},
)
check_arguments(
mock_execute(
["principal-roles", "update", "foo", "--remove-property", "key"]
),
"get_principal_role",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(["principal-roles", "grant", "bar", "--principal", "foo"]),
"assign_principal_role",
{
(0, None): "foo",
(1, "principal_role.name"): "bar",
},
)
check_arguments(
mock_execute(["principal-roles", "revoke", "bar", "--principal", "foo"]),
"revoke_principal_role",
{
(0, None): "foo",
(1, None): "bar",
},
)
check_arguments(
mock_execute(
[
"catalog-roles",
"create",
"foo",
"--catalog",
"bar",
"--property",
"key=value",
]
),
"create_catalog_role",
{
(0, None): "bar",
(1, "catalog_role.name"): "foo",
(1, "catalog_role.properties"): {"key": "value"},
},
)
check_arguments(
mock_execute(["catalog-roles", "delete", "foo", "--catalog", "bar"]),
"delete_catalog_role",
{
(0, None): "bar",
(1, None): "foo",
},
)
check_arguments(
mock_execute(["catalog-roles", "get", "foo", "--catalog", "bar"]),
"get_catalog_role",
{
(0, None): "bar",
(1, None): "foo",
},
)
check_arguments(
mock_execute(["catalog-roles", "list", "foo"]),
"list_catalog_roles",
{
(0, None): "foo",
},
)
check_arguments(
mock_execute(["catalog-roles", "list", "foo", "--principal-role", "bar"]),
"list_catalog_roles_for_principal_role",
{
(0, None): "bar",
(1, None): "foo",
},
)
check_arguments(
mock_execute(
[
"catalog-roles",
"update",
"foo",
"--catalog",
"bar",
"--set-property",
"key=value",
]
),
"get_catalog_role",
{
(0, None): "bar",
(1, None): "foo",
},
)
check_arguments(
mock_execute(
[
"catalog-roles",
"update",
"foo",
"--catalog",
"bar",
"--remove-property",
"key",
]
),
"get_catalog_role",
{
(0, None): "bar",
(1, None): "foo",
},
)
check_arguments(
mock_execute(
[
"catalog-roles",
"grant",
"--principal-role",
"foo",
"--catalog",
"bar",
"baz",
]
),
"assign_catalog_role_to_principal_role",
{
(0, None): "foo",
(1, None): "bar",
(2, "catalog_role.name"): "baz",
},
)
check_arguments(
mock_execute(
[
"catalog-roles",
"revoke",
"--principal-role",
"foo",
"--catalog",
"bar",
"baz",
]
),
"revoke_catalog_role_from_principal_role",
{
(0, None): "foo",
(1, None): "bar",
(2, None): "baz",
},
)
check_arguments(
mock_execute(
[
"privileges",
"catalog",
"grant",
"--catalog",
"foo",
"--catalog-role",
"bar",
"TABLE_READ_DATA",
]
),
"add_grant_to_catalog_role",
{
(0, None): "foo",
(1, None): "bar",
(2, "grant.privilege.value"): "TABLE_READ_DATA",
},
)
check_arguments(
mock_execute(
[
"privileges",
"catalog",
"revoke",
"--catalog",
"foo",
"--catalog-role",
"bar",
"TABLE_READ_DATA",
]
),
"revoke_grant_from_catalog_role",
{
(0, None): "foo",
(1, None): "bar",
(2, None): False,
(3, "grant.privilege.value"): "TABLE_READ_DATA",
},
)
check_arguments(
mock_execute(
[
"privileges",
"namespace",
"grant",
"--namespace",
"a.b.c",
"--catalog",
"foo",
"--catalog-role",
"bar",
"TABLE_READ_DATA",
]
),
"add_grant_to_catalog_role",
{
(0, None): "foo",
(1, None): "bar",
(2, "grant.privilege.value"): "TABLE_READ_DATA",
(2, "grant.namespace"): ["a", "b", "c"],
},
)
check_arguments(
mock_execute(
[
"privileges",
"table",
"grant",
"--namespace",
"a.b.c",
"--table",
"t",
"--catalog",
"foo",
"--catalog-role",
"bar",
"TABLE_READ_DATA",
]
),
"add_grant_to_catalog_role",
{
(0, None): "foo",
(1, None): "bar",
(2, "grant.privilege.value"): "TABLE_READ_DATA",
(2, "grant.namespace"): ["a", "b", "c"],
(2, "grant.table_name"): "t",
},
)
check_arguments(
mock_execute(
[
"privileges",
"table",
"revoke",
"--namespace",
"a.b.c",
"--catalog",
"foo",
"--catalog-role",
"bar",
"--table",
"t",
"--cascade",
"TABLE_READ_DATA",
]
),
"revoke_grant_from_catalog_role",
{
(0, None): "foo",
(1, None): "bar",
(2, None): True,
(3, "grant.privilege.value"): "TABLE_READ_DATA",
(3, "grant.namespace"): ["a", "b", "c"],
(3, "grant.table_name"): "t",
},
)
check_arguments(
mock_execute(
[
"privileges",
"view",
"grant",
"--namespace",
"a.b.c",
"--catalog",
"foo",
"--catalog-role",
"bar",
"--view",
"v",
"VIEW_FULL_METADATA",
]
),
"add_grant_to_catalog_role",
{
(0, None): "foo",
(1, None): "bar",
(2, "grant.privilege.value"): "VIEW_FULL_METADATA",
(2, "grant.namespace"): ["a", "b", "c"],
(2, "grant.view_name"): "v",
},
)
check_arguments(
mock_execute(
[
"catalogs",
"create",
"my-catalog",
"--type",
"external",
"--storage-type",
"gcs",
"--default-base-location",
"dbl",
"--catalog-connection-type",
"iceberg-rest",
"--iceberg-remote-catalog-name",
"i",
"--catalog-uri",
"u",
"--catalog-authentication-type",
"bearer",
"--catalog-bearer-token",
"b",
]
),
"create_catalog",
{
(0, "catalog.name"): "my-catalog",
(0, "catalog.type"): "EXTERNAL",
(0, "catalog.connection_config_info.connection_type"): "ICEBERG_REST",
(0, "catalog.connection_config_info.remote_catalog_name"): "i",
(0, "catalog.connection_config_info.uri"): "u",
},
)
check_arguments(
mock_execute(
[
"catalogs",
"create",
"my-catalog",
"--type",
"external",
"--storage-type",
"gcs",
"--default-base-location",
"dbl",
"--catalog-connection-type",
"iceberg-rest",
"--iceberg-remote-catalog-name",
"c",
"--catalog-uri",
"u",
"--catalog-authentication-type",
"oauth",
"--catalog-token-uri",
"u",
"--catalog-client-id",
"i",
"--catalog-client-secret",
"k",
"--catalog-client-scope",
"s1",
"--catalog-client-scope",
"s2",
]
),
"create_catalog",
{
(0, "catalog.name"): "my-catalog",
(0, "catalog.type"): "EXTERNAL",
(0, "catalog.connection_config_info.connection_type"): "ICEBERG_REST",
(0, "catalog.connection_config_info.remote_catalog_name"): "c",
(0, "catalog.connection_config_info.uri"): "u",
(
0,
"catalog.connection_config_info.authentication_parameters.authentication_type",
): "OAUTH",
(
0,
"catalog.connection_config_info.authentication_parameters.token_uri",
): "u",
(
0,
"catalog.connection_config_info.authentication_parameters.client_id",
): "i",
(
0,
"catalog.connection_config_info.authentication_parameters.scopes",
): ["s1", "s2"],
(0, "catalog.storage_config_info.storage_type"): "GCS",
(0, "catalog.properties.default_base_location"): "dbl",
},
)
check_arguments(
mock_execute(
[
"catalogs",
"create",
"my-catalog",
"--type",
"external",
"--storage-type",
"gcs",
"--default-base-location",
"dbl",
"--catalog-connection-type",
"iceberg-rest",
"--iceberg-remote-catalog-name",
"i",
"--catalog-uri",
"u",
"--catalog-authentication-type",
"sigv4",
"--catalog-role-arn",
"a",
"--catalog-signing-region",
"s",
]
),
"create_catalog",
{
(0, "catalog.name"): "my-catalog",
(0, "catalog.type"): "EXTERNAL",
(0, "catalog.connection_config_info.connection_type"): "ICEBERG_REST",
(0, "catalog.connection_config_info.remote_catalog_name"): "i",
(0, "catalog.connection_config_info.uri"): "u",
(
0,
"catalog.connection_config_info.authentication_parameters.role_arn",
): "a",
(
0,
"catalog.connection_config_info.authentication_parameters.signing_region",
): "s",
},
)
check_arguments(
mock_execute(
[
"catalogs",
"create",
"my-catalog",
"--type",
"external",
"--storage-type",
"gcs",
"--default-base-location",
"dbl",
"--catalog-connection-type",
"iceberg-rest",
"--iceberg-remote-catalog-name",
"i",
"--catalog-uri",
"u",
"--catalog-authentication-type",
"sigv4",
"--catalog-role-arn",
"a",
"--catalog-signing-region",
"s",
"--catalog-role-session-name",
"n",
"--catalog-external-id",
"i",
"--catalog-signing-name",
"g",
]
),
"create_catalog",
{
(0, "catalog.name"): "my-catalog",
(0, "catalog.type"): "EXTERNAL",
(0, "catalog.connection_config_info.connection_type"): "ICEBERG_REST",
(0, "catalog.connection_config_info.remote_catalog_name"): "i",
(0, "catalog.connection_config_info.uri"): "u",
(
0,
"catalog.connection_config_info.authentication_parameters.role_arn",
): "a",
(
0,
"catalog.connection_config_info.authentication_parameters.signing_region",
): "s",
(
0,
"catalog.connection_config_info.authentication_parameters.role_session_name",
): "n",
(
0,
"catalog.connection_config_info.authentication_parameters.external_id",
): "i",
(
0,
"catalog.connection_config_info.authentication_parameters.signing_name",
): "g",
},
)
check_arguments(
mock_execute(
[
"catalogs",
"create",
"my-catalog",
"--type",
"external",
"--storage-type",
"file",
"--default-base-location",
"dbl",
"--catalog-connection-type",
"hadoop",
"--hadoop-warehouse",
"h",
"--catalog-authentication-type",
"implicit",
"--catalog-uri",
"u",
]
),
"create_catalog",
{
(0, "catalog.name"): "my-catalog",
(0, "catalog.type"): "EXTERNAL",
(0, "catalog.connection_config_info.connection_type"): "HADOOP",
(0, "catalog.connection_config_info.warehouse"): "h",
(
0,
"catalog.connection_config_info.authentication_parameters.authentication_type",
): "IMPLICIT",
(0, "catalog.connection_config_info.uri"): "u",
},
)
check_arguments(
mock_execute(
[
"catalogs",
"create",
"my-catalog",
"--type",
"external",
"--storage-type",
"file",
"--default-base-location",
"dbl",
"--catalog-connection-type",
"hive",
"--hive-warehouse",
"h",
"--catalog-authentication-type",
"implicit",
"--catalog-uri",
"u",
]
),
"create_catalog",
{
(0, "catalog.name"): "my-catalog",
(0, "catalog.type"): "EXTERNAL",
(0, "catalog.connection_config_info.connection_type"): "HIVE",
(0, "catalog.connection_config_info.warehouse"): "h",
(
0,
"catalog.connection_config_info.authentication_parameters.authentication_type",
): "IMPLICIT",
(0, "catalog.connection_config_info.uri"): "u",
},
)
check_arguments(
mock_execute(
[
"catalogs",
"create",
"my-catalog",
"--type",
"external",
"--storage-type",
"file",
"--default-base-location",
"dbl",
"--catalog-connection-type",
"hive",
"--hive-warehouse",
"/warehouse/path",
"--catalog-authentication-type",
"oauth",
"--catalog-uri",
"thrift://hive-metastore:9083",
"--catalog-token-uri",
"http://auth-server/token",
"--catalog-client-id",
"test-client",
"--catalog-client-secret",
"test-secret",
"--catalog-client-scope",
"read",
"--catalog-client-scope",
"write",
]
),
"create_catalog",
{
(0, "catalog.name"): "my-catalog",
(0, "catalog.type"): "EXTERNAL",
(0, "catalog.connection_config_info.connection_type"): "HIVE",
(0, "catalog.connection_config_info.warehouse"): "/warehouse/path",
(
0,
"catalog.connection_config_info.authentication_parameters.authentication_type",
): "OAUTH",
(
0,
"catalog.connection_config_info.uri",
): "thrift://hive-metastore:9083",
},
)
check_arguments(
mock_execute(
[
"principals",
"reset",
"test",
"--new-client-id",
"e469c048cf866df1",
"--new-client-secret",
"e469c048cf866dfae469c048cf866df1",
]
),
"reset_credentials",
{
(0, None): "test",
(1, "client_id"): "e469c048cf866df1",
(1, "client_secret"): "e469c048cf866dfae469c048cf866df1",
},
)
check_arguments(
mock_execute(["principals", "reset", "test"]),
"reset_credentials",
{
(0, None): "test",
(1, None): None,
},
)
check_arguments(
mock_execute(
["principals", "reset", "test", "--new-client-id", "e469c048cf866df1"]
),
"reset_credentials",
{
(0, None): "test",
(1, "client_id"): "e469c048cf866df1",
(1, "client_secret"): None,
},
)
check_arguments(
mock_execute(
[
"principals",
"reset",
"test",
"--new-client-secret",
"e469c048cf866dfae469c048cf866df1",
]
),
"reset_credentials",
{
(0, None): "test",
(1, "client_id"): None,
(1, "client_secret"): "e469c048cf866dfae469c048cf866df1",
},
)
def test_policies_attach_parameters_parsed_to_dict(self) -> None:
options = Parser.parse(
[
"policies",
"attach",
"policy-name",
"--catalog",
"cat",
"--attachment-type",
"catalog",
"--parameters",
"key=value",
]
)
command = Command.from_options(options)
command = cast(PoliciesCommand, command)
self.assertIsInstance(command.parameters, dict)
self.assertEqual({"key": "value"}, command.parameters)
if __name__ == "__main__":
unittest.main()