prelude-cli-beta 1446__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.
- prelude_cli_beta/__init__.py +0 -0
- prelude_cli_beta/cli.py +52 -0
- prelude_cli_beta/templates/__init__.py +0 -0
- prelude_cli_beta/views/__init__.py +0 -0
- prelude_cli_beta/views/auth.py +56 -0
- prelude_cli_beta/views/build.py +488 -0
- prelude_cli_beta/views/configure.py +29 -0
- prelude_cli_beta/views/detect.py +438 -0
- prelude_cli_beta/views/generate.py +130 -0
- prelude_cli_beta/views/iam.py +368 -0
- prelude_cli_beta/views/jobs.py +50 -0
- prelude_cli_beta/views/partner.py +181 -0
- prelude_cli_beta/views/scm.py +881 -0
- prelude_cli_beta/views/shared.py +37 -0
- prelude_cli_beta-1446.dist-info/METADATA +38 -0
- prelude_cli_beta-1446.dist-info/RECORD +20 -0
- prelude_cli_beta-1446.dist-info/WHEEL +5 -0
- prelude_cli_beta-1446.dist-info/entry_points.txt +3 -0
- prelude_cli_beta-1446.dist-info/licenses/LICENSE +9 -0
- prelude_cli_beta-1446.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from prelude_cli_beta.views.shared import Spinner, pretty_print
|
|
4
|
+
from prelude_sdk_beta.controllers.iam_controller import (
|
|
5
|
+
IAMAccountController,
|
|
6
|
+
IAMUserController,
|
|
7
|
+
)
|
|
8
|
+
from prelude_sdk_beta.models.codes import Mode, Permission
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@click.group()
|
|
12
|
+
@click.pass_context
|
|
13
|
+
def iam(ctx):
|
|
14
|
+
"""Prelude account management"""
|
|
15
|
+
ctx.obj = IAMAccountController(account=ctx.obj)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@iam.command("account")
|
|
19
|
+
@click.pass_obj
|
|
20
|
+
@pretty_print
|
|
21
|
+
def describe_account(controller):
|
|
22
|
+
"""Get account details"""
|
|
23
|
+
with Spinner(description="Fetching account details"):
|
|
24
|
+
return controller.get_account()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@iam.command("purge-account")
|
|
28
|
+
@click.confirmation_option(prompt="Are you sure?")
|
|
29
|
+
@click.pass_obj
|
|
30
|
+
@pretty_print
|
|
31
|
+
def purge_account(controller):
|
|
32
|
+
"""Delete your account"""
|
|
33
|
+
with Spinner(description="Purging account from existence"):
|
|
34
|
+
return controller.purge_account()
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@iam.command("update-account")
|
|
38
|
+
@click.option(
|
|
39
|
+
"-m",
|
|
40
|
+
"--mode",
|
|
41
|
+
help="provide a mode",
|
|
42
|
+
default=None,
|
|
43
|
+
show_default=False,
|
|
44
|
+
type=click.Choice([m.name for m in Mode], case_sensitive=False),
|
|
45
|
+
)
|
|
46
|
+
@click.option(
|
|
47
|
+
"-c",
|
|
48
|
+
"--company",
|
|
49
|
+
help="provide your associated company",
|
|
50
|
+
default=None,
|
|
51
|
+
show_default=False,
|
|
52
|
+
type=str,
|
|
53
|
+
)
|
|
54
|
+
@click.option(
|
|
55
|
+
"-s",
|
|
56
|
+
"--slug",
|
|
57
|
+
help="provide a unique human-readable identifier for your account",
|
|
58
|
+
default=None,
|
|
59
|
+
show_default=False,
|
|
60
|
+
type=str,
|
|
61
|
+
)
|
|
62
|
+
@click.pass_obj
|
|
63
|
+
@pretty_print
|
|
64
|
+
def update_account(controller, mode, company, slug):
|
|
65
|
+
"""Update an account"""
|
|
66
|
+
with Spinner(description="Updating account information"):
|
|
67
|
+
return controller.update_account(
|
|
68
|
+
mode=Mode[mode] if mode else None, company=company, slug=slug
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
@iam.command("attach-oidc")
|
|
73
|
+
@click.argument(
|
|
74
|
+
"issuer", type=click.Choice(["google", "azure", "okta"], case_sensitive=False)
|
|
75
|
+
)
|
|
76
|
+
@click.option("--client_id", required=True, help="Client ID")
|
|
77
|
+
@click.option("--client_secret", required=True, help="Client secret")
|
|
78
|
+
@click.option("--oidc_config_url", required=True, help="Configuration endpoint")
|
|
79
|
+
@click.pass_obj
|
|
80
|
+
@pretty_print
|
|
81
|
+
def attach_oidc(controller, issuer, client_id, client_secret, oidc_config_url):
|
|
82
|
+
"""Attach OIDC to an account"""
|
|
83
|
+
with Spinner(description="Attaching OIDC"):
|
|
84
|
+
return controller.attach_oidc(
|
|
85
|
+
client_id=client_id,
|
|
86
|
+
client_secret=client_secret,
|
|
87
|
+
issuer=issuer,
|
|
88
|
+
oidc_url=oidc_config_url,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@iam.command("detach-oidc")
|
|
93
|
+
@click.confirmation_option(prompt="Are you sure?")
|
|
94
|
+
@click.pass_obj
|
|
95
|
+
@pretty_print
|
|
96
|
+
def detach_oidc(controller):
|
|
97
|
+
"""Detach OIDC to an account"""
|
|
98
|
+
with Spinner(description="Detaching OIDC"):
|
|
99
|
+
return controller.detach_oidc()
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@iam.command("invite-user")
|
|
103
|
+
@click.option(
|
|
104
|
+
"-p",
|
|
105
|
+
"--permission",
|
|
106
|
+
help="user permission level",
|
|
107
|
+
default=Permission.EXECUTIVE.name,
|
|
108
|
+
type=click.Choice(
|
|
109
|
+
[
|
|
110
|
+
p.name
|
|
111
|
+
for p in Permission
|
|
112
|
+
if p not in [Permission.INVALID, Permission.SERVICE, Permission.SUPPORT]
|
|
113
|
+
],
|
|
114
|
+
case_sensitive=False,
|
|
115
|
+
),
|
|
116
|
+
show_default=True,
|
|
117
|
+
)
|
|
118
|
+
@click.option(
|
|
119
|
+
"-n", "--name", help="name of user", default=None, show_default=False, type=str
|
|
120
|
+
)
|
|
121
|
+
@click.option(
|
|
122
|
+
"-o",
|
|
123
|
+
"--oidc",
|
|
124
|
+
help="OIDC app name, or 'none' to login via a password",
|
|
125
|
+
required=True,
|
|
126
|
+
type=str,
|
|
127
|
+
)
|
|
128
|
+
@click.argument("email")
|
|
129
|
+
@click.pass_obj
|
|
130
|
+
@pretty_print
|
|
131
|
+
def invite_user(controller, permission, name, oidc, email):
|
|
132
|
+
"""Invite a new user to your account"""
|
|
133
|
+
with Spinner(description="Inviting new user"):
|
|
134
|
+
data = controller.invite_user(
|
|
135
|
+
email=email,
|
|
136
|
+
oidc="" if oidc.lower() == "none" else oidc,
|
|
137
|
+
permission=Permission[permission],
|
|
138
|
+
name=name,
|
|
139
|
+
)
|
|
140
|
+
msg = "New non-oidc users must check their email to get their temporary password"
|
|
141
|
+
return data, msg
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
@iam.command("create-service-user")
|
|
145
|
+
@click.argument("name")
|
|
146
|
+
@click.pass_obj
|
|
147
|
+
@pretty_print
|
|
148
|
+
def create_service_user(controller, name):
|
|
149
|
+
"""Create a new service user in your account"""
|
|
150
|
+
with Spinner(description="Creating new service user"):
|
|
151
|
+
return controller.create_service_user(name=name)
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
@iam.command("delete-service-user")
|
|
155
|
+
@click.argument("handle")
|
|
156
|
+
@click.pass_obj
|
|
157
|
+
@pretty_print
|
|
158
|
+
def delete_service_user(controller, handle):
|
|
159
|
+
"""Delete a service user from all accounts"""
|
|
160
|
+
with Spinner(description="Deleting service user"):
|
|
161
|
+
return controller.delete_service_user(handle=handle)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@iam.command("update-account-user")
|
|
165
|
+
@click.option(
|
|
166
|
+
"-p",
|
|
167
|
+
"--permission",
|
|
168
|
+
help="user permission level",
|
|
169
|
+
default=Permission.EXECUTIVE.name,
|
|
170
|
+
type=click.Choice(
|
|
171
|
+
[
|
|
172
|
+
p.name
|
|
173
|
+
for p in Permission
|
|
174
|
+
if p not in [Permission.INVALID, Permission.SERVICE, Permission.SUPPORT]
|
|
175
|
+
],
|
|
176
|
+
case_sensitive=False,
|
|
177
|
+
),
|
|
178
|
+
show_default=True,
|
|
179
|
+
)
|
|
180
|
+
@click.option(
|
|
181
|
+
"-o",
|
|
182
|
+
"--oidc",
|
|
183
|
+
help="OIDC app name, or 'none' for non-OIDC users",
|
|
184
|
+
required=True,
|
|
185
|
+
type=str,
|
|
186
|
+
)
|
|
187
|
+
@click.argument("email")
|
|
188
|
+
@click.pass_obj
|
|
189
|
+
@pretty_print
|
|
190
|
+
def update_account_user(controller, permission, oidc, email):
|
|
191
|
+
"""Update a user in your account"""
|
|
192
|
+
with Spinner(description="Updating account user"):
|
|
193
|
+
return controller.update_account_user(
|
|
194
|
+
email=email,
|
|
195
|
+
oidc="" if oidc.lower() == "none" else oidc,
|
|
196
|
+
permission=Permission[permission],
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
@iam.command("remove-user")
|
|
201
|
+
@click.confirmation_option(prompt="Are you sure?")
|
|
202
|
+
@click.option(
|
|
203
|
+
"-o",
|
|
204
|
+
"--oidc",
|
|
205
|
+
help="OIDC app name, or 'none' for non-OIDC users",
|
|
206
|
+
required=True,
|
|
207
|
+
type=str,
|
|
208
|
+
)
|
|
209
|
+
@click.argument("email")
|
|
210
|
+
@click.pass_obj
|
|
211
|
+
@pretty_print
|
|
212
|
+
def remove_user(controller, oidc, email):
|
|
213
|
+
"""Remove a user from your account"""
|
|
214
|
+
with Spinner(description="Removing user"):
|
|
215
|
+
return controller.remove_user(
|
|
216
|
+
email=email, oidc="" if oidc.lower() == "none" else oidc
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
@iam.command("logs")
|
|
221
|
+
@click.option(
|
|
222
|
+
"-d", "--days", help="days back to search from today", default=7, type=int
|
|
223
|
+
)
|
|
224
|
+
@click.option(
|
|
225
|
+
"-l", "--limit", help="limit the number of results", default=1000, type=int
|
|
226
|
+
)
|
|
227
|
+
@click.pass_obj
|
|
228
|
+
@pretty_print
|
|
229
|
+
def logs(controller, days, limit):
|
|
230
|
+
"""Get audit logs"""
|
|
231
|
+
with Spinner(description="Fetching logs"):
|
|
232
|
+
return controller.audit_logs(days=days, limit=limit)
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
@iam.command("sign-up", hidden=True)
|
|
236
|
+
@click.option("-c", "--company", type=str, required=True)
|
|
237
|
+
@click.option("-n", "--name", type=str, required=True)
|
|
238
|
+
@click.argument("email", type=str, required=True)
|
|
239
|
+
@click.pass_obj
|
|
240
|
+
@pretty_print
|
|
241
|
+
def sign_up(controller, company, name, email):
|
|
242
|
+
"""(NOT AVAIABLE IN PRODUCTION) Create a new user and account"""
|
|
243
|
+
with Spinner(description="Creating new user and account"):
|
|
244
|
+
return controller.sign_up(company=company, email=email, name=name)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
@click.group()
|
|
248
|
+
@click.pass_context
|
|
249
|
+
def user(ctx):
|
|
250
|
+
"""Prelude user management"""
|
|
251
|
+
ctx.obj = IAMUserController(account=ctx.obj.account)
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
@user.command("accounts")
|
|
255
|
+
@click.pass_obj
|
|
256
|
+
@pretty_print
|
|
257
|
+
def list_accounts(controller):
|
|
258
|
+
"""List all accounts for your user"""
|
|
259
|
+
with Spinner(description="Fetching all accounts for your user"):
|
|
260
|
+
return controller.list_accounts()
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
@user.command("purge-user")
|
|
264
|
+
@click.confirmation_option(prompt="Are you sure?")
|
|
265
|
+
@click.pass_obj
|
|
266
|
+
@pretty_print
|
|
267
|
+
def purge_user(controller):
|
|
268
|
+
"""Remove your user from all accounts and purge user data"""
|
|
269
|
+
with Spinner(description="Purging user"):
|
|
270
|
+
return controller.purge_user()
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
@user.command("update-user")
|
|
274
|
+
@click.option("-n", "--name", help="name of user", type=str)
|
|
275
|
+
@click.pass_obj
|
|
276
|
+
@pretty_print
|
|
277
|
+
def update_user(controller, name):
|
|
278
|
+
"""Update your user information"""
|
|
279
|
+
with Spinner(description="Updating user"):
|
|
280
|
+
return controller.update_user(name=name)
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
@user.command("forgot-password")
|
|
284
|
+
@click.pass_obj
|
|
285
|
+
@pretty_print
|
|
286
|
+
def forgot_password(controller):
|
|
287
|
+
"""Send a password reset email"""
|
|
288
|
+
with Spinner(description="Sending password reset email"):
|
|
289
|
+
return (
|
|
290
|
+
controller.forgot_password(),
|
|
291
|
+
"Please check your email for a confirmation code",
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
|
|
295
|
+
@user.command("confirm-forgot-password")
|
|
296
|
+
@click.option("-c", "--code", help="confirmation code", required=True)
|
|
297
|
+
@click.option(
|
|
298
|
+
"-n",
|
|
299
|
+
"--new_password",
|
|
300
|
+
help="new password",
|
|
301
|
+
required=True,
|
|
302
|
+
hide_input=True,
|
|
303
|
+
prompt=True,
|
|
304
|
+
)
|
|
305
|
+
@click.option(
|
|
306
|
+
"-r",
|
|
307
|
+
"--confirm_new_password",
|
|
308
|
+
help="confirm new password",
|
|
309
|
+
required=True,
|
|
310
|
+
hide_input=True,
|
|
311
|
+
prompt=True,
|
|
312
|
+
)
|
|
313
|
+
@click.pass_obj
|
|
314
|
+
@pretty_print
|
|
315
|
+
def confirm_forgot_password(controller, code, new_password, confirm_new_password):
|
|
316
|
+
"""Change your password using a confirmation code"""
|
|
317
|
+
if new_password != confirm_new_password:
|
|
318
|
+
raise ValueError("New password and confirmation do not match")
|
|
319
|
+
with Spinner(description="Changing password"):
|
|
320
|
+
return (
|
|
321
|
+
controller.confirm_forgot_password(
|
|
322
|
+
confirmation_code=code, new_password=new_password
|
|
323
|
+
),
|
|
324
|
+
"Password changed successfully",
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
|
|
328
|
+
@user.command("change-password")
|
|
329
|
+
@click.option(
|
|
330
|
+
"-c",
|
|
331
|
+
"--current_password",
|
|
332
|
+
help="current password",
|
|
333
|
+
required=True,
|
|
334
|
+
hide_input=True,
|
|
335
|
+
prompt=True,
|
|
336
|
+
)
|
|
337
|
+
@click.option(
|
|
338
|
+
"-n",
|
|
339
|
+
"--new_password",
|
|
340
|
+
help="new password",
|
|
341
|
+
required=True,
|
|
342
|
+
hide_input=True,
|
|
343
|
+
prompt=True,
|
|
344
|
+
)
|
|
345
|
+
@click.option(
|
|
346
|
+
"-r",
|
|
347
|
+
"--confirm_new_password",
|
|
348
|
+
help="confirm new password",
|
|
349
|
+
required=True,
|
|
350
|
+
hide_input=True,
|
|
351
|
+
prompt=True,
|
|
352
|
+
)
|
|
353
|
+
@click.pass_obj
|
|
354
|
+
@pretty_print
|
|
355
|
+
def change_password(controller, current_password, new_password, confirm_new_password):
|
|
356
|
+
"""Change your password"""
|
|
357
|
+
if new_password != confirm_new_password:
|
|
358
|
+
raise ValueError("New password and confirmation do not match")
|
|
359
|
+
with Spinner(description="Changing password"):
|
|
360
|
+
return (
|
|
361
|
+
controller.change_password(
|
|
362
|
+
current_password=current_password, new_password=new_password
|
|
363
|
+
),
|
|
364
|
+
"Password changed successfully",
|
|
365
|
+
)
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
iam.add_command(user)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from prelude_cli_beta.views.shared import Spinner, pretty_print
|
|
4
|
+
from prelude_sdk_beta.controllers.jobs_controller import JobsController
|
|
5
|
+
from prelude_sdk_beta.models.codes import BackgroundJobTypes
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@click.group()
|
|
9
|
+
@click.pass_context
|
|
10
|
+
def jobs(ctx):
|
|
11
|
+
"""Jobs system commands"""
|
|
12
|
+
ctx.obj = JobsController(account=ctx.obj)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@jobs.command("background-jobs")
|
|
16
|
+
@click.option(
|
|
17
|
+
"-t",
|
|
18
|
+
"--job_type",
|
|
19
|
+
help="filter by job type",
|
|
20
|
+
type=click.Choice(
|
|
21
|
+
[t.name for t in BackgroundJobTypes if t != BackgroundJobTypes.INVALID],
|
|
22
|
+
case_sensitive=False,
|
|
23
|
+
),
|
|
24
|
+
)
|
|
25
|
+
@click.option(
|
|
26
|
+
"-l", "--limit", help="limit the number of jobs returned (per job type)", type=int
|
|
27
|
+
)
|
|
28
|
+
@click.pass_obj
|
|
29
|
+
@pretty_print
|
|
30
|
+
def background_jobs(controller, job_type, limit):
|
|
31
|
+
"""List background jobs"""
|
|
32
|
+
with Spinner(description="Fetching background job statuses"):
|
|
33
|
+
result = controller.job_statuses()
|
|
34
|
+
if job_type:
|
|
35
|
+
result = {job_type: result[job_type]}
|
|
36
|
+
if limit:
|
|
37
|
+
result = {k: v[:limit] for k, v in result.items()}
|
|
38
|
+
return result
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@jobs.command("background-job")
|
|
42
|
+
@click.option(
|
|
43
|
+
"-j", "--job_id", required=True, help="background job ID to retrieve status for"
|
|
44
|
+
)
|
|
45
|
+
@click.pass_obj
|
|
46
|
+
@pretty_print
|
|
47
|
+
def job_status(controller, job_id):
|
|
48
|
+
"""Get status of a given background job"""
|
|
49
|
+
with Spinner(description="Fetching background job status"):
|
|
50
|
+
return controller.job_status(job_id=job_id)
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import click
|
|
2
|
+
|
|
3
|
+
from prelude_cli_beta.views.shared import Spinner, pretty_print
|
|
4
|
+
from prelude_sdk_beta.controllers.partner_controller import PartnerController
|
|
5
|
+
from prelude_sdk_beta.models.codes import Control
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@click.group()
|
|
9
|
+
@click.pass_context
|
|
10
|
+
def partner(ctx):
|
|
11
|
+
"""Partner system commands"""
|
|
12
|
+
ctx.obj = PartnerController(account=ctx.obj)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@partner.command("attach")
|
|
16
|
+
@click.argument(
|
|
17
|
+
"partner",
|
|
18
|
+
type=click.Choice(
|
|
19
|
+
[c.name for c in Control if c != Control.INVALID], case_sensitive=False
|
|
20
|
+
),
|
|
21
|
+
)
|
|
22
|
+
@click.option("--instance_id", help="instance ID of the partner")
|
|
23
|
+
@click.option("--name", help="Friendly name of the partner instance")
|
|
24
|
+
@click.option("--api", help="API endpoint of the partner")
|
|
25
|
+
@click.option("--user", help="user identifier")
|
|
26
|
+
@click.option("--secret", help="secret for OAUTH use cases")
|
|
27
|
+
@click.pass_obj
|
|
28
|
+
@pretty_print
|
|
29
|
+
def attach_partner(controller, partner, instance_id, name, api, user, secret):
|
|
30
|
+
"""Attach an EDR to Detect"""
|
|
31
|
+
with Spinner(description="Attaching partner"):
|
|
32
|
+
return controller.attach(
|
|
33
|
+
partner=Control[partner],
|
|
34
|
+
api=api,
|
|
35
|
+
user=user,
|
|
36
|
+
secret=secret,
|
|
37
|
+
name=name,
|
|
38
|
+
instance_id=instance_id,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@partner.command("detach")
|
|
43
|
+
@click.confirmation_option(prompt="Are you sure?")
|
|
44
|
+
@click.argument(
|
|
45
|
+
"partner",
|
|
46
|
+
type=click.Choice(
|
|
47
|
+
[c.name for c in Control if c != Control.INVALID], case_sensitive=False
|
|
48
|
+
),
|
|
49
|
+
)
|
|
50
|
+
@click.option("--instance_id", required=True, help="instance ID of the partner")
|
|
51
|
+
@click.pass_obj
|
|
52
|
+
@pretty_print
|
|
53
|
+
def detach_partner(controller, partner, instance_id):
|
|
54
|
+
"""Detach an existing partner from your account"""
|
|
55
|
+
with Spinner(description="Detaching partner"):
|
|
56
|
+
return controller.detach(partner=Control[partner], instance_id=instance_id)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
@partner.command("block")
|
|
60
|
+
@click.argument(
|
|
61
|
+
"partner",
|
|
62
|
+
type=click.Choice(
|
|
63
|
+
[c.name for c in Control if c != Control.INVALID], case_sensitive=False
|
|
64
|
+
),
|
|
65
|
+
)
|
|
66
|
+
@click.option("-t", "--test_id", required=True, help="a test to block")
|
|
67
|
+
@click.pass_obj
|
|
68
|
+
@pretty_print
|
|
69
|
+
def partner_block(controller, partner, test_id):
|
|
70
|
+
"""Report to a partner to block a test"""
|
|
71
|
+
with Spinner(description="Reporting test to partner"):
|
|
72
|
+
return controller.block(partner=Control[partner], test_id=test_id)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@partner.command("endpoints")
|
|
76
|
+
@click.argument(
|
|
77
|
+
"partner",
|
|
78
|
+
type=click.Choice(
|
|
79
|
+
[c.name for c in Control if c != Control.INVALID], case_sensitive=False
|
|
80
|
+
),
|
|
81
|
+
)
|
|
82
|
+
@click.option(
|
|
83
|
+
"--platform",
|
|
84
|
+
help='platform name (e.g. "windows")',
|
|
85
|
+
required=True,
|
|
86
|
+
type=click.Choice(["windows", "linux", "darwin"], case_sensitive=False),
|
|
87
|
+
)
|
|
88
|
+
@click.option(
|
|
89
|
+
"--hostname", default="", help='hostname pattern (e.g. "mycompany-c24oi444")'
|
|
90
|
+
)
|
|
91
|
+
@click.option("--offset", default=0, help="API pagination offset", type=int)
|
|
92
|
+
@click.option("--limit", default=100, help="API pagination limit", type=int)
|
|
93
|
+
@click.pass_obj
|
|
94
|
+
@pretty_print
|
|
95
|
+
def partner_endpoints(controller, partner, platform, hostname, offset, limit):
|
|
96
|
+
"""Get a list of endpoints from a partner"""
|
|
97
|
+
with Spinner(description="Fetching endpoints from partner"):
|
|
98
|
+
return controller.endpoints(
|
|
99
|
+
partner=Control[partner],
|
|
100
|
+
platform=platform,
|
|
101
|
+
hostname=hostname,
|
|
102
|
+
offset=offset,
|
|
103
|
+
count=limit,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
@partner.command("deploy")
|
|
108
|
+
@click.confirmation_option(prompt="Are you sure?")
|
|
109
|
+
@click.argument(
|
|
110
|
+
"partner", type=click.Choice([Control.CROWDSTRIKE.name], case_sensitive=False)
|
|
111
|
+
)
|
|
112
|
+
@click.option(
|
|
113
|
+
"--host_ids",
|
|
114
|
+
required=True,
|
|
115
|
+
help="a list of host IDs to deploy to",
|
|
116
|
+
multiple=True,
|
|
117
|
+
default=[],
|
|
118
|
+
)
|
|
119
|
+
@click.pass_obj
|
|
120
|
+
@pretty_print
|
|
121
|
+
def partner_deploy(controller, partner, host_ids):
|
|
122
|
+
"""Deploy probes to hosts associated to a partner"""
|
|
123
|
+
with Spinner(description="Deploying probes to hosts"):
|
|
124
|
+
return controller.deploy(partner=Control[partner], host_ids=host_ids)
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@partner.command("reports")
|
|
128
|
+
@click.argument(
|
|
129
|
+
"partner", type=click.Choice([Control.CROWDSTRIKE.name], case_sensitive=False)
|
|
130
|
+
)
|
|
131
|
+
@click.option("-t", "--test_id", help="test to get reports for")
|
|
132
|
+
@click.pass_obj
|
|
133
|
+
@pretty_print
|
|
134
|
+
def partner_reports(controller, partner, test_id):
|
|
135
|
+
"""Get reports to a partner for a test"""
|
|
136
|
+
with Spinner(description="Getting reports to partner"):
|
|
137
|
+
return controller.list_reports(partner=Control[partner], test_id=test_id)
|
|
138
|
+
|
|
139
|
+
@partner.command("observed-detected")
|
|
140
|
+
@click.option("-t", "--test_id", help="test to get observed/detected stats for")
|
|
141
|
+
@click.option("-h", "--hours", help="number of hours to look back", type=int)
|
|
142
|
+
@click.pass_obj
|
|
143
|
+
@pretty_print
|
|
144
|
+
def observed_detected(controller, test_id, hours):
|
|
145
|
+
"""Get observed / detected stats"""
|
|
146
|
+
with Spinner(description="Getting observed / detected stats"):
|
|
147
|
+
return controller.observed_detected(test_id=test_id, hours=hours)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
@partner.command("advisories")
|
|
151
|
+
@click.argument(
|
|
152
|
+
"partner", type=click.Choice([Control.CROWDSTRIKE.name], case_sensitive=False)
|
|
153
|
+
)
|
|
154
|
+
@click.option("-s", "--start", help="start date for advisories")
|
|
155
|
+
@click.option("-o", "--offset", help="API pagination offset", type=int)
|
|
156
|
+
@click.option("-l", "--limit", help="API pagination limit", type=int)
|
|
157
|
+
@click.pass_obj
|
|
158
|
+
@pretty_print
|
|
159
|
+
def partner_advisories(controller, partner, start, offset, limit):
|
|
160
|
+
"""Get advisories provided by partner"""
|
|
161
|
+
with Spinner(description="Getting partner advisories"):
|
|
162
|
+
return controller.list_advisories(
|
|
163
|
+
partner=Control[partner], start=start, offset=offset, limit=limit
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
@partner.command("groups")
|
|
167
|
+
@click.argument(
|
|
168
|
+
"partner",
|
|
169
|
+
type=click.Choice(
|
|
170
|
+
[c.name for c in Control if c != Control.INVALID], case_sensitive=False
|
|
171
|
+
),
|
|
172
|
+
)
|
|
173
|
+
@click.option("--instance_id", required=True, help="instance ID of the partner")
|
|
174
|
+
@click.pass_obj
|
|
175
|
+
@pretty_print
|
|
176
|
+
def partner_groups(controller, partner, instance_id):
|
|
177
|
+
"""Get a list of groups from a partner"""
|
|
178
|
+
with Spinner(description="Fetching groups from partner"):
|
|
179
|
+
return controller.partner_groups(
|
|
180
|
+
partner=Control[partner], instance_id=instance_id
|
|
181
|
+
)
|