Skip to content

Commit 292a307

Browse files
authored
Refactor/click (#107)
* refactor profile * fix show * use profile_name_arg on all funcs that take one * fix profile_name args in functions * legal hold initial move to click * progress * more progress * functioning security-data * add clear-checkpoint * completed security-data and some misc refactoring * make incremental incompatible * refactor alerts * clean up --begin option validation * fix legalhold state/sdk args and delete a bunch of stuff * start on alert-rules * changes * some help strings and refactor bulk options * remove compat since py2 is no longer supported * start refactoring detectionlists * more refactoring detectionlists * changes * working refactor of departing-employee * HRE refactor plus etc. * fix handle_parse_result funcs to prevent errors on autocomplete * refactor generate_template to shared function * templates and help strings * legal hold help texts * main banner and more help texts * fix reset_pw, some work on refactoring logging exceptions * progress * more logging refactors * done refactoring logger/exceptions/printing * remove uneeded loggers, use echo instead of print in utils * bring in worker fix * refactor progress bar, remove all u-prefixes * progress bar labels and improved help texts * fix bad alerts strings from a pycharm refactor, and a better fix for logging exception handling when BrokenPipe encountered * clean up main * use echo for printing lh policy * correct create profile help * remove util.open_file and usage * encoding * change log_error * remove underscores from packages * line length * bring in saved search work * specify click and colorama min versions * pull in new cursor store changes * add cmd names in bulk helps * remove hyphens and change commands to actions in bulk helps * fix util tests * fix sdk, profile, and logger tests * fix config tests * remove unused imports * fix a bug in profile loading * improve read_flat_file * update generate_template_cmd_factory to allow for flat file templates * correct "remove" templates for DE and HRE to be flat files * fix bulk tests * optimize imports everywhere * fix profile cmd tests * add message to delete-all * fix deprecated callback arg usage * fix alert tests * add check for valid json in --advanced-query arg * fix advanced-query callback to handle None * narrow the exception catching * actually return the arg in the callback * format option correctly in advanced-query error * raise ClickException since it's just an input validation error * fix alerts tests * fix the rest of alert tests * alert-rules tests * make saved-search incompatible with advanced-query * oops, forgot to implement saved-search extraction * fix cursor_store tests * fix file reader callbacks * u prefixes * add bulk alert-rules tests * refactor some fixtures, add some tests, make sure cli_state obj is in all runs * refactor fixtures * move cursor_store and logger_factory tests and a few tweaks elsewhere * securitydata tests * legalhold tests * make runner a fixture, fix departing-employee tests * prevent opening of checkpoint file if --use-checkpoint not actually passed in * fix bug in adding risk tags * rest of fix for risk tags * remove future import * update `generate_template_cmd_factory` to take an arbitrary amount of commands, add `add-risk-tags`/`remove-risk-tags` templates to HRE bulk cmds * better bulk csv testing * fixed HRE tests * fix risk_tag splitting from csv input * add missing @global_options on HRE bulk commands, remove unused RiskTagError * fix test_bulk * fix sdk_client tests * fix py3.5 timezone error * account for potential race in bulk test call arg order * check correct method call * see if sleep fixes intermittent bulk test failure * another check to fix test? * see if side effect helps test * use len(call_args_list) instead of call_count for atomicity due to threads * bulk threading fix for departing employee * fix bug when no profiles exist * optimize imports * attempt thread-safe side effects * complete thread-safe side effects * rename @global_options to @sdk_options * refactor matter member printing * remove unused _current_row attr from BulkProcessor * rename private click command funcs, rework alert-rules `show` logic into _get_rule_type_func * only print inactive when option is passed * update changelog and readme
1 parent ba832b3 commit 292a307

File tree

119 files changed

+4984
-7854
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

119 files changed

+4984
-7854
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ how a consumer would use the library (e.g. adding unit tests, updating documenta
1313
### Changed
1414

1515
- `-i` (`--incremental`) has been removed, use `-c` (`--use-checkpoint`) with a string name for the checkpoint instead.
16+
- The code42cli has been migrated to the [click](https://click.palletsprojects.com) framework. This brings:
17+
- BREAKING CHANGE: Commands that accept multiple values for the same option now must have the option flag provided
18+
before each value:
19+
`--option value1 --option value2` instead of `--option value1 value2` (which was previously possible).
20+
- Cosmetic changes to error messages, progress bars, and help message formatting.
1621

1722
### Added
1823

README.md

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ Use the `code42` command to interact with your Code42 environment.
1010

1111
## Requirements
1212

13-
- Python 2.7.x or 3.5.0+
13+
- Python 3.5.0+
1414
- Code42 Server 6.8.x+
1515

1616
## Installation
1717

1818
Install the `code42` CLI using:
1919

2020
```bash
21-
$ python setup.py install
21+
$ python3 -m pip install code42cli
2222
```
2323

2424
## Usage
@@ -144,7 +144,7 @@ This is only guaranteed if you did not change your query.
144144
To send events to a server using a specific profile, do:
145145

146146
```bash
147-
code42 security-data send-to --profile PROFILE_FOR_RECURRING_JOB syslog.company.com -b 2020-02-02 -f CEF -i
147+
code42 security-data --profile PROFILE_FOR_RECURRING_JOB send-to syslog.company.com -b 2020-02-02 -f CEF -i
148148
```
149149

150150
You can also use wildcard for queries, but note, if they are not in quotes, you may get unexpected behavior.
@@ -173,6 +173,8 @@ Each destination-type subcommand shares query parameters
173173
You cannot use other query parameters if you use `--advanced-query`.
174174
To learn more about acceptable arguments, add the `-h` flag to `code42` or any of the destination-type subcommands.
175175

176+
177+
176178
## Detection Lists
177179

178180
You can both add and remove employees from detection lists using the CLI. This example uses `high-risk-employee`.
@@ -212,16 +214,22 @@ If that doesn't work, delete your credentials file located at ~/.code42cli or th
212214

213215
## Tab completion
214216

215-
For `zsh`, add these commands to your `.zshrc` file:
217+
For Bash, add this to ~/.bashrc:
216218

217-
```bash
218-
C42_COMPLETER=$(which code42cli_completer)
219-
autoload bashcompinit && bashcompinit
220-
complete -C '$C42_COMPLETER' code42
219+
```
220+
eval "$(_CODE42_COMPLETE=source_bash code42)"
221221
```
222222

223-
For bash, add just the first and last commands to your `.bash_profile`:
224-
```bash
225-
C42_COMPLETER=$(which code42cli_completer)
226-
complete -C '$C42_COMPLETER' code42
223+
For Zsh, add this to ~/.zshrc:
224+
227225
```
226+
eval "$(_CODE42_COMPLETE=source_zsh code42)"
227+
```
228+
229+
For Fish, add this to ~/.config/fish/completions/code42.fish:
230+
231+
```
232+
eval (env _CODE42_COMPLETE=source_fish code42)
233+
```
234+
235+
Open a new shell to enable completion. Or run the eval command directly in your current shell to enable it temporarily.

docs/conf.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121

2222
# -- Project information -----------------------------------------------------
2323

24-
project = u"code42cli"
25-
copyright = u"2020, Code42 Software"
26-
author = u"Code42 Software"
24+
project = "code42cli"
25+
copyright = "2020, Code42 Software"
26+
author = "Code42 Software"
2727

2828
# The short X.Y version
2929
version = "code42cli v{}".format(meta.__version__)
@@ -63,7 +63,7 @@
6363
# List of patterns, relative to source directory, that match files and
6464
# directories to ignore when looking for source files.
6565
# This pattern also affects html_static_path and html_extra_path.
66-
exclude_patterns = [u"_build", "Thumbs.db", ".DS_Store"]
66+
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
6767

6868
# The name of the Pygments (syntax highlighting) style to use.
6969
pygments_style = None

integration/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
import pexpect
33

44

5-
LINE_FEED = b'\r\n'
6-
PASSWORD_PROMPT = b'Password: '
7-
ENCODING_TYPE = 'utf-8'
5+
LINE_FEED = b"\r\n"
6+
PASSWORD_PROMPT = b"Password: "
7+
ENCODING_TYPE = "utf-8"
88

99

1010
def encode_response(line, encoding_type=ENCODING_TYPE):

integration/test_alerts.py

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,27 @@ def _validate_field_value(field, value, response):
2020

2121
@pytest.mark.parametrize(
2222
"command, field, value",
23-
[("{} --state OPEN".format(ALERT_COMMAND), "state", "OPEN"),
24-
("{} --state RESOLVED".format(ALERT_COMMAND), "state", "RESOLVED"),
25-
("{} --actor spatel@code42.com".format(ALERT_COMMAND), "actor", "spatel@code42.com"),
26-
("{} --rule-name 'File Upload Alert'".format(ALERT_COMMAND), "name", "File Upload Alert"),
27-
("{} --rule-id 962a6a1c-54f6-4477-90bd-a08cc74cbf71".format(ALERT_COMMAND), "ruleId",
28-
"962a6a1c-54f6-4477-90bd-a08cc74cbf71"),
29-
("{} --rule-type FedEndpointExfiltration".format(ALERT_COMMAND), "type",
30-
"FED_ENDPOINT_EXFILTRATION"),
31-
("{} --description 'Alert on any file upload'".format(ALERT_COMMAND), "description",
32-
"Alert on any file upload events"),
33-
]
23+
[
24+
("{} --state OPEN".format(ALERT_COMMAND), "state", "OPEN"),
25+
("{} --state RESOLVED".format(ALERT_COMMAND), "state", "RESOLVED"),
26+
("{} --actor spatel@code42.com".format(ALERT_COMMAND), "actor", "spatel@code42.com"),
27+
("{} --rule-name 'File Upload Alert'".format(ALERT_COMMAND), "name", "File Upload Alert"),
28+
(
29+
"{} --rule-id 962a6a1c-54f6-4477-90bd-a08cc74cbf71".format(ALERT_COMMAND),
30+
"ruleId",
31+
"962a6a1c-54f6-4477-90bd-a08cc74cbf71",
32+
),
33+
(
34+
"{} --rule-type FedEndpointExfiltration".format(ALERT_COMMAND),
35+
"type",
36+
"FED_ENDPOINT_EXFILTRATION",
37+
),
38+
(
39+
"{} --description 'Alert on any file upload'".format(ALERT_COMMAND),
40+
"description",
41+
"Alert on any file upload events",
42+
),
43+
],
3444
)
3545
def test_alert_prints_to_stdout_and_filters_result_by_given_value(command, field, value):
3646
return_code, response = run_command(command)
@@ -45,9 +55,7 @@ def _validate_begin_date(response):
4555
assert record["createdAt"].startswith("2020-05-18")
4656

4757

48-
@pytest.mark.parametrize("command, validate", [
49-
(ALERT_COMMAND, _validate_begin_date),
50-
])
58+
@pytest.mark.parametrize("command, validate", [(ALERT_COMMAND, _validate_begin_date),])
5159
def test_alert_prints_to_stdout_and_filters_result_between_given_date(command, validate):
5260
return_code, response = run_command(command)
5361
assert return_code is 0
@@ -61,7 +69,9 @@ def _validate_severity(response):
6169

6270
@cleanup_after_validation("./integration/alerts")
6371
def test_alert_writes_to_file_and_filters_result_by_severity():
64-
command = "code42 alerts write-to ./integration/alerts -b 2020-05-18 -e 2020-05-20 " \
65-
"--severity MEDIUM"
72+
command = (
73+
"code42 alerts write-to ./integration/alerts -b 2020-05-18 -e 2020-05-20 "
74+
"--severity MEDIUM"
75+
)
6676
return_code, response = run_command(command)
6777
return _validate_severity

integration/util.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33

44
class cleanup(object):
5-
def __init__(self, filename):
5+
def __init__(self, filename):
66
self.filename = filename
77

88
def __enter__(self):
99
return open(self.filename, "r")
10-
10+
1111
def __exit__(self, exc_type, exc_val, exc_tb):
1212
os.remove(self.filename)
1313

@@ -19,11 +19,14 @@ def cleanup_after_validation(filename):
1919
The decorated function should return validation function that takes the content of the file
2020
as input. e.g `test_alerts.py::test_alert_writes_to_file_and_filters_result_by_severity`
2121
"""
22+
2223
def wrap(test_function):
2324
def wrapper():
2425
validate = test_function()
2526
with cleanup(filename) as f:
2627
response = f.read()
2728
validate(response)
29+
2830
return wrapper
31+
2932
return wrap

setup.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@
2121
package_dir={"": "src"},
2222
python_requires=">3, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4",
2323
install_requires=[
24+
"click>=7.1.1",
25+
"colorama>=0.4.3",
2426
"c42eventextractor==0.3.2",
2527
"keyring==18.0.1",
2628
"keyrings.alt==3.2.0",
29+
"py42>=1.5.1",
2730
],
2831
license="MIT",
2932
include_package_data=True,
@@ -54,5 +57,5 @@
5457
"Programming Language :: Python :: Implementation :: CPython",
5558
],
5659
scripts=["bin/code42cli_completer"],
57-
entry_points={"console_scripts": ["code42=code42cli.main:main"]},
60+
entry_points={"console_scripts": ["code42=code42cli.main:cli"]},
5861
)

src/code42cli/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
PRODUCT_NAME = u"code42cli"
2-
MAIN_COMMAND = u"code42"
1+
PRODUCT_NAME = "code42cli"
2+
MAIN_COMMAND = "code42"

src/code42cli/args.py

Lines changed: 0 additions & 120 deletions
This file was deleted.

0 commit comments

Comments
 (0)