cmem-cmemc 23.1.3__py3-none-any.whl → 23.3.0__py3-none-any.whl
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.
- cmem/cmemc/cli/__init__.py +9 -3
- cmem/cmemc/cli/_cmemc.zsh +44 -0
- cmem/cmemc/cli/commands/__init__.py +3 -0
- cmem/cmemc/cli/commands/admin.py +3 -1
- cmem/cmemc/cli/commands/client.py +173 -0
- cmem/cmemc/cli/commands/config.py +1 -1
- cmem/cmemc/cli/commands/dataset.py +161 -70
- cmem/cmemc/cli/commands/graph.py +10 -10
- cmem/cmemc/cli/commands/metrics.py +3 -3
- cmem/cmemc/cli/commands/project.py +90 -27
- cmem/cmemc/cli/commands/python.py +110 -29
- cmem/cmemc/cli/commands/query.py +6 -6
- cmem/cmemc/cli/commands/resource.py +5 -5
- cmem/cmemc/cli/commands/scheduler.py +4 -4
- cmem/cmemc/cli/commands/store.py +34 -31
- cmem/cmemc/cli/commands/user.py +27 -10
- cmem/cmemc/cli/commands/variable.py +364 -0
- cmem/cmemc/cli/commands/vocabulary.py +5 -5
- cmem/cmemc/cli/commands/workflow.py +118 -55
- cmem/cmemc/cli/commands/workspace.py +5 -5
- cmem/cmemc/cli/completion.py +393 -154
- cmem/cmemc/cli/context.py +20 -3
- cmem/cmemc/cli/manual_helper/multi_page.py +11 -6
- cmem/cmemc/cli/utils.py +80 -0
- {cmem_cmemc-23.1.3.dist-info → cmem_cmemc-23.3.0.dist-info}/METADATA +6 -8
- cmem_cmemc-23.3.0.dist-info/RECORD +35 -0
- {cmem_cmemc-23.1.3.dist-info → cmem_cmemc-23.3.0.dist-info}/WHEEL +1 -1
- cmem_cmemc-23.1.3.dist-info/RECORD +0 -32
- {cmem_cmemc-23.1.3.dist-info → cmem_cmemc-23.3.0.dist-info}/LICENSE +0 -0
- {cmem_cmemc-23.1.3.dist-info → cmem_cmemc-23.3.0.dist-info}/entry_points.txt +0 -0
cmem/cmemc/cli/commands/store.py
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
"""DataPlatform store commands for the cmem command line interface."""
|
|
2
2
|
import os
|
|
3
|
-
import sys
|
|
4
3
|
from os.path import exists
|
|
5
4
|
|
|
6
5
|
import click
|
|
6
|
+
from click import UsageError
|
|
7
7
|
|
|
8
8
|
from cmem.cmemc.cli import completion
|
|
9
9
|
from cmem.cmemc.cli.commands import CmemcCommand, CmemcGroup
|
|
10
10
|
from cmem.cmemc.cli.context import ApplicationContext
|
|
11
|
-
from cmem.cmempy.dp.admin import
|
|
11
|
+
from cmem.cmempy.dp.admin import (
|
|
12
|
+
create_showcase_data,
|
|
13
|
+
delete_bootstrap_data,
|
|
14
|
+
import_bootstrap_data
|
|
15
|
+
)
|
|
12
16
|
from cmem.cmempy.dp.admin.backup import get_zip, post_zip
|
|
13
17
|
|
|
14
18
|
|
|
@@ -17,32 +21,37 @@ from cmem.cmempy.dp.admin.backup import get_zip, post_zip
|
|
|
17
21
|
"--import", "import_",
|
|
18
22
|
is_flag=True,
|
|
19
23
|
help="Delete existing bootstrap data if present and import bootstrap "
|
|
20
|
-
"data which was delivered "
|
|
24
|
+
"data which was delivered with Corporate Memory."
|
|
25
|
+
)
|
|
26
|
+
@click.option(
|
|
27
|
+
"--remove",
|
|
28
|
+
is_flag=True,
|
|
29
|
+
help="Delete existing bootstrap data if present."
|
|
21
30
|
)
|
|
22
31
|
@click.pass_obj
|
|
23
|
-
def bootstrap_command(app: ApplicationContext, import_):
|
|
24
|
-
"""Update/Import bootstrap data.
|
|
32
|
+
def bootstrap_command(app: ApplicationContext, import_, remove):
|
|
33
|
+
"""Update/Import or remove bootstrap data.
|
|
34
|
+
|
|
35
|
+
Use `--import` to import the bootstrap data needed for managing shapes and
|
|
36
|
+
configuration objects. This will remove the old data first.
|
|
25
37
|
|
|
26
|
-
|
|
27
|
-
configuration objects.
|
|
38
|
+
Use `--remove` to delete bootstrap data.
|
|
28
39
|
|
|
29
|
-
Note: The
|
|
30
|
-
|
|
31
|
-
to the corresponding graphs (shape catalog, vocabulary catalog, configuration
|
|
32
|
-
graph).
|
|
40
|
+
Note: The removal of existing bootstrap data will search for resources which are
|
|
41
|
+
flagged with the isSystemResource property.
|
|
33
42
|
"""
|
|
34
|
-
if
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
if import_ and remove or not import_ and not remove:
|
|
44
|
+
raise UsageError("Either use the --import or the --remove option.")
|
|
45
|
+
if import_:
|
|
46
|
+
app.echo_info("Update or import bootstrap data ... ", nl=False)
|
|
47
|
+
import_bootstrap_data()
|
|
48
|
+
app.echo_success("done")
|
|
49
|
+
return
|
|
50
|
+
if remove:
|
|
51
|
+
app.echo_info("Remove bootstrap data ... ", nl=False)
|
|
52
|
+
delete_bootstrap_data()
|
|
53
|
+
app.echo_success("done")
|
|
54
|
+
return
|
|
46
55
|
|
|
47
56
|
|
|
48
57
|
@click.command(cls=CmemcCommand, name="showcase")
|
|
@@ -77,12 +86,6 @@ def showcase_command(app, scale, create, delete):
|
|
|
77
86
|
you need to remove the showcase graphs manually (or just remove all
|
|
78
87
|
graphs).
|
|
79
88
|
"""
|
|
80
|
-
if "store" not in sys.argv:
|
|
81
|
-
app.echo_warning(
|
|
82
|
-
"The 'admin showcase' command is deprecated and will be removed "
|
|
83
|
-
"in the next major release.\n"
|
|
84
|
-
"Please use the 'admin store showcase' command instead."
|
|
85
|
-
)
|
|
86
89
|
if not delete and not create:
|
|
87
90
|
raise ValueError("Either use the --create or the --delete flag.")
|
|
88
91
|
if delete:
|
|
@@ -102,7 +105,7 @@ def showcase_command(app, scale, create, delete):
|
|
|
102
105
|
@click.command(cls=CmemcCommand, name="export")
|
|
103
106
|
@click.argument(
|
|
104
107
|
"BACKUP_FILE",
|
|
105
|
-
|
|
108
|
+
shell_complete=completion.graph_backup_files,
|
|
106
109
|
required=True,
|
|
107
110
|
type=click.Path(
|
|
108
111
|
writable=True,
|
|
@@ -161,7 +164,7 @@ def export_command(app, backup_file, overwrite):
|
|
|
161
164
|
@click.command(cls=CmemcCommand, name="import")
|
|
162
165
|
@click.argument(
|
|
163
166
|
"BACKUP_FILE",
|
|
164
|
-
|
|
167
|
+
shell_complete=completion.graph_backup_files,
|
|
165
168
|
required=True,
|
|
166
169
|
type=click.Path(
|
|
167
170
|
readable=True,
|
cmem/cmemc/cli/commands/user.py
CHANGED
|
@@ -17,7 +17,7 @@ from cmem.cmempy.keycloak.user import (
|
|
|
17
17
|
create_user,
|
|
18
18
|
update_user,
|
|
19
19
|
assign_groups,
|
|
20
|
-
unassign_groups, user_groups
|
|
20
|
+
unassign_groups, user_groups, request_password_change
|
|
21
21
|
)
|
|
22
22
|
|
|
23
23
|
NO_USER_ERROR = "{} is not a valid user account. Use the 'admin user list' command " \
|
|
@@ -27,6 +27,7 @@ NO_GROUP_ERROR = "{} is not a valid group. Valid groups are {}"
|
|
|
27
27
|
INVALID_UNASSIGN_GROUP_ERROR = (
|
|
28
28
|
"Group {} is not assigned to user. Valid groups are {}"
|
|
29
29
|
)
|
|
30
|
+
NO_EMAIL_ERROR = "Email is empty for {} user."
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
@click.command(cls=CmemcCommand, name="list")
|
|
@@ -75,7 +76,7 @@ def list_command(app: ApplicationContext, raw, id_only):
|
|
|
75
76
|
@click.command(cls=CmemcCommand, name="delete")
|
|
76
77
|
@click.argument(
|
|
77
78
|
"username",
|
|
78
|
-
|
|
79
|
+
shell_complete=completion.user_ids
|
|
79
80
|
)
|
|
80
81
|
@click.pass_obj
|
|
81
82
|
def delete_command(app: ApplicationContext, username):
|
|
@@ -129,7 +130,7 @@ def create_command(app: ApplicationContext, username):
|
|
|
129
130
|
@click.command(cls=CmemcCommand, name="update")
|
|
130
131
|
@click.argument(
|
|
131
132
|
"username",
|
|
132
|
-
|
|
133
|
+
shell_complete=completion.user_ids
|
|
133
134
|
)
|
|
134
135
|
@click.option(
|
|
135
136
|
"--first-name",
|
|
@@ -153,14 +154,14 @@ def create_command(app: ApplicationContext, username):
|
|
|
153
154
|
"--assign-group",
|
|
154
155
|
type=click.STRING,
|
|
155
156
|
multiple=True,
|
|
156
|
-
|
|
157
|
+
shell_complete=completion.user_group_ids,
|
|
157
158
|
help="Assign a group."
|
|
158
159
|
)
|
|
159
160
|
@click.option(
|
|
160
161
|
"--unassign-group",
|
|
161
162
|
type=click.STRING,
|
|
162
163
|
multiple=True,
|
|
163
|
-
|
|
164
|
+
shell_complete=completion.user_group_ids,
|
|
164
165
|
help="Unassign a group."
|
|
165
166
|
)
|
|
166
167
|
@click.pass_obj
|
|
@@ -237,7 +238,7 @@ def update_command(
|
|
|
237
238
|
@click.command(cls=CmemcCommand, name="password")
|
|
238
239
|
@click.argument(
|
|
239
240
|
"username",
|
|
240
|
-
|
|
241
|
+
shell_complete=completion.user_ids
|
|
241
242
|
)
|
|
242
243
|
@click.option(
|
|
243
244
|
"--value",
|
|
@@ -248,8 +249,19 @@ def update_command(
|
|
|
248
249
|
is_flag=True,
|
|
249
250
|
help="If enabled, the user must change the password on next login."
|
|
250
251
|
)
|
|
252
|
+
@click.option(
|
|
253
|
+
"--request-change",
|
|
254
|
+
is_flag=True,
|
|
255
|
+
help="If enabled, will send a email to user to reset the password."
|
|
256
|
+
)
|
|
251
257
|
@click.pass_obj
|
|
252
|
-
def password_command(
|
|
258
|
+
def password_command(
|
|
259
|
+
app: ApplicationContext,
|
|
260
|
+
username,
|
|
261
|
+
value,
|
|
262
|
+
temporary,
|
|
263
|
+
request_change
|
|
264
|
+
):
|
|
253
265
|
"""
|
|
254
266
|
Change the password of a user account.
|
|
255
267
|
|
|
@@ -268,7 +280,7 @@ def password_command(app: ApplicationContext, username, value, temporary):
|
|
|
268
280
|
users = get_user_by_username(username)
|
|
269
281
|
if not users:
|
|
270
282
|
raise ValueError(NO_USER_ERROR.format(username))
|
|
271
|
-
if not value:
|
|
283
|
+
if not value and not request_change:
|
|
272
284
|
app.echo_info("\nNew password: ", nl=False)
|
|
273
285
|
value = getpass(prompt="")
|
|
274
286
|
app.echo_info("Retype new password: ", nl=False)
|
|
@@ -277,7 +289,12 @@ def password_command(app: ApplicationContext, username, value, temporary):
|
|
|
277
289
|
app.echo_error("Sorry, passwords do not match.")
|
|
278
290
|
app.echo_error("password unchanged")
|
|
279
291
|
sys.exit(1)
|
|
280
|
-
|
|
292
|
+
if value:
|
|
293
|
+
reset_password(user_id=users[0]["id"], value=value, temporary=temporary)
|
|
294
|
+
if request_change and not users[0].get("email", None):
|
|
295
|
+
raise ValueError(NO_EMAIL_ERROR.format(username))
|
|
296
|
+
if request_change:
|
|
297
|
+
request_password_change(users[0]["id"])
|
|
281
298
|
app.echo_success("done")
|
|
282
299
|
|
|
283
300
|
|
|
@@ -287,7 +304,7 @@ def password_command(app: ApplicationContext, username, value, temporary):
|
|
|
287
304
|
nargs=-1,
|
|
288
305
|
required=False,
|
|
289
306
|
type=click.STRING,
|
|
290
|
-
|
|
307
|
+
shell_complete=completion.user_ids
|
|
291
308
|
)
|
|
292
309
|
@click.pass_obj
|
|
293
310
|
def open_command(app: ApplicationContext, usernames: str):
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
"""DataIntegration variable commands for cmemc."""
|
|
2
|
+
import re
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
from click import UsageError
|
|
6
|
+
|
|
7
|
+
from cmem.cmemc.cli import completion
|
|
8
|
+
from cmem.cmemc.cli.commands import CmemcCommand, CmemcGroup
|
|
9
|
+
from cmem.cmemc.cli.utils import split_task_id, check_or_select_project
|
|
10
|
+
from cmem.cmempy.workspace.projects.variables import (
|
|
11
|
+
create_or_update_variable,
|
|
12
|
+
delete_variable,
|
|
13
|
+
get_all_variables,
|
|
14
|
+
get_variable
|
|
15
|
+
)
|
|
16
|
+
from cmem.cmemc.cli.context import ApplicationContext
|
|
17
|
+
|
|
18
|
+
VARIABLES_FILTER_TYPES = ["project", 'regex']
|
|
19
|
+
VARIABLES_FILTER_TYPES_HIDDEN = ["ids"]
|
|
20
|
+
VARIABLES_FILTER_TEXT = (
|
|
21
|
+
"Filter variables based on metadata. "
|
|
22
|
+
f"First parameter CHOICE can be one of {str(VARIABLES_FILTER_TYPES)}"
|
|
23
|
+
". The second parameter is based on CHOICE, e.g. a project "
|
|
24
|
+
"ID or a regular expression string."
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _get_variables_filtered(variables, filter_name, filter_value):
|
|
29
|
+
"""Get variables but filtered according to name and value."""
|
|
30
|
+
filter_types = VARIABLES_FILTER_TYPES + VARIABLES_FILTER_TYPES_HIDDEN
|
|
31
|
+
# check for correct filter names (filter ids is used internally only)
|
|
32
|
+
if filter_name not in filter_types:
|
|
33
|
+
raise ValueError(
|
|
34
|
+
f"{filter_name} is an unknown filter name. "
|
|
35
|
+
f"Use one of {VARIABLES_FILTER_TYPES}."
|
|
36
|
+
)
|
|
37
|
+
# filter by ID list
|
|
38
|
+
if filter_name == "ids":
|
|
39
|
+
return [_ for _ in variables if _["id"] in filter_value]
|
|
40
|
+
# filter by project
|
|
41
|
+
if filter_name == "project":
|
|
42
|
+
return [_ for _ in variables if _["project"] == filter_value]
|
|
43
|
+
# filter by regex
|
|
44
|
+
if filter_name == "regex":
|
|
45
|
+
return [
|
|
46
|
+
_ for _ in variables
|
|
47
|
+
if re.search(filter_value, _["id"])
|
|
48
|
+
or re.search(filter_value, _["value"])
|
|
49
|
+
or re.search(filter_value, _.get("description", ""))
|
|
50
|
+
or re.search(filter_value, _.get("template", ""))
|
|
51
|
+
]
|
|
52
|
+
# return unfiltered list
|
|
53
|
+
return variables
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@click.command(cls=CmemcCommand, name="list")
|
|
57
|
+
@click.option(
|
|
58
|
+
"--raw",
|
|
59
|
+
is_flag=True,
|
|
60
|
+
help="Outputs raw JSON."
|
|
61
|
+
)
|
|
62
|
+
@click.option(
|
|
63
|
+
"--id-only",
|
|
64
|
+
is_flag=True,
|
|
65
|
+
help="Lists only variables names and no other metadata. "
|
|
66
|
+
"This is useful for piping the IDs into other commands."
|
|
67
|
+
)
|
|
68
|
+
@click.option(
|
|
69
|
+
"--filter", "filters_",
|
|
70
|
+
multiple=True,
|
|
71
|
+
type=(str, str),
|
|
72
|
+
shell_complete=completion.variable_list_filter,
|
|
73
|
+
help=VARIABLES_FILTER_TEXT
|
|
74
|
+
)
|
|
75
|
+
@click.pass_obj
|
|
76
|
+
def list_command(app: ApplicationContext, raw, id_only, filters_):
|
|
77
|
+
"""List available project variables.
|
|
78
|
+
|
|
79
|
+
Outputs a table or a list of project variables.
|
|
80
|
+
"""
|
|
81
|
+
variables = get_all_variables()
|
|
82
|
+
|
|
83
|
+
for _ in filters_:
|
|
84
|
+
filter_name, filter_value = _
|
|
85
|
+
variables = _get_variables_filtered(
|
|
86
|
+
variables, filter_name, filter_value
|
|
87
|
+
)
|
|
88
|
+
if raw:
|
|
89
|
+
app.echo_info_json(variables)
|
|
90
|
+
return
|
|
91
|
+
if id_only:
|
|
92
|
+
for _ in sorted(_["id"] for _ in variables):
|
|
93
|
+
app.echo_result(_)
|
|
94
|
+
return
|
|
95
|
+
# output a user table
|
|
96
|
+
table = []
|
|
97
|
+
headers = ["ID", "Value", "Template", "Description"]
|
|
98
|
+
for _ in variables:
|
|
99
|
+
row = [
|
|
100
|
+
_["id"],
|
|
101
|
+
_["value"],
|
|
102
|
+
_.get("template", ""),
|
|
103
|
+
_.get("description", ""),
|
|
104
|
+
]
|
|
105
|
+
table.append(row)
|
|
106
|
+
app.echo_info_table(table, headers=headers, sort_column=0)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@click.command(cls=CmemcCommand, name="get")
|
|
110
|
+
@click.argument(
|
|
111
|
+
"variable_id",
|
|
112
|
+
required=True,
|
|
113
|
+
type=click.STRING,
|
|
114
|
+
shell_complete=completion.variable_ids
|
|
115
|
+
)
|
|
116
|
+
@click.option(
|
|
117
|
+
"--key",
|
|
118
|
+
type=click.Choice(
|
|
119
|
+
["value", "template", "description"],
|
|
120
|
+
case_sensitive=False
|
|
121
|
+
),
|
|
122
|
+
default="value",
|
|
123
|
+
show_default=True,
|
|
124
|
+
help="Specify the name of the value you want to get."
|
|
125
|
+
)
|
|
126
|
+
@click.option(
|
|
127
|
+
"--raw",
|
|
128
|
+
is_flag=True,
|
|
129
|
+
help="Outputs raw json."
|
|
130
|
+
)
|
|
131
|
+
@click.pass_obj
|
|
132
|
+
def get_command(app: ApplicationContext, variable_id, key, raw):
|
|
133
|
+
"""Get the value or other data of a project variable.
|
|
134
|
+
|
|
135
|
+
Use the `--key` option to specify which information you want to get.
|
|
136
|
+
|
|
137
|
+
Note: Only the `value` key is always available on a project variable.
|
|
138
|
+
Static value variables have no `template` key, and the `description` key
|
|
139
|
+
is optional for both types of variables.
|
|
140
|
+
"""
|
|
141
|
+
project_name, variable_name = split_task_id(variable_id)
|
|
142
|
+
_ = get_variable(variable_name=variable_name, project_name=project_name)
|
|
143
|
+
if raw:
|
|
144
|
+
app.echo_info_json(_)
|
|
145
|
+
return
|
|
146
|
+
try:
|
|
147
|
+
app.echo_info(_[key], nl=False)
|
|
148
|
+
except KeyError as error:
|
|
149
|
+
raise UsageError(
|
|
150
|
+
f"Variable {variable_name} has no value of '{key}'."
|
|
151
|
+
) from error
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@click.command(cls=CmemcCommand, name="delete")
|
|
155
|
+
@click.argument(
|
|
156
|
+
"variable_id",
|
|
157
|
+
required=True,
|
|
158
|
+
type=click.STRING,
|
|
159
|
+
shell_complete=completion.variable_ids
|
|
160
|
+
)
|
|
161
|
+
@click.pass_obj
|
|
162
|
+
def delete_command(app: ApplicationContext, variable_id):
|
|
163
|
+
"""Delete a project variable.
|
|
164
|
+
|
|
165
|
+
Note: You can not delete a variable which is used by another
|
|
166
|
+
(template based) variable. In order to do so, delete the template based
|
|
167
|
+
variable first.
|
|
168
|
+
"""
|
|
169
|
+
project_name, variable_name = split_task_id(variable_id)
|
|
170
|
+
app.echo_info(
|
|
171
|
+
f"Delete variable {variable_name} from project {project_name} ... ",
|
|
172
|
+
nl=False
|
|
173
|
+
)
|
|
174
|
+
delete_variable(variable_name=variable_name, project_name=project_name)
|
|
175
|
+
app.echo_success("done")
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
# pylint: disable=too-many-arguments
|
|
179
|
+
@click.command(cls=CmemcCommand, name="create")
|
|
180
|
+
@click.argument(
|
|
181
|
+
"variable_name",
|
|
182
|
+
required=True,
|
|
183
|
+
type=click.STRING,
|
|
184
|
+
)
|
|
185
|
+
@click.option(
|
|
186
|
+
"--value",
|
|
187
|
+
type=click.STRING,
|
|
188
|
+
help="The value of the new project variable."
|
|
189
|
+
)
|
|
190
|
+
@click.option(
|
|
191
|
+
"--template",
|
|
192
|
+
type=click.STRING,
|
|
193
|
+
help="The template of the new project variable. You can use Jinja template "
|
|
194
|
+
"syntax, e.g. use '{{global.myVar}}' for accessing global variables, or "
|
|
195
|
+
"'{{project.myVar}}' for accessing variables from the same project."
|
|
196
|
+
)
|
|
197
|
+
@click.option(
|
|
198
|
+
"--description",
|
|
199
|
+
type=click.STRING,
|
|
200
|
+
help="The optional description of the new project variable."
|
|
201
|
+
)
|
|
202
|
+
@click.option(
|
|
203
|
+
"--project", "project_id",
|
|
204
|
+
type=click.STRING,
|
|
205
|
+
shell_complete=completion.project_ids,
|
|
206
|
+
help="The project, where you want to create the variable in. If there is "
|
|
207
|
+
"only one project in the workspace, this option can be omitted."
|
|
208
|
+
)
|
|
209
|
+
@click.pass_obj
|
|
210
|
+
def create_command(
|
|
211
|
+
app: ApplicationContext,
|
|
212
|
+
variable_name, value, template, description,
|
|
213
|
+
project_id
|
|
214
|
+
):
|
|
215
|
+
"""Create a new project variable.
|
|
216
|
+
|
|
217
|
+
Variables need to be created with a value or a template (not both).
|
|
218
|
+
In addition to that, a project ID and a name are mandatory.
|
|
219
|
+
|
|
220
|
+
Example: cmemc project variable create my_var --project my_project --value abc
|
|
221
|
+
|
|
222
|
+
Note: cmemc is currently not able to manage the order of the variables in a
|
|
223
|
+
project. This means you have to create plain value variables in advance,
|
|
224
|
+
before you can create template based variables, which access these values.
|
|
225
|
+
"""
|
|
226
|
+
if value and template:
|
|
227
|
+
raise UsageError(
|
|
228
|
+
"Either use '--value' or '--template' but not both."
|
|
229
|
+
)
|
|
230
|
+
if not value and not template:
|
|
231
|
+
raise UsageError(
|
|
232
|
+
"Use '--value' or '--template' to create a new variable."
|
|
233
|
+
)
|
|
234
|
+
project_id = check_or_select_project(app, project_id)
|
|
235
|
+
data = get_variable(project_name=project_id, variable_name=variable_name)
|
|
236
|
+
if data:
|
|
237
|
+
raise UsageError(
|
|
238
|
+
f"Variable '{variable_name}' already exist in project '{project_id}'."
|
|
239
|
+
)
|
|
240
|
+
data = {
|
|
241
|
+
"name": variable_name,
|
|
242
|
+
"isSensitive": False,
|
|
243
|
+
"scope": "project"
|
|
244
|
+
}
|
|
245
|
+
if value:
|
|
246
|
+
data["value"] = value
|
|
247
|
+
if template:
|
|
248
|
+
data["template"] = template
|
|
249
|
+
if description:
|
|
250
|
+
data["description"] = description
|
|
251
|
+
app.echo_info(
|
|
252
|
+
f"Create variable {variable_name} in project {project_id} ... ",
|
|
253
|
+
nl=False
|
|
254
|
+
)
|
|
255
|
+
create_or_update_variable(
|
|
256
|
+
project_name=project_id,
|
|
257
|
+
variable_name=variable_name,
|
|
258
|
+
data=data
|
|
259
|
+
)
|
|
260
|
+
app.echo_success("done")
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
@click.command(cls=CmemcCommand, name="update")
|
|
264
|
+
@click.argument(
|
|
265
|
+
"variable_id",
|
|
266
|
+
required=True,
|
|
267
|
+
type=click.STRING,
|
|
268
|
+
shell_complete=completion.variable_ids
|
|
269
|
+
)
|
|
270
|
+
@click.option(
|
|
271
|
+
"--value",
|
|
272
|
+
type=click.STRING,
|
|
273
|
+
help="The new value of the project variable."
|
|
274
|
+
)
|
|
275
|
+
@click.option(
|
|
276
|
+
"--template",
|
|
277
|
+
type=click.STRING,
|
|
278
|
+
help="The new template of the project variable. You can use Jinja template "
|
|
279
|
+
"syntax, e.g. use '{{global.myVar}}' for accessing global variables, or "
|
|
280
|
+
"'{{project.myVar}}' for accessing variables from the same project."
|
|
281
|
+
)
|
|
282
|
+
@click.option(
|
|
283
|
+
"--description",
|
|
284
|
+
type=click.STRING,
|
|
285
|
+
help="The new description of the project variable."
|
|
286
|
+
)
|
|
287
|
+
@click.pass_obj
|
|
288
|
+
def update_command(
|
|
289
|
+
app: ApplicationContext,
|
|
290
|
+
variable_id, value, template, description,
|
|
291
|
+
):
|
|
292
|
+
"""Update data of an existing project variable.
|
|
293
|
+
|
|
294
|
+
With this command you can update the value or the template, as well as the
|
|
295
|
+
description of a project variable.
|
|
296
|
+
|
|
297
|
+
Note: If you update the template of a static variable, it will be transformed
|
|
298
|
+
to a template based variable. If you want to change the value of a template
|
|
299
|
+
based variable, an error will be shown.
|
|
300
|
+
"""
|
|
301
|
+
project_id, variable_name = split_task_id(variable_id)
|
|
302
|
+
data = get_variable(project_name=project_id, variable_name=variable_name)
|
|
303
|
+
if not data:
|
|
304
|
+
raise UsageError(
|
|
305
|
+
f"Variable '{variable_name}' does not exist in project '{project_id}'."
|
|
306
|
+
)
|
|
307
|
+
if value and template:
|
|
308
|
+
raise UsageError(
|
|
309
|
+
"Project variables are based on a static value or on a template, but not "
|
|
310
|
+
"both."
|
|
311
|
+
)
|
|
312
|
+
if not value and not template and not description:
|
|
313
|
+
raise UsageError(
|
|
314
|
+
"Please specify what you want to update. "
|
|
315
|
+
"Use at least one of the following options: "
|
|
316
|
+
"'--value', '--template', '--description'."
|
|
317
|
+
)
|
|
318
|
+
if value:
|
|
319
|
+
if data.get("template", None):
|
|
320
|
+
raise UsageError(
|
|
321
|
+
"You can not change the value of a template based variable."
|
|
322
|
+
)
|
|
323
|
+
data["value"] = value
|
|
324
|
+
if template:
|
|
325
|
+
if not data.get("template", None):
|
|
326
|
+
app.echo_warning(f"Variable '{variable_id}' will be converted from a "
|
|
327
|
+
f"simple to a template based variable.")
|
|
328
|
+
data["template"] = template
|
|
329
|
+
if description:
|
|
330
|
+
data["description"] = description
|
|
331
|
+
app.echo_info(
|
|
332
|
+
f"Update variable {variable_name} in project {project_id} ... ",
|
|
333
|
+
nl=False
|
|
334
|
+
)
|
|
335
|
+
create_or_update_variable(
|
|
336
|
+
project_name=project_id,
|
|
337
|
+
variable_name=variable_name,
|
|
338
|
+
data=data
|
|
339
|
+
)
|
|
340
|
+
app.echo_success("done")
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
@click.group(cls=CmemcGroup)
|
|
344
|
+
def variable():
|
|
345
|
+
"""List, create, delete or get data from project variables.
|
|
346
|
+
|
|
347
|
+
Project variables can be used in dataset and task parameters, and in the template
|
|
348
|
+
transform operator.
|
|
349
|
+
Variables are either based on a static value or based on a template.
|
|
350
|
+
They may use templates that access globally configured
|
|
351
|
+
variables or other preceding variables from the same project.
|
|
352
|
+
|
|
353
|
+
Variables are identified by a VARIABLE_ID. To get a list of existing
|
|
354
|
+
variables, execute the list command or use tab-completion.
|
|
355
|
+
The VARIABLE_ID is a concatenation of a PROJECT_ID and a VARIABLE_NAME,
|
|
356
|
+
such as `my-project:my-variable`.
|
|
357
|
+
"""
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
variable.add_command(list_command)
|
|
361
|
+
variable.add_command(get_command)
|
|
362
|
+
variable.add_command(delete_command)
|
|
363
|
+
variable.add_command(create_command)
|
|
364
|
+
variable.add_command(update_command)
|
|
@@ -202,7 +202,7 @@ def _transform_cache_to_table(cache_category, table):
|
|
|
202
202
|
@click.argument(
|
|
203
203
|
"iri",
|
|
204
204
|
type=click.STRING,
|
|
205
|
-
|
|
205
|
+
shell_complete=completion.installed_vocabularies
|
|
206
206
|
)
|
|
207
207
|
@click.pass_obj
|
|
208
208
|
def open_command(app, iri):
|
|
@@ -276,7 +276,7 @@ def list_command(app, id_only, filter_, raw):
|
|
|
276
276
|
"iris",
|
|
277
277
|
nargs=-1,
|
|
278
278
|
type=click.STRING,
|
|
279
|
-
|
|
279
|
+
shell_complete=completion.installable_vocabularies
|
|
280
280
|
)
|
|
281
281
|
@click.option(
|
|
282
282
|
"-a", "--all", "all_",
|
|
@@ -316,7 +316,7 @@ def install_command(app: ApplicationContext, iris: tuple[str, ...], all_):
|
|
|
316
316
|
"iris",
|
|
317
317
|
nargs=-1,
|
|
318
318
|
type=click.STRING,
|
|
319
|
-
|
|
319
|
+
shell_complete=completion.installed_vocabularies
|
|
320
320
|
)
|
|
321
321
|
@click.option(
|
|
322
322
|
"-a", "--all", "all_",
|
|
@@ -355,7 +355,7 @@ def uninstall_command(app: ApplicationContext, iris: tuple[str, ...], all_):
|
|
|
355
355
|
@click.argument(
|
|
356
356
|
"FILE",
|
|
357
357
|
required=True,
|
|
358
|
-
|
|
358
|
+
shell_complete=completion.triple_files,
|
|
359
359
|
type=click.Path(
|
|
360
360
|
allow_dash=False,
|
|
361
361
|
readable=True
|
|
@@ -437,7 +437,7 @@ def import_command(app: ApplicationContext, file, namespace, replace):
|
|
|
437
437
|
"iris",
|
|
438
438
|
nargs=-1,
|
|
439
439
|
type=click.STRING,
|
|
440
|
-
|
|
440
|
+
shell_complete=completion.installed_vocabularies
|
|
441
441
|
)
|
|
442
442
|
@click.option(
|
|
443
443
|
"-a", "--all", "all_",
|