aioli-sdk 1.0.1.dev4__tar.gz → 1.0.1.dev22__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/PKG-INFO +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/__version__.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/cli/_util.py +2 -9
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/cli/cli.py +2 -0
- aioli_sdk-1.0.1.dev22/aioli/cli/token.py +221 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/cli/user.py +23 -4
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/common/api/authentication.py +9 -4
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli_sdk.egg-info/PKG-INFO +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli_sdk.egg-info/SOURCES.txt +5 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/__init__.py +5 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/api/__init__.py +1 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/api/authentication_api.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/api/deployments_api.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/api/information_api.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/api/packaged_models_api.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/api/registries_api.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/api/roles_api.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/api/templates_api.py +1 -1
- aioli_sdk-1.0.1.dev22/aiolirest/api/tokens_api.py +1445 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/api/users_api.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/api_client.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/configuration.py +2 -2
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/exceptions.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/__init__.py +4 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/auto_scaling_template.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/autoscaling.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/configuration_resources.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/deployment.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/deployment_model_version.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/deployment_request.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/deployment_state.py +1 -1
- aioli_sdk-1.0.1.dev22/aiolirest/models/deployment_token.py +107 -0
- aioli_sdk-1.0.1.dev22/aiolirest/models/deployment_token_patch_request.py +93 -0
- aioli_sdk-1.0.1.dev22/aiolirest/models/deployment_token_request.py +97 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/error_response.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/event_info.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/failure_info.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/login_request.py +6 -3
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/login_response.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/model_auth_token.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/model_response.py +4 -4
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/observability.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/packaged_model.py +2 -2
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/packaged_model_request.py +2 -2
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/resource_profile.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/resources_template.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/role.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/role_assignment.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/role_assignments.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/security.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/success_response.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/trained_model_registry.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/trained_model_registry_request.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/user.py +1 -1
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/user_patch_request.py +5 -2
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/models/user_request.py +6 -4
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/rest.py +1 -1
- aioli_sdk-1.0.1.dev22/pyproject.toml +14 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/setup.py +1 -1
- aioli_sdk-1.0.1.dev4/pyproject.toml +0 -7
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/README.md +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/__init__.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/cli/__init__.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/cli/__main__.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/cli/deployment.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/cli/errors.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/cli/model.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/cli/registry.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/cli/render.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/cli/role.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/cli/sso.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/cli/test/conftest.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/cli/test/test_cli.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/cli/version.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/common/__init__.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/common/api/__init__.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/common/api/_util.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/common/api/certs.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/common/api/errors.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/common/api/request.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/common/check.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/common/constants.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/common/declarative_argparse.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/common/requests.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/common/util.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli/util.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli_sdk.egg-info/dependency_links.txt +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli_sdk.egg-info/entry_points.txt +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli_sdk.egg-info/not-zip-safe +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli_sdk.egg-info/requires.txt +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aioli_sdk.egg-info/top_level.txt +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/api_response.py +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/aiolirest/py.typed +0 -0
- {aioli_sdk-1.0.1.dev4 → aioli_sdk-1.0.1.dev22}/setup.cfg +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
# © Copyright 2024 Hewlett Packard Enterprise Development LP
|
|
2
|
-
__version__ = "1.0.1-
|
|
2
|
+
__version__ = "1.0.1-dev22"
|
|
@@ -8,7 +8,7 @@ from aioli.common.api import authentication
|
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def setup_session_no_auth(host: str) -> aiolirest.ApiClient:
|
|
11
|
-
host = prepend_protocol(host)
|
|
11
|
+
host = util.prepend_protocol(host)
|
|
12
12
|
|
|
13
13
|
return aiolirest.ApiClient(authentication.get_rest_config(host))
|
|
14
14
|
|
|
@@ -23,7 +23,7 @@ def setup_session(
|
|
|
23
23
|
else:
|
|
24
24
|
host = args.controller
|
|
25
25
|
|
|
26
|
-
host = prepend_protocol(host)
|
|
26
|
+
host = util.prepend_protocol(host)
|
|
27
27
|
|
|
28
28
|
configuration = authentication.get_rest_config(host)
|
|
29
29
|
|
|
@@ -40,10 +40,3 @@ def setup_session(
|
|
|
40
40
|
configuration.api_key["ApiKeyAuth"] = "Bearer " + token
|
|
41
41
|
|
|
42
42
|
return aiolirest.ApiClient(configuration)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def prepend_protocol(host: str) -> str:
|
|
46
|
-
# If neither http nor https is specified, supply the default of http.
|
|
47
|
-
if not (host.startswith("http://") or host.startswith("https://")):
|
|
48
|
-
host = f"http://{host}"
|
|
49
|
-
return f"{host}/api/v1"
|
|
@@ -21,6 +21,7 @@ from aioli.cli.model import args_description as model_args_description
|
|
|
21
21
|
from aioli.cli.registry import args_description as registry_args_description
|
|
22
22
|
from aioli.cli.role import args_description as role_args_description
|
|
23
23
|
from aioli.cli.sso import args_description as sso_args_description
|
|
24
|
+
from aioli.cli.token import args_description as deployment_token_args_description
|
|
24
25
|
from aioli.cli.user import args_description as user_args_description
|
|
25
26
|
from aioli.cli.version import args_description as version_args_description
|
|
26
27
|
from aioli.cli.version import check_version
|
|
@@ -59,6 +60,7 @@ all_args_description: ArgsDescription = (
|
|
|
59
60
|
+ user_args_description
|
|
60
61
|
+ role_args_description
|
|
61
62
|
+ sso_args_description
|
|
63
|
+
+ deployment_token_args_description
|
|
62
64
|
)
|
|
63
65
|
|
|
64
66
|
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# © Copyright 2024 Hewlett Packard Enterprise Development LP
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import datetime
|
|
5
|
+
from typing import Any, List
|
|
6
|
+
|
|
7
|
+
import aioli
|
|
8
|
+
import aioli.cli
|
|
9
|
+
import aioli.cli.errors
|
|
10
|
+
import aioli.cli.render
|
|
11
|
+
import aioli.common.api.authentication
|
|
12
|
+
import aioli.common.declarative_argparse
|
|
13
|
+
import aiolirest
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def format_token(t: aiolirest.DeploymentToken) -> List[Any]:
|
|
17
|
+
result = [t.id, t.description, t.username, t.deployment, t.expiration, t.revoked]
|
|
18
|
+
return result
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@aioli.common.api.authentication.required
|
|
22
|
+
def create_token(parsed_args: argparse.Namespace) -> None:
|
|
23
|
+
"""Create a deployment token with the provided arguments.
|
|
24
|
+
|
|
25
|
+
Invoke the Aioli Tokens API to create the deployment token. Print the ID of the deployment
|
|
26
|
+
token created on the console.
|
|
27
|
+
|
|
28
|
+
Args:
|
|
29
|
+
parsed_args: command line arguments provided by the user. Includes username, deployment
|
|
30
|
+
name, description, and expiration.
|
|
31
|
+
"""
|
|
32
|
+
with aioli.cli.setup_session(parsed_args) as session:
|
|
33
|
+
tokens_api = aiolirest.TokensApi(session)
|
|
34
|
+
|
|
35
|
+
# The Aioli REST API endpoint /tokens has a mandatory field expiration and it
|
|
36
|
+
# accepts timestamp in only one format, i.e., 2024-06-28T18:41:52-05:00.
|
|
37
|
+
# If the user provided timestamp doesn't match the expected format. The REST API returns an
|
|
38
|
+
# error but does not include the expected format. This makes it difficult for the users to
|
|
39
|
+
# invoke the command successfully.
|
|
40
|
+
# The validation below is and the error message help the users to quickly change the format
|
|
41
|
+
# of the timestamp, if needed. This validation can be removed once the REST API is updated
|
|
42
|
+
# to handle expiration timestamp in a user-friendly way.
|
|
43
|
+
try:
|
|
44
|
+
datetime.datetime.strptime(parsed_args.expiration, "%Y-%m-%dT%H:%M:%S%z")
|
|
45
|
+
except ValueError as e:
|
|
46
|
+
raise aioli.cli.errors.CliError(
|
|
47
|
+
f"Failed to parse expiration: {parsed_args.expiration}. "
|
|
48
|
+
"Expected format: 2024-06-28T18:41:52-05:00"
|
|
49
|
+
) from e
|
|
50
|
+
|
|
51
|
+
token_request = aiolirest.DeploymentTokenRequest(
|
|
52
|
+
user=parsed_args.username,
|
|
53
|
+
deployment=parsed_args.deployment,
|
|
54
|
+
description=parsed_args.description,
|
|
55
|
+
expiration=parsed_args.expiration,
|
|
56
|
+
)
|
|
57
|
+
token = tokens_api.tokens_post(request=token_request)
|
|
58
|
+
print(token.id)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
@aioli.common.api.authentication.required
|
|
62
|
+
def list_tokens(parsed_args: argparse.Namespace) -> None:
|
|
63
|
+
"""List the deployment tokens.
|
|
64
|
+
|
|
65
|
+
Invoke the Aioli Tokens API and fetch the deployment tokens. Format and display the deployment
|
|
66
|
+
tokens on the console as a table.
|
|
67
|
+
"""
|
|
68
|
+
with aioli.cli.setup_session(parsed_args) as session:
|
|
69
|
+
tokens_api = aiolirest.TokensApi(session)
|
|
70
|
+
response = tokens_api.tokens_get()
|
|
71
|
+
|
|
72
|
+
if parsed_args.json:
|
|
73
|
+
tokens = [token.to_dict() for token in response]
|
|
74
|
+
aioli.cli.render.print_json(tokens)
|
|
75
|
+
else:
|
|
76
|
+
headers = ["ID", "Description", "Username", "Deployment", "Expiration", "Revoked"]
|
|
77
|
+
values = [format_token(t) for t in response]
|
|
78
|
+
aioli.cli.render.tabulate_or_csv(headers, values, parsed_args.csv)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@aioli.common.api.authentication.required
|
|
82
|
+
def get_token(parsed_args: argparse.Namespace) -> None:
|
|
83
|
+
"""Get the deployment token with the provided ID.
|
|
84
|
+
|
|
85
|
+
Invoke the Aioli Tokens API to get the deployment token with the provided ID. Display the
|
|
86
|
+
deployment token details in JSON format on the console.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
parsed_args: command line arguments provided by the user. Includes ID for the deployment
|
|
90
|
+
token.
|
|
91
|
+
"""
|
|
92
|
+
with aioli.cli.setup_session(parsed_args) as session:
|
|
93
|
+
tokens_api = aiolirest.TokensApi(session)
|
|
94
|
+
token = tokens_api.tokens_id_get(parsed_args.id)
|
|
95
|
+
if parsed_args.json:
|
|
96
|
+
aioli.cli.render.print_json(token.to_json())
|
|
97
|
+
else:
|
|
98
|
+
token_yaml = aioli.cli.render.format_object_as_yaml(token.to_dict())
|
|
99
|
+
print(token_yaml)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@aioli.common.api.authentication.required
|
|
103
|
+
def delete_token(parsed_args: argparse.Namespace) -> None:
|
|
104
|
+
"""Delete the deployment token with the provided ID.
|
|
105
|
+
|
|
106
|
+
Invoke the Aioli Tokens API to delete the deployment token with the provided ID.
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
parsed_args: command line arguments provided by the user. Includes ID for the deployment
|
|
110
|
+
token.
|
|
111
|
+
"""
|
|
112
|
+
with aioli.cli.setup_session(parsed_args) as session:
|
|
113
|
+
tokens_api = aiolirest.TokensApi(session)
|
|
114
|
+
tokens_api.tokens_id_delete(parsed_args.id)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
@aioli.common.api.authentication.required
|
|
118
|
+
def update_token(parsed_args: argparse.Namespace) -> None:
|
|
119
|
+
"""Update the description for the deployment token with the provided ID.
|
|
120
|
+
|
|
121
|
+
Invoke the Aioli Tokens API to update the description for the deployment token with the
|
|
122
|
+
provided ID.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
parsed_args: command line arguments provided by the user. Includes ID for the deployment
|
|
126
|
+
token and the updated description.
|
|
127
|
+
"""
|
|
128
|
+
with aioli.cli.setup_session(parsed_args) as session:
|
|
129
|
+
tokens_api = aiolirest.TokensApi(session)
|
|
130
|
+
token_patch_request = aiolirest.DeploymentTokenPatchRequest(
|
|
131
|
+
description=parsed_args.description,
|
|
132
|
+
)
|
|
133
|
+
tokens_api.tokens_id_patch(parsed_args.id, token_patch_request)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@aioli.common.api.authentication.required
|
|
137
|
+
def revoke_token(parsed_args: argparse.Namespace) -> None:
|
|
138
|
+
"""Revoke the deployment token with the provided ID.
|
|
139
|
+
|
|
140
|
+
Invoke the Aioli Tokens API to revoke the deployment token with the provided ID.
|
|
141
|
+
|
|
142
|
+
Args:
|
|
143
|
+
parsed_args: command line arguments provided by the user. Includes ID for the deployment
|
|
144
|
+
token to be revoked.
|
|
145
|
+
"""
|
|
146
|
+
with aioli.cli.setup_session(parsed_args) as session:
|
|
147
|
+
tokens_api = aiolirest.TokensApi(session)
|
|
148
|
+
token_patch_request = aiolirest.DeploymentTokenPatchRequest(
|
|
149
|
+
revoked=True,
|
|
150
|
+
)
|
|
151
|
+
tokens_api.tokens_id_patch(parsed_args.id, token_patch_request)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
# fmt: off
|
|
155
|
+
|
|
156
|
+
args_description = [
|
|
157
|
+
aioli.common.declarative_argparse.Cmd("t|oken", None, "manage deployment tokens", [
|
|
158
|
+
aioli.common.declarative_argparse.Cmd("create", create_token, "create deployment token", [
|
|
159
|
+
aioli.common.declarative_argparse.Arg(
|
|
160
|
+
"deployment", help="The deployment for which the token will be created.",
|
|
161
|
+
),
|
|
162
|
+
aioli.common.declarative_argparse.Arg(
|
|
163
|
+
"--username",
|
|
164
|
+
help="The username for whom the token will be created. "
|
|
165
|
+
"If no username is provided, the current user's username will be used."
|
|
166
|
+
),
|
|
167
|
+
aioli.common.declarative_argparse.Arg(
|
|
168
|
+
"--description", help="Description for the deployment token."
|
|
169
|
+
),
|
|
170
|
+
aioli.common.declarative_argparse.Arg(
|
|
171
|
+
"--expiration",
|
|
172
|
+
help="Expiration date for the token. For example, 2024-06-28T18:41:52-05:00",
|
|
173
|
+
),
|
|
174
|
+
]),
|
|
175
|
+
aioli.common.declarative_argparse.Cmd(
|
|
176
|
+
"list ls",
|
|
177
|
+
list_tokens,
|
|
178
|
+
"list the deployment tokens",
|
|
179
|
+
[
|
|
180
|
+
aioli.common.declarative_argparse.Arg(
|
|
181
|
+
"--json", action="store_true",
|
|
182
|
+
help="Print the tokens in JSON format.",
|
|
183
|
+
),
|
|
184
|
+
aioli.common.declarative_argparse.Arg(
|
|
185
|
+
"--csv", action="store_true",
|
|
186
|
+
help="Print the tokens in CSV format.",
|
|
187
|
+
),
|
|
188
|
+
],
|
|
189
|
+
is_default=True,
|
|
190
|
+
),
|
|
191
|
+
aioli.common.declarative_argparse.Cmd(
|
|
192
|
+
"show", get_token, "show the details of the deployment token with given ID", [
|
|
193
|
+
aioli.common.declarative_argparse.Arg("id", help="ID of the token"),
|
|
194
|
+
aioli.common.declarative_argparse.Arg(
|
|
195
|
+
"--json", action="store_true",
|
|
196
|
+
help="Print the token in JSON format.",
|
|
197
|
+
),
|
|
198
|
+
]
|
|
199
|
+
),
|
|
200
|
+
aioli.common.declarative_argparse.Cmd(
|
|
201
|
+
"update", update_token, "update the description for deployment token with given ID", [
|
|
202
|
+
aioli.common.declarative_argparse.Arg("id", help="ID of the token"),
|
|
203
|
+
aioli.common.declarative_argparse.Arg(
|
|
204
|
+
"description", help="New description for the deployment token."
|
|
205
|
+
),
|
|
206
|
+
]
|
|
207
|
+
),
|
|
208
|
+
aioli.common.declarative_argparse.Cmd(
|
|
209
|
+
"revoke", revoke_token, "revoke the deployment token with given ID", [
|
|
210
|
+
aioli.common.declarative_argparse.Arg("id", help="ID of the token"),
|
|
211
|
+
]
|
|
212
|
+
),
|
|
213
|
+
aioli.common.declarative_argparse.Cmd(
|
|
214
|
+
"delete", delete_token, "delete the deployment token with given ID", [
|
|
215
|
+
aioli.common.declarative_argparse.Arg("id", help="ID of the token"),
|
|
216
|
+
]
|
|
217
|
+
),
|
|
218
|
+
])
|
|
219
|
+
] # type: List[Any]
|
|
220
|
+
|
|
221
|
+
# fmt: on
|
|
@@ -72,7 +72,22 @@ def log_in_user(parsed_args: Namespace) -> None:
|
|
|
72
72
|
password = getpass.getpass(message)
|
|
73
73
|
|
|
74
74
|
token_store = authentication.TokenStore(parsed_args.controller)
|
|
75
|
-
|
|
75
|
+
|
|
76
|
+
try:
|
|
77
|
+
token = authentication.do_login(
|
|
78
|
+
parsed_args.controller,
|
|
79
|
+
username,
|
|
80
|
+
authentication.salt_and_hash(password),
|
|
81
|
+
True,
|
|
82
|
+
certs.cli_cert,
|
|
83
|
+
)
|
|
84
|
+
except aiolirest.exceptions.ForbiddenException:
|
|
85
|
+
# log in request was possibly for user that was created before INF-851,
|
|
86
|
+
# retry log in using the password without apply salt_and_hash
|
|
87
|
+
token = authentication.do_login(
|
|
88
|
+
parsed_args.controller, username, password, False, certs.cli_cert
|
|
89
|
+
)
|
|
90
|
+
|
|
76
91
|
token_store.set_token(username, token)
|
|
77
92
|
token_store.set_active(username)
|
|
78
93
|
|
|
@@ -104,7 +119,8 @@ def change_password(parsed_args: Namespace) -> None:
|
|
|
104
119
|
if password != check_password:
|
|
105
120
|
raise errors.CliError("Passwords do not match")
|
|
106
121
|
|
|
107
|
-
|
|
122
|
+
password = authentication.salt_and_hash(password)
|
|
123
|
+
patch_data = UserPatchRequest(password=password, isHashed=True)
|
|
108
124
|
|
|
109
125
|
patch_user(parsed_args, username, patch_data)
|
|
110
126
|
|
|
@@ -112,7 +128,9 @@ def change_password(parsed_args: Namespace) -> None:
|
|
|
112
128
|
# password change so that the user doesn't have to do so manually.
|
|
113
129
|
if parsed_args.target_user is None:
|
|
114
130
|
token_store = authentication.TokenStore(parsed_args.controller)
|
|
115
|
-
token = authentication.do_login(
|
|
131
|
+
token = authentication.do_login(
|
|
132
|
+
parsed_args.controller, username, password, True, certs.cli_cert
|
|
133
|
+
)
|
|
116
134
|
token_store.set_token(username, token)
|
|
117
135
|
token_store.set_active(username)
|
|
118
136
|
|
|
@@ -145,7 +163,8 @@ def create_user(parsed_args: Namespace) -> None:
|
|
|
145
163
|
displayName=display_name,
|
|
146
164
|
remote=remote,
|
|
147
165
|
roleName=role_name,
|
|
148
|
-
password=password,
|
|
166
|
+
password=authentication.salt_and_hash(password),
|
|
167
|
+
isHashed=True,
|
|
149
168
|
)
|
|
150
169
|
api_instance.users_post(user=new_user)
|
|
151
170
|
|
|
@@ -160,7 +160,7 @@ class Authentication:
|
|
|
160
160
|
password = getpass.getpass("Password for user '{}': ".format(session_user))
|
|
161
161
|
|
|
162
162
|
try:
|
|
163
|
-
token = do_login(self.master_address, session_user, password, cert)
|
|
163
|
+
token = do_login(self.master_address, session_user, salt_and_hash(password), True, cert)
|
|
164
164
|
except api.errors.ForbiddenException:
|
|
165
165
|
if fallback_to_default:
|
|
166
166
|
raise api.errors.UnauthenticatedException(username=session_user)
|
|
@@ -197,13 +197,14 @@ def do_login(
|
|
|
197
197
|
controller_address: str,
|
|
198
198
|
username: str,
|
|
199
199
|
password: str,
|
|
200
|
+
isHashed: bool,
|
|
200
201
|
cert: Optional[certs.Cert] = None,
|
|
201
202
|
) -> str:
|
|
202
203
|
host: str = controller_address
|
|
203
204
|
host = util.prepend_protocol(host)
|
|
204
205
|
|
|
205
206
|
client = aiolirest.ApiClient(get_rest_config(host))
|
|
206
|
-
request = aiolirest.LoginRequest(username=username, password=password)
|
|
207
|
+
request = aiolirest.LoginRequest(username=username, password=password, isHashed=isHashed)
|
|
207
208
|
response = aiolirest.AuthenticationApi(client).login_post(request=request)
|
|
208
209
|
|
|
209
210
|
token = response.token
|
|
@@ -531,8 +532,7 @@ def required(func: Callable[[argparse.Namespace], Any]) -> Callable[..., Any]:
|
|
|
531
532
|
|
|
532
533
|
@functools.wraps(func)
|
|
533
534
|
def f(namespace: argparse.Namespace) -> Any:
|
|
534
|
-
|
|
535
|
-
cli_auth = Authentication(namespace.controller, namespace.user)
|
|
535
|
+
update_cli_auth(namespace)
|
|
536
536
|
return func(namespace)
|
|
537
537
|
|
|
538
538
|
return f
|
|
@@ -542,3 +542,8 @@ def must_cli_auth() -> Authentication:
|
|
|
542
542
|
if not cli_auth:
|
|
543
543
|
raise api.errors.UnauthenticatedException(username="")
|
|
544
544
|
return cli_auth
|
|
545
|
+
|
|
546
|
+
|
|
547
|
+
def update_cli_auth(namespace: argparse.Namespace) -> None:
|
|
548
|
+
global cli_auth
|
|
549
|
+
cli_auth = Authentication(namespace.controller, namespace.user)
|
|
@@ -15,6 +15,7 @@ aioli/cli/registry.py
|
|
|
15
15
|
aioli/cli/render.py
|
|
16
16
|
aioli/cli/role.py
|
|
17
17
|
aioli/cli/sso.py
|
|
18
|
+
aioli/cli/token.py
|
|
18
19
|
aioli/cli/user.py
|
|
19
20
|
aioli/cli/version.py
|
|
20
21
|
aioli/cli/test/conftest.py
|
|
@@ -53,6 +54,7 @@ aiolirest/api/packaged_models_api.py
|
|
|
53
54
|
aiolirest/api/registries_api.py
|
|
54
55
|
aiolirest/api/roles_api.py
|
|
55
56
|
aiolirest/api/templates_api.py
|
|
57
|
+
aiolirest/api/tokens_api.py
|
|
56
58
|
aiolirest/api/users_api.py
|
|
57
59
|
aiolirest/models/__init__.py
|
|
58
60
|
aiolirest/models/auto_scaling_template.py
|
|
@@ -62,6 +64,9 @@ aiolirest/models/deployment.py
|
|
|
62
64
|
aiolirest/models/deployment_model_version.py
|
|
63
65
|
aiolirest/models/deployment_request.py
|
|
64
66
|
aiolirest/models/deployment_state.py
|
|
67
|
+
aiolirest/models/deployment_token.py
|
|
68
|
+
aiolirest/models/deployment_token_patch_request.py
|
|
69
|
+
aiolirest/models/deployment_token_request.py
|
|
65
70
|
aiolirest/models/error_response.py
|
|
66
71
|
aiolirest/models/event_info.py
|
|
67
72
|
aiolirest/models/failure_info.py
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
HPE MLIS is *Aioli* -- The AI On-line Inference Platform that enables easy deployment, tracking, and serving of your packaged models regardless of your preferred AI framework.
|
|
9
9
|
|
|
10
|
-
The version of the OpenAPI document: 1.0.1-
|
|
10
|
+
The version of the OpenAPI document: 1.0.1-dev22
|
|
11
11
|
Contact: community@determined-ai
|
|
12
12
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
13
13
|
|
|
@@ -25,6 +25,7 @@ from aiolirest.api.packaged_models_api import PackagedModelsApi
|
|
|
25
25
|
from aiolirest.api.registries_api import RegistriesApi
|
|
26
26
|
from aiolirest.api.roles_api import RolesApi
|
|
27
27
|
from aiolirest.api.templates_api import TemplatesApi
|
|
28
|
+
from aiolirest.api.tokens_api import TokensApi
|
|
28
29
|
from aiolirest.api.users_api import UsersApi
|
|
29
30
|
|
|
30
31
|
# import ApiClient
|
|
@@ -46,6 +47,9 @@ from aiolirest.models.deployment import Deployment
|
|
|
46
47
|
from aiolirest.models.deployment_model_version import DeploymentModelVersion
|
|
47
48
|
from aiolirest.models.deployment_request import DeploymentRequest
|
|
48
49
|
from aiolirest.models.deployment_state import DeploymentState
|
|
50
|
+
from aiolirest.models.deployment_token import DeploymentToken
|
|
51
|
+
from aiolirest.models.deployment_token_patch_request import DeploymentTokenPatchRequest
|
|
52
|
+
from aiolirest.models.deployment_token_request import DeploymentTokenRequest
|
|
49
53
|
from aiolirest.models.error_response import ErrorResponse
|
|
50
54
|
from aiolirest.models.event_info import EventInfo
|
|
51
55
|
from aiolirest.models.failure_info import FailureInfo
|
|
@@ -8,5 +8,6 @@ from aiolirest.api.packaged_models_api import PackagedModelsApi
|
|
|
8
8
|
from aiolirest.api.registries_api import RegistriesApi
|
|
9
9
|
from aiolirest.api.roles_api import RolesApi
|
|
10
10
|
from aiolirest.api.templates_api import TemplatesApi
|
|
11
|
+
from aiolirest.api.tokens_api import TokensApi
|
|
11
12
|
from aiolirest.api.users_api import UsersApi
|
|
12
13
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
HPE MLIS is *Aioli* -- The AI On-line Inference Platform that enables easy deployment, tracking, and serving of your packaged models regardless of your preferred AI framework.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document: 1.0.1-
|
|
8
|
+
The version of the OpenAPI document: 1.0.1-dev22
|
|
9
9
|
Contact: community@determined-ai
|
|
10
10
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
11
11
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
HPE MLIS is *Aioli* -- The AI On-line Inference Platform that enables easy deployment, tracking, and serving of your packaged models regardless of your preferred AI framework.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document: 1.0.1-
|
|
8
|
+
The version of the OpenAPI document: 1.0.1-dev22
|
|
9
9
|
Contact: community@determined-ai
|
|
10
10
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
11
11
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
HPE MLIS is *Aioli* -- The AI On-line Inference Platform that enables easy deployment, tracking, and serving of your packaged models regardless of your preferred AI framework.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document: 1.0.1-
|
|
8
|
+
The version of the OpenAPI document: 1.0.1-dev22
|
|
9
9
|
Contact: community@determined-ai
|
|
10
10
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
11
11
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
HPE MLIS is *Aioli* -- The AI On-line Inference Platform that enables easy deployment, tracking, and serving of your packaged models regardless of your preferred AI framework.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document: 1.0.1-
|
|
8
|
+
The version of the OpenAPI document: 1.0.1-dev22
|
|
9
9
|
Contact: community@determined-ai
|
|
10
10
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
11
11
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
HPE MLIS is *Aioli* -- The AI On-line Inference Platform that enables easy deployment, tracking, and serving of your packaged models regardless of your preferred AI framework.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document: 1.0.1-
|
|
8
|
+
The version of the OpenAPI document: 1.0.1-dev22
|
|
9
9
|
Contact: community@determined-ai
|
|
10
10
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
11
11
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
HPE MLIS is *Aioli* -- The AI On-line Inference Platform that enables easy deployment, tracking, and serving of your packaged models regardless of your preferred AI framework.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document: 1.0.1-
|
|
8
|
+
The version of the OpenAPI document: 1.0.1-dev22
|
|
9
9
|
Contact: community@determined-ai
|
|
10
10
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
11
11
|
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
HPE MLIS is *Aioli* -- The AI On-line Inference Platform that enables easy deployment, tracking, and serving of your packaged models regardless of your preferred AI framework.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document: 1.0.1-
|
|
8
|
+
The version of the OpenAPI document: 1.0.1-dev22
|
|
9
9
|
Contact: community@determined-ai
|
|
10
10
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
11
11
|
|