-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathoptions.py
More file actions
225 lines (181 loc) · 6.75 KB
/
Copy pathoptions.py
File metadata and controls
225 lines (181 loc) · 6.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
import click
from code42cli.click_ext.types import MagicDate
from code42cli.click_ext.types import TOTP
from code42cli.cmds.search.options import AdvancedQueryAndSavedSearchIncompatible
from code42cli.cmds.search.options import BeginOption
from code42cli.date_helper import convert_datetime_to_timestamp
from code42cli.date_helper import round_datetime_to_day_end
from code42cli.date_helper import round_datetime_to_day_start
from code42cli.enums import OutputFormat
from code42cli.enums import SendToFileEventsOutputFormat
from code42cli.errors import Code42CLIError
from code42cli.logger.enums import ServerProtocol
from code42cli.profile import get_profile
from code42cli.sdk_client import create_sdk
def yes_option(hidden=False):
return click.option(
"-y",
"--assume-yes",
is_flag=True,
expose_value=False,
callback=lambda ctx, param, value: ctx.obj.set_assume_yes(value),
help='Assume "yes" as the answer to all prompts and run non-interactively.',
hidden=hidden,
)
format_option = click.option(
"-f",
"--format",
type=click.Choice(OutputFormat(), case_sensitive=False),
help="The output format of the result. Defaults to table format.",
default=OutputFormat.TABLE,
)
class CLIState:
def __init__(self):
try:
self._profile = get_profile()
except Code42CLIError:
self._profile = None
self.totp = None
self.debug = False
self._sdk = None
self.search_filters = []
self.assume_yes = False
@property
def profile(self):
if self._profile is None:
self._profile = get_profile()
return self._profile
@profile.setter
def profile(self, value):
self._profile = value
@property
def sdk(self):
if self._sdk is None:
self._sdk = create_sdk(
self.profile,
self.debug,
totp=self.totp,
api_client=self.profile.api_client_auth == "True",
)
return self._sdk
def set_assume_yes(self, param):
self.assume_yes = param
def set_profile(ctx, param, value):
"""Sets the profile on the global state object when --profile <name> is passed to commands
decorated with @sdk_options."""
if value:
ctx.ensure_object(CLIState).profile = get_profile(value)
def set_debug(ctx, param, value):
"""Sets debug to True on global state object when --debug/-d is passed to commands decorated
with @sdk_options.
"""
if value:
ctx.ensure_object(CLIState).debug = value
def set_totp(ctx, param, value):
"""Sets TOTP token on global state object for multi-factor authentication."""
if value:
ctx.ensure_object(CLIState).totp = value
def profile_option(hidden=False):
opt = click.option(
"--profile",
expose_value=False,
callback=set_profile,
hidden=hidden,
help="The name of the Code42 CLI profile to use when executing this command.",
)
return opt
def debug_option(hidden=False):
opt = click.option(
"-d",
"--debug",
is_flag=True,
expose_value=False,
callback=set_debug,
hidden=hidden,
help="Turn on debug logging.",
)
return opt
def totp_option(hidden=False):
opt = click.option(
"--totp",
type=TOTP(),
expose_value=False,
callback=set_totp,
hidden=hidden,
help="TOTP token for multi-factor authentication.",
)
return opt
pass_state = click.make_pass_decorator(CLIState, ensure=True)
def sdk_options(hidden=False):
def decorator(f):
f = profile_option(hidden)(f)
f = totp_option(hidden)(f)
f = debug_option(hidden)(f)
f = pass_state(f)
return f
return decorator
def server_options(f):
hostname_arg = click.argument("hostname")
protocol_option = click.option(
"-p",
"--protocol",
type=click.Choice(ServerProtocol(), case_sensitive=False),
default=ServerProtocol.UDP,
help="Protocol used to send logs to server. Defaults to UDP.",
)
f = hostname_arg(f)
f = protocol_option(f)
return f
send_to_format_options = click.option(
"-f",
"--format",
type=click.Choice(SendToFileEventsOutputFormat(), case_sensitive=False),
help="The output format of the result. Defaults to json format.",
default=SendToFileEventsOutputFormat.RAW,
)
def begin_option(term, **kwargs):
defaults = dict(
type=MagicDate(rounding_func=round_datetime_to_day_start),
help=f"The beginning of the date range in which to look for {term}. {MagicDate.HELP_TEXT} [required unless --use-checkpoint option used]",
cls=BeginOption,
callback=lambda ctx, param, arg: convert_datetime_to_timestamp(arg),
)
defaults.update(kwargs)
return click.option("-b", "--begin", **defaults)
def end_option(term, **kwargs):
defaults = dict(
type=MagicDate(rounding_func=round_datetime_to_day_end),
cls=AdvancedQueryAndSavedSearchIncompatible,
help=f"The end of the date range in which to look for {term}, argument format options are "
"the same as `--begin`.",
callback=lambda ctx, param, arg: convert_datetime_to_timestamp(arg),
)
defaults.update(kwargs)
return click.option("-e", "--end", **defaults)
def checkpoint_option(term, **kwargs):
defaults = dict(
help=f"Use a checkpoint with the given name to only get {term} that were not previously retrieved."
f"If a checkpoint for {term} with the given name doesn't exist, it will be created on the first run."
"Subsequent CLI runs with this flag and the same name will use the stored checkpoint to modify the search query and then update the stored checkpoint"
)
defaults.update(kwargs)
return click.option("-c", "--use-checkpoint", **defaults)
def set_begin_default_dict(term):
return dict(
type=MagicDate(rounding_func=round_datetime_to_day_start),
help=f"The beginning of the date range in which to look for {term}. {MagicDate.HELP_TEXT}",
callback=lambda ctx, param, arg: convert_datetime_to_timestamp(arg),
)
def set_end_default_dict(term):
return dict(
type=MagicDate(rounding_func=round_datetime_to_day_end),
help=f"The end of the date range in which to look for {term}, argument format options are "
"the same as `--begin`.",
callback=lambda ctx, param, arg: convert_datetime_to_timestamp(arg),
)
column_option = click.option(
"--columns",
default=None,
callback=lambda ctx, param, value: value.split(",") if value is not None else None,
help="Filter output to include only specified columns. Accepts comma-separated list of column names (case-insensitive).",
)