Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add commands in arlas cli #67

Merged
merged 5 commits into from
Feb 20, 2025
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion arlas/cli/configurations.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,4 @@ def describe_configuration(
if Configuration.settings.arlas.get(config, None) is None:
print("Error: arlas configuration {} not found among [{}]".format(config, ", ".join(Configuration.settings.arlas.keys())), file=sys.stderr)
exit(1)
print(yaml.dump(Configuration.settings.arlas[config].model_dump()))
print(yaml.dump(Configuration.settings.arlas[config].model_dump()))
74 changes: 72 additions & 2 deletions arlas/cli/org.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import sys
import typer
from prettytable import PrettyTable

from arlas.cli.service import Service
from arlas.cli.settings import Configuration
from arlas.cli.variables import variables

org = typer.Typer()
Expand All @@ -18,9 +20,12 @@ def list_organisations():


@org.command(help="Create organisation with the given name", name="add", epilog=variables["help_epilog"])
def create_organisation(organisation: str = typer.Argument(help="Organisation's name")):
def create_organisation(organisation: str = typer.Argument(default="", help="Organisation's name")):
config = variables["arlas"]
print(Service.create_organisation(config, organisation).get("id"))
if organisation:
print(Service.create_organisation(config, organisation).get("id"))
else:
print(Service.create_organisation_from_user_domain(config, organisation).get("id"))


@org.command(help="Delete the organisation", name="delete", epilog=variables["help_epilog"])
Expand Down Expand Up @@ -148,3 +153,68 @@ def delete_user_from_group(org_id: str = typer.Argument(help="Organisation's ide
group_id: str = typer.Argument(help="Group identifier")):
config = variables["arlas"]
print(Service.delete_permission_from_group_in_organisation(config, org_id, user_id, group_id))


@org.command(help="Add and returns an new API Key with permissions associated to provided groups. Use the key id and key secret with the arlas-api-key-id and arlas-api-key-secret headers.", name="add-apikey",
epilog=variables["help_epilog"])
def add_apikey(org_id: str = typer.Argument(help="Organisation's identifier"),
name: str = typer.Argument(help="API Key name"),
user_id: str = typer.Option(help="User identifier", default=None),
ttlInDays: int = typer.Option(help="Time To Live in days", default=365),
gids: list[str] = typer.Option(help="Group identifiers. If not provided, all groups of the user are used.", default=None)
):
config = variables["arlas"]
if not gids or len(gids) == 0:
gids = list(map(lambda arr: arr[0], Service.list_organisation_groups(config, org_id) + Service.list_organisation_roles(config, org_id)))
print(Service.create_api_key(config, org_id, name, ttlInDays, __solve_user_id__(config, org_id, user_id), gids))


@org.command(help="Delete an API Key", name="delete-apikey",
epilog=variables["help_epilog"])
def delete_apikey(org_id: str = typer.Argument(help="Organisation's identifier"),
key_id: str = typer.Argument(help="API Key identifier"),
user_id: str = typer.Option(help="User identifier", default=None),
):
config = variables["arlas"]
print(Service.delete_api_key(config, org_id, __solve_user_id__(config, org_id, user_id), key_id))


def __solve_user_id__(config: str, org_id: str, user_id: str):
if not user_id:
if Configuration.settings.arlas.get(config) and Configuration.settings.arlas.get(config).authorization and Configuration.settings.arlas.get(config).authorization.token_url and Configuration.settings.arlas.get(config).authorization.token_url.login:
user_id = Service.get_user_from_organisation(config, org_id, Configuration.settings.arlas.get(config).authorization.token_url.login)[0]
if not user_id:
print("Error : user id not found for {}.".format(config), file=sys.stderr)
sys.exit(1)
else:
print("Error : no login found for {}.".format(config), file=sys.stderr)
sys.exit(1)
return user_id


@org.command(help="Check if user's organisation exists", name="check",
epilog=variables["help_epilog"])
def check():
config = variables["arlas"]
print(Service.check_organisation(config))


@org.command(help="List forbidden organisations.", name="forbidden",
epilog=variables["help_epilog"])
def forbidden():
config = variables["arlas"]
print(Service.forbidden_organisation(config))


@org.command(help="Forbid an organisation name.", name="forbid",
epilog=variables["help_epilog"])
def forbid(name: str = typer.Argument(help="Name of the organisation to forbid")):
config = variables["arlas"]
print(Service.forbid_organisation(config, name))


@org.command(help="Remove an organisation name from the forbidden list.", name="authorize",
epilog=variables["help_epilog"])
def authorize(name: str = typer.Argument(help="Name of the organisation to authorize")):
config = variables["arlas"]
print(Service.authorize_organisation(config, name))
53 changes: 52 additions & 1 deletion arlas/cli/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,23 @@ def test_es(arlas: str):
def create_user(arlas: str, email: str):
return Service.__arlas__(arlas, "users", post=json.dumps({"email": email}), service=Services.iam)

def describe_user(arlas: str, id: str):
return Service.__arlas__(arlas, "/".join(["users", id]), service=Services.iam)

def update_user(arlas: str, id: str, oldPassword: str = None, newPassword: str = None, locale: str = None, timezone: str = None, firstName: str = None, lastName: str = None):
data = {"oldPassword": oldPassword}
if newPassword:
data["newPassword"] = newPassword
if locale:
data["locale"] = locale
if timezone:
data["timezone"] = timezone
if firstName:
data["firstName"] = firstName
if lastName:
data["lastName"] = lastName
return Service.__arlas__(arlas, "/".join(["users", id]), put=json.dumps(data), service=Services.iam)

def delete_user(arlas: str, id: str):
return Service.__arlas__(arlas, "/".join(["users", id]), delete=True, service=Services.iam)

Expand All @@ -67,6 +84,9 @@ def activate(arlas: str, id: str):
def deactivate(arlas: str, id: str):
return Service.__arlas__(arlas, "/".join(["users", id, "deactivate"]), post="{}", service=Services.iam)

def reset_password(arlas: str, email: str):
return Service.__arlas__(arlas, "/".join(["users", "resetpassword"]), post=email, service=Services.iam)

def list_organisations(arlas: str) -> list[list[str]]:
data = Service.__arlas__(arlas, "organisations", service=Services.iam)
table = [["id", "name", "Am I owner?"]]
Expand All @@ -81,8 +101,11 @@ def list_organisations(arlas: str) -> list[list[str]]:
def create_organisation(arlas: str, org: str):
return Service.__arlas__(arlas, "/".join(["organisations", org]), post="{}", service=Services.iam)

def create_organisation_from_user_domain(arlas: str, org: str):
return Service.__arlas__(arlas, "organisations", post="{}", service=Services.iam)

def delete_organisation(arlas: str, oid: str):
return Service.__arlas__(arlas, "/".join(["organisations", oid]), delete="{}", service=Services.iam)
return Service.__arlas__(arlas, "/".join(["organisations", oid]), delete=True, service=Services.iam)

def list_organisation_collections(arlas: str, oid: str):
return Service.__arlas__(arlas, "/".join(["organisations", oid, "collections"]), service=Services.iam)
Expand All @@ -95,6 +118,16 @@ def list_organisation_users(arlas: str, oid: str):
"\n".join(list(map(lambda role: role.get("fullName"), user.get("member").get("roles"))))],
users))

def get_user_from_organisation(arlas: str, oid: str, user: str):
users: list = Service.__arlas__(arlas, "/".join(["organisations", oid, "users"]), service=Services.iam)
users: list = list(filter(lambda u: u.get("member").get("email") == user, users))
if len(users) > 0:
return list(map(lambda user: [user.get("member").get("id"),
user.get("member").get("email"),
user.get("isOwner"),
"\n".join(list(map(lambda role: role.get("fullName"), user.get("member").get("roles"))))], users))[0]
return None

def list_organisation_groups(arlas: str, oid: str):
groups: list = Service.__arlas__(arlas, "/".join(["organisations", oid, "groups"]), service=Services.iam)
return list(map(lambda user: [user.get("id"),
Expand Down Expand Up @@ -407,6 +440,24 @@ def persistence_describe(arlas: str, id: str):
table.append(["writers", ", ".join(r.get("doc_writers", []))])
return table

def create_api_key(arlas: str, oid: str, name: str, ttlInDays: int, uid: str, gids: list[str]):
return Service.__arlas__(arlas, "/".join(["organisations", oid, "users", uid, "apikeys"]), post=json.dumps({"name": name, "ttlInDays": ttlInDays, "roleIds": gids}), service=Services.iam)

def delete_api_key(arlas: str, oid: str, uid: str, keyid: str):
return Service.__arlas__(arlas, "/".join(["organisations", oid, "users", uid, "apikeys", keyid]), delete=True, service=Services.iam)

def check_organisation(arlas: str):
return Service.__arlas__(arlas, "/".join(["organisations", "check"]), service=Services.iam)

def forbidden_organisation(arlas: str):
return Service.__arlas__(arlas, "/".join(["organisations", "forbidden"]), service=Services.iam)

def forbid_organisation(arlas: str, name: str):
return Service.__arlas__(arlas, "/".join(["organisations", "forbidden"]), post=json.dumps({"name": name}), service=Services.iam)

def authorize_organisation(arlas: str, name: str):
return Service.__arlas__(arlas, "/".join(["organisations", "forbidden", name]), delete=True, service=Services.iam)

def __index_bulk__(arlas: str, index: str, bulk: []):
data = os.linesep.join([json.dumps(line) for line in bulk]) + os.linesep
result = json.loads(Service.__es__(arlas, "/".join([index, "_bulk"]), post=data, exit_on_failure=False, headers={"Content-Type": "application/x-ndjson"}))
Expand Down
25 changes: 25 additions & 0 deletions arlas/cli/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,25 @@ def add(email: str = typer.Argument(help="User's email")):
print(Service.create_user(config, email).get("id"))


@user.command(help="Describe user", name="describe", epilog=variables["help_epilog"])
def describe(uid: str = typer.Argument(help="User's identifier")):
config = variables["arlas"]
print(Service.describe_user(config, uid))


@user.command(help="Update user", name="update", epilog=variables["help_epilog"])
def update(uid: str = typer.Argument(help="User's identifier"),
oldPassword: str = typer.Option(help="Old password", default=None),
newPassword: str = typer.Option(help="New password", default=None),
locale: str = typer.Option(help="Locale", default=None),
timezone: str = typer.Option(help="Timezone", default=None),
firstname: str = typer.Option(help="Firstname", default=None),
lastname: str = typer.Option(help="Lastname", default=None)
):
config = variables["arlas"]
print(Service.update_user(config, uid, oldPassword, newPassword, locale, timezone, firstname, lastname))


@user.command(help="Delete user", name="delete", epilog=variables["help_epilog"])
def delete(id: str = typer.Argument(help="User's identifier")):
config = variables["arlas"]
Expand All @@ -28,3 +47,9 @@ def activate(id: str = typer.Argument(help="User's identifier")):
def deactivate(id: str = typer.Argument(help="User's identifier")):
config = variables["arlas"]
print(Service.deactivate(config, id).get("message"))


@user.command(help="Deactivate user account", name="reset-password", epilog=variables["help_epilog"])
def reset_password(email: str = typer.Argument(help="User's email")):
config = variables["arlas"]
print(Service.reset_password(config, email).get("message"))