mantis_api_client 5.5.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.
- mantis_api_client/__init__.py +21 -0
- mantis_api_client/cli_parser/account_parser.py +451 -0
- mantis_api_client/cli_parser/attack_parser.py +317 -0
- mantis_api_client/cli_parser/bas_parser.py +1204 -0
- mantis_api_client/cli_parser/basebox_parser.py +258 -0
- mantis_api_client/cli_parser/dataset_parser.py +200 -0
- mantis_api_client/cli_parser/lab_parser.py +805 -0
- mantis_api_client/cli_parser/labs_parser.py +87 -0
- mantis_api_client/cli_parser/log_collector_parser.py +71 -0
- mantis_api_client/cli_parser/redteam_parser.py +375 -0
- mantis_api_client/cli_parser/scenario_parser.py +311 -0
- mantis_api_client/cli_parser/signature_parser.py +147 -0
- mantis_api_client/cli_parser/topology_parser.py +255 -0
- mantis_api_client/cli_parser/user_parser.py +225 -0
- mantis_api_client/config.py +73 -0
- mantis_api_client/dataset_api.py +267 -0
- mantis_api_client/exceptions.py +27 -0
- mantis_api_client/mantis.py +186 -0
- mantis_api_client/oidc.py +302 -0
- mantis_api_client/scenario_api.py +1196 -0
- mantis_api_client/user_api.py +282 -0
- mantis_api_client/utils.py +130 -0
- mantis_api_client-5.5.0.dist-info/AUTHORS +1 -0
- mantis_api_client-5.5.0.dist-info/LICENSE +19 -0
- mantis_api_client-5.5.0.dist-info/METADATA +33 -0
- mantis_api_client-5.5.0.dist-info/RECORD +28 -0
- mantis_api_client-5.5.0.dist-info/WHEEL +4 -0
- mantis_api_client-5.5.0.dist-info/entry_points.txt +3 -0
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import argparse
|
|
3
|
+
import json
|
|
4
|
+
import sys
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from mantis_scenario_model.lab_config_model import LabConfig
|
|
8
|
+
from pydantic.json import pydantic_encoder
|
|
9
|
+
from ruamel.yaml import YAML
|
|
10
|
+
|
|
11
|
+
from mantis_api_client import scenario_api
|
|
12
|
+
from mantis_api_client.oidc import get_oidc_client
|
|
13
|
+
from mantis_api_client.utils import colored
|
|
14
|
+
from mantis_api_client.utils import wait_lab
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
#
|
|
18
|
+
# 'basebox_list_handler' handler
|
|
19
|
+
def basebox_list_handler(args: Any) -> None:
|
|
20
|
+
try:
|
|
21
|
+
baseboxes = sorted(scenario_api.fetch_baseboxes(), key=lambda x: x.id)
|
|
22
|
+
except Exception as e:
|
|
23
|
+
print(colored(f"Error when fetching baseboxes: '{e}'", "red"))
|
|
24
|
+
sys.exit(1)
|
|
25
|
+
|
|
26
|
+
if args.json:
|
|
27
|
+
print(json.dumps(baseboxes, default=pydantic_encoder))
|
|
28
|
+
return
|
|
29
|
+
|
|
30
|
+
print("[+] Available baseboxes:")
|
|
31
|
+
for basebox in baseboxes:
|
|
32
|
+
print(f" [+] {basebox.id}")
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
# 'basebox_info_handler' handler
|
|
37
|
+
#
|
|
38
|
+
def basebox_info_handler(args: Any) -> None:
|
|
39
|
+
# Parameters
|
|
40
|
+
basebox_id = args.basebox_id
|
|
41
|
+
|
|
42
|
+
try:
|
|
43
|
+
basebox = scenario_api.fetch_basebox_by_id(basebox_id)
|
|
44
|
+
except Exception as e:
|
|
45
|
+
print(colored(f"Error when fetching basebox {basebox_id}: '{e}'", "red"))
|
|
46
|
+
sys.exit(1)
|
|
47
|
+
|
|
48
|
+
if args.json:
|
|
49
|
+
print(basebox.json())
|
|
50
|
+
return
|
|
51
|
+
|
|
52
|
+
print("[+] Basebox information:")
|
|
53
|
+
print(f" [+] \033[1mId\033[0m: {basebox.id}")
|
|
54
|
+
print(f" [+] \033[1mDescription\033[0m: {basebox.description}")
|
|
55
|
+
print(f" [+] \033[1mOS\033[0m: {basebox.operating_system} ({basebox.system_type})")
|
|
56
|
+
print(f" [+] \033[1mLanguage\033[0m: {basebox.language}")
|
|
57
|
+
print(f" [+] \033[1mInstallation date\033[0m: {basebox.installation_date}")
|
|
58
|
+
print(" [+] \033[1mCredentials\033[0m:")
|
|
59
|
+
if basebox.username != "" and basebox.username:
|
|
60
|
+
print(f" [+] User: {basebox.username}:{basebox.password}")
|
|
61
|
+
if basebox.admin_username != "" and basebox.admin_username:
|
|
62
|
+
print(
|
|
63
|
+
f" [+] Administrator: {basebox.admin_username}:{basebox.admin_password}"
|
|
64
|
+
)
|
|
65
|
+
print(" [+] \033[1mCPE\033[0m:")
|
|
66
|
+
for cpe in basebox.cpes:
|
|
67
|
+
print(f" [+] {cpe}")
|
|
68
|
+
if basebox.changelog:
|
|
69
|
+
print(" [+] \033[1mChangelog\033[0m:")
|
|
70
|
+
for changelog in basebox.changelog:
|
|
71
|
+
if changelog.get("date", "") != "":
|
|
72
|
+
print(f""" [+] {changelog.get("date")}:""")
|
|
73
|
+
for info in changelog.get("info", "").splitlines():
|
|
74
|
+
print(f""" {info}""")
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _basebox_create_or_run_lab(args: Any, do_run: bool = True):
|
|
78
|
+
# Parameters
|
|
79
|
+
basebox_id = args.basebox_id
|
|
80
|
+
lab_config_path = args.lab_config_path
|
|
81
|
+
|
|
82
|
+
if not args.workspace_id:
|
|
83
|
+
try:
|
|
84
|
+
workspace_id = get_oidc_client().get_default_workspace(raise_exc=True)
|
|
85
|
+
except Exception as e:
|
|
86
|
+
print(colored(f"Error when fetching attacks: '{e}'", "red"))
|
|
87
|
+
sys.exit(1)
|
|
88
|
+
else:
|
|
89
|
+
workspace_id = args.workspace_id
|
|
90
|
+
|
|
91
|
+
# Retrieve associated group id
|
|
92
|
+
if workspace_id is None:
|
|
93
|
+
print(colored("You have to specify a workspace with --workspace", "yellow"))
|
|
94
|
+
sys.exit(1)
|
|
95
|
+
|
|
96
|
+
# Manage lab configuration
|
|
97
|
+
if lab_config_path is None:
|
|
98
|
+
lab_config_dict = {}
|
|
99
|
+
else:
|
|
100
|
+
with open(lab_config_path, "r") as fd:
|
|
101
|
+
yaml_content = fd.read()
|
|
102
|
+
loader = YAML(typ="rt")
|
|
103
|
+
lab_config_dict = loader.load(yaml_content)
|
|
104
|
+
lab_config = LabConfig(**lab_config_dict)
|
|
105
|
+
|
|
106
|
+
# Launch basebox
|
|
107
|
+
try:
|
|
108
|
+
print(f"[+] Going to execute basebox: {basebox_id}")
|
|
109
|
+
|
|
110
|
+
if do_run:
|
|
111
|
+
lab_id = scenario_api.run_lab_basebox(
|
|
112
|
+
basebox_id,
|
|
113
|
+
lab_config,
|
|
114
|
+
workspace_id,
|
|
115
|
+
args.public,
|
|
116
|
+
)
|
|
117
|
+
else:
|
|
118
|
+
lab_id = scenario_api.create_lab_basebox(
|
|
119
|
+
basebox_id,
|
|
120
|
+
lab_config,
|
|
121
|
+
workspace_id,
|
|
122
|
+
args.public,
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
print(f"[+] Lab ID: {lab_id}")
|
|
126
|
+
|
|
127
|
+
if do_run:
|
|
128
|
+
wait_lab(lab_id)
|
|
129
|
+
|
|
130
|
+
except Exception as e:
|
|
131
|
+
print(colored(f"Error when running basebox {basebox_id}: '{e}'", "red"))
|
|
132
|
+
sys.exit(1)
|
|
133
|
+
finally:
|
|
134
|
+
if do_run and args.destroy_after_scenario:
|
|
135
|
+
print("[+] Stopping lab...")
|
|
136
|
+
scenario_api.stop_lab(lab_id)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
#
|
|
140
|
+
# 'basebox_create_lab_handler' handler
|
|
141
|
+
#
|
|
142
|
+
def basebox_create_lab_handler(args: Any) -> None:
|
|
143
|
+
_basebox_create_or_run_lab(args, do_run=False)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
#
|
|
147
|
+
# 'basebox_run_lab_handler' handler
|
|
148
|
+
#
|
|
149
|
+
def basebox_run_lab_handler(args: Any) -> None:
|
|
150
|
+
_basebox_create_or_run_lab(args, do_run=True)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def add_basebox_parser(
|
|
154
|
+
root_parser: argparse.ArgumentParser,
|
|
155
|
+
subparsers: Any,
|
|
156
|
+
) -> None:
|
|
157
|
+
# -------------------
|
|
158
|
+
# --- Scenario API options (baseboxes)
|
|
159
|
+
# -------------------
|
|
160
|
+
|
|
161
|
+
parser_basebox = subparsers.add_parser(
|
|
162
|
+
"basebox",
|
|
163
|
+
help="Scenario API related commands (basebox)",
|
|
164
|
+
formatter_class=root_parser.formatter_class,
|
|
165
|
+
)
|
|
166
|
+
subparsers_basebox = parser_basebox.add_subparsers()
|
|
167
|
+
|
|
168
|
+
# 'basebox_list' command
|
|
169
|
+
parser_basebox_list = subparsers_basebox.add_parser(
|
|
170
|
+
"list",
|
|
171
|
+
help="List all available baseboxes",
|
|
172
|
+
formatter_class=root_parser.formatter_class,
|
|
173
|
+
)
|
|
174
|
+
parser_basebox_list.set_defaults(func=basebox_list_handler)
|
|
175
|
+
parser_basebox_list.add_argument(
|
|
176
|
+
"--json", help="Return JSON result.", action="store_true"
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
# 'basebox_info' command
|
|
180
|
+
parser_basebox_info = subparsers_basebox.add_parser(
|
|
181
|
+
"info",
|
|
182
|
+
help="Get information about a basebox",
|
|
183
|
+
formatter_class=root_parser.formatter_class,
|
|
184
|
+
)
|
|
185
|
+
parser_basebox_info.set_defaults(func=basebox_info_handler)
|
|
186
|
+
parser_basebox_info.add_argument("basebox_id", type=str, help="The basebox ID")
|
|
187
|
+
parser_basebox_info.add_argument(
|
|
188
|
+
"--json", help="Return JSON result.", action="store_true"
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
# 'basebox_create_lab' command
|
|
192
|
+
parser_basebox_create_lab = subparsers_basebox.add_parser(
|
|
193
|
+
"create",
|
|
194
|
+
help="Create a lab with a specific basebox",
|
|
195
|
+
formatter_class=root_parser.formatter_class,
|
|
196
|
+
)
|
|
197
|
+
parser_basebox_create_lab.set_defaults(func=basebox_create_lab_handler)
|
|
198
|
+
parser_basebox_create_lab.add_argument(
|
|
199
|
+
"basebox_id", type=str, help="The basebox ID"
|
|
200
|
+
)
|
|
201
|
+
parser_basebox_create_lab.add_argument(
|
|
202
|
+
"--destroy",
|
|
203
|
+
action="store_true",
|
|
204
|
+
dest="destroy_after_scenario",
|
|
205
|
+
help="Do not keep the lab up after basebox execution (False by default)",
|
|
206
|
+
)
|
|
207
|
+
parser_basebox_create_lab.add_argument(
|
|
208
|
+
"--workspace",
|
|
209
|
+
dest="workspace_id",
|
|
210
|
+
help="The group ID that have ownership on lab",
|
|
211
|
+
)
|
|
212
|
+
parser_basebox_create_lab.add_argument(
|
|
213
|
+
"--lab_config",
|
|
214
|
+
action="store",
|
|
215
|
+
required=False,
|
|
216
|
+
dest="lab_config_path",
|
|
217
|
+
help="Input path of a YAML configuration for the scenario to run",
|
|
218
|
+
)
|
|
219
|
+
parser_basebox_create_lab.add_argument(
|
|
220
|
+
"--public",
|
|
221
|
+
action="store_true",
|
|
222
|
+
help="Create a public link to access this lab",
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
# 'basebox_run_lab' command
|
|
226
|
+
parser_basebox_run_lab = subparsers_basebox.add_parser(
|
|
227
|
+
"run",
|
|
228
|
+
help="Create and run a lab with a specific basebox",
|
|
229
|
+
formatter_class=root_parser.formatter_class,
|
|
230
|
+
)
|
|
231
|
+
parser_basebox_run_lab.set_defaults(func=basebox_run_lab_handler)
|
|
232
|
+
parser_basebox_run_lab.add_argument("basebox_id", type=str, help="The basebox ID")
|
|
233
|
+
parser_basebox_run_lab.add_argument(
|
|
234
|
+
"--destroy",
|
|
235
|
+
action="store_true",
|
|
236
|
+
dest="destroy_after_scenario",
|
|
237
|
+
help="Do not keep the lab up after basebox execution (False by default)",
|
|
238
|
+
)
|
|
239
|
+
parser_basebox_run_lab.add_argument(
|
|
240
|
+
"--workspace",
|
|
241
|
+
dest="workspace_id",
|
|
242
|
+
help="The group ID that have ownership on lab",
|
|
243
|
+
)
|
|
244
|
+
parser_basebox_run_lab.add_argument(
|
|
245
|
+
"--lab_config",
|
|
246
|
+
"-lc",
|
|
247
|
+
action="store",
|
|
248
|
+
required=False,
|
|
249
|
+
dest="lab_config_path",
|
|
250
|
+
help="Input path of a YAML configuration for the scenario run",
|
|
251
|
+
)
|
|
252
|
+
parser_basebox_run_lab.add_argument(
|
|
253
|
+
"--public",
|
|
254
|
+
action="store_true",
|
|
255
|
+
help="Create a public link to access this lab",
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
parser_basebox.set_defaults(func=lambda _: parser_basebox.print_help())
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import argparse
|
|
3
|
+
import json
|
|
4
|
+
import time
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from typing import Any
|
|
7
|
+
from typing import Dict
|
|
8
|
+
from typing import List
|
|
9
|
+
from typing import NoReturn
|
|
10
|
+
from uuid import UUID
|
|
11
|
+
|
|
12
|
+
from mantis_dataset_model.dataset_model import PartialManifest
|
|
13
|
+
from pydantic.json import pydantic_encoder
|
|
14
|
+
from rich.console import Console
|
|
15
|
+
|
|
16
|
+
from mantis_api_client import dataset_api
|
|
17
|
+
from mantis_api_client.exceptions import ConfigException
|
|
18
|
+
from mantis_api_client.oidc import get_oidc_client
|
|
19
|
+
from mantis_api_client.utils import colored
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
print = Console().print
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# 'datasets_list_handler' handler
|
|
27
|
+
#
|
|
28
|
+
def datasets_list_handler(args: Any) -> None:
|
|
29
|
+
try:
|
|
30
|
+
datasets: Dict[str, List[Dict[UUID, PartialManifest]]] = (
|
|
31
|
+
dataset_api.fetch_datasets()
|
|
32
|
+
)
|
|
33
|
+
except ConfigException as e:
|
|
34
|
+
print("{} You should run `mantis init` again to login to M&ntis SSO.", e)
|
|
35
|
+
exit(1)
|
|
36
|
+
except Exception as e:
|
|
37
|
+
print(colored(f"Error when listing datasets: '{e}'", "red"))
|
|
38
|
+
exit(1)
|
|
39
|
+
|
|
40
|
+
if args.json:
|
|
41
|
+
print(json.dumps(datasets, default=pydantic_encoder))
|
|
42
|
+
return
|
|
43
|
+
|
|
44
|
+
print("[+] Available datasets:")
|
|
45
|
+
for dataset in datasets:
|
|
46
|
+
if len(datasets[dataset]) > 0:
|
|
47
|
+
print(f" [+] Datasets of '{dataset}': ")
|
|
48
|
+
for d in datasets[dataset]:
|
|
49
|
+
for id in d:
|
|
50
|
+
print(
|
|
51
|
+
f""" [+] {id} - {d[id]['name']} ({d[id]["date_dataset_created"]})"""
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
#
|
|
56
|
+
# 'datasets_info_handler' handler
|
|
57
|
+
#
|
|
58
|
+
def datasets_info_handler(args: Any) -> None:
|
|
59
|
+
# Parameters
|
|
60
|
+
dataset_id = args.dataset_id
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
dataset = dataset_api.fetch_dataset_by_uuid(dataset_id)
|
|
64
|
+
except Exception as e:
|
|
65
|
+
print(colored(f"Error when fetching dataset: '{e}'", "red"))
|
|
66
|
+
exit(1)
|
|
67
|
+
|
|
68
|
+
if args.json:
|
|
69
|
+
print(dataset.json())
|
|
70
|
+
return
|
|
71
|
+
|
|
72
|
+
print("[+] Dataset information: ")
|
|
73
|
+
print(f" [+] \033[1mName\033[0m: {dataset.name}")
|
|
74
|
+
print(f" [+] \033[1mDescription\033[0m: {dataset.description}")
|
|
75
|
+
print(f" [+] \033[1mCreation date\033[0m: {dataset.date_dataset_created}")
|
|
76
|
+
if dataset.scenario: # scenario is optional
|
|
77
|
+
if (
|
|
78
|
+
"timestamps" in dataset.scenario
|
|
79
|
+
and "duration" in dataset.scenario["timestamps"]
|
|
80
|
+
):
|
|
81
|
+
print(f" [+] Duration: {dataset.scenario['timestamps']['duration']}")
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
# 'datasets_push_handler' handler
|
|
86
|
+
#
|
|
87
|
+
def datasets_push_handler(args: Any) -> None | NoReturn:
|
|
88
|
+
"""
|
|
89
|
+
Handler to upload dataset to remote
|
|
90
|
+
|
|
91
|
+
An attempt is performed to send the dataset and make it available to workspace WORKSPACE (--workspace).
|
|
92
|
+
"""
|
|
93
|
+
# Parameters
|
|
94
|
+
dataset_path: Path = args.dataset_path
|
|
95
|
+
workspace_id: UUID | None = args.workspace
|
|
96
|
+
uploaded: bool = False
|
|
97
|
+
error_msg: str = ""
|
|
98
|
+
|
|
99
|
+
if not args.public:
|
|
100
|
+
_workspace_id: str | None = None
|
|
101
|
+
if not workspace_id:
|
|
102
|
+
_workspace_id = get_oidc_client().get_default_workspace()
|
|
103
|
+
if not _workspace_id:
|
|
104
|
+
print("[b red]No default workspace found. [/b red]Run `mantis login`.")
|
|
105
|
+
exit(1)
|
|
106
|
+
workspace_id = UUID(_workspace_id)
|
|
107
|
+
|
|
108
|
+
if dataset_path.exists() is False:
|
|
109
|
+
print(f"[b red]The dataset path '{dataset_path}' does not exist.")
|
|
110
|
+
exit(1)
|
|
111
|
+
|
|
112
|
+
if args.public:
|
|
113
|
+
print("[+] Uploading dataset accessible to anyone")
|
|
114
|
+
else:
|
|
115
|
+
print(f"[+] Uploading dataset accessible to workspace: {workspace_id}")
|
|
116
|
+
|
|
117
|
+
# Uploading the dataset
|
|
118
|
+
dataset_id = dataset_api.upload_dataset(dataset_path, workspace_id)
|
|
119
|
+
print(f" [+] Dataset id: {dataset_id}")
|
|
120
|
+
|
|
121
|
+
# Checking the status of the task
|
|
122
|
+
timeout = 300 # seconds
|
|
123
|
+
start = time.time()
|
|
124
|
+
finished = False
|
|
125
|
+
while time.time() - start < timeout and finished is False:
|
|
126
|
+
res = dataset_api.upload_dataset_status(dataset_id)
|
|
127
|
+
try:
|
|
128
|
+
state = res["status"]
|
|
129
|
+
error_msg = res["message"]
|
|
130
|
+
except KeyError:
|
|
131
|
+
error_msg = res.get("detail", "Unknown error")
|
|
132
|
+
break
|
|
133
|
+
if state in ["FINISHED", "FINISHED_ERROR"]:
|
|
134
|
+
finished = True
|
|
135
|
+
uploaded = state == "FINISHED"
|
|
136
|
+
else:
|
|
137
|
+
print(" [+] Dataset verification in progress")
|
|
138
|
+
time.sleep(1)
|
|
139
|
+
|
|
140
|
+
if uploaded is False:
|
|
141
|
+
print(colored(f" [-] The dataset could not be uploaded: {error_msg}", "red"))
|
|
142
|
+
else:
|
|
143
|
+
print(" [+] Successfully uploaded the dataset.")
|
|
144
|
+
return None
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def add_dataset_parser(root_parser: argparse.ArgumentParser, subparsers: Any) -> None:
|
|
148
|
+
|
|
149
|
+
# -------------------
|
|
150
|
+
# --- Dataset API options
|
|
151
|
+
# -------------------
|
|
152
|
+
|
|
153
|
+
parser_dataset = subparsers.add_parser(
|
|
154
|
+
"dataset",
|
|
155
|
+
help="Dataset API related commands",
|
|
156
|
+
formatter_class=root_parser.formatter_class,
|
|
157
|
+
)
|
|
158
|
+
subparsers_dataset = parser_dataset.add_subparsers()
|
|
159
|
+
|
|
160
|
+
# 'datasets_list' command
|
|
161
|
+
parser_dataset_list = subparsers_dataset.add_parser(
|
|
162
|
+
"list",
|
|
163
|
+
help="List all available datasets",
|
|
164
|
+
formatter_class=root_parser.formatter_class,
|
|
165
|
+
)
|
|
166
|
+
parser_dataset_list.set_defaults(func=datasets_list_handler)
|
|
167
|
+
parser_dataset_list.add_argument(
|
|
168
|
+
"--json", help="Return JSON result.", action="store_true"
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
# 'datasets_info' command
|
|
172
|
+
parser_datasets_info = subparsers_dataset.add_parser(
|
|
173
|
+
"info",
|
|
174
|
+
help="Get information about a dataset",
|
|
175
|
+
formatter_class=root_parser.formatter_class,
|
|
176
|
+
)
|
|
177
|
+
parser_datasets_info.set_defaults(func=datasets_info_handler)
|
|
178
|
+
parser_datasets_info.add_argument("dataset_id", type=str, help="The dataset id")
|
|
179
|
+
parser_datasets_info.add_argument(
|
|
180
|
+
"--json", help="Return JSON result.", action="store_true"
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
parser_datasets_push = subparsers_dataset.add_parser(
|
|
184
|
+
"push",
|
|
185
|
+
help="Upload a local dataset .zip file to the remote",
|
|
186
|
+
formatter_class=root_parser.formatter_class,
|
|
187
|
+
)
|
|
188
|
+
parser_datasets_push.set_defaults(func=datasets_push_handler)
|
|
189
|
+
pubpriv_group = parser_datasets_push.add_mutually_exclusive_group()
|
|
190
|
+
pubpriv_group.add_argument(
|
|
191
|
+
"--workspace",
|
|
192
|
+
type=UUID,
|
|
193
|
+
metavar="WORKSPACE_UUID",
|
|
194
|
+
help="Workspace to which this dataset belongs",
|
|
195
|
+
)
|
|
196
|
+
pubpriv_group.add_argument("--public", action="store_true")
|
|
197
|
+
parser_datasets_push.add_argument(
|
|
198
|
+
"dataset_path", type=Path, help="Path to the dataset .zip file to upload"
|
|
199
|
+
)
|
|
200
|
+
parser_dataset.set_defaults(func=lambda _: parser_dataset.print_help())
|