azdev 0.1.74__tar.gz → 0.1.77__tar.gz
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.
- {azdev-0.1.74 → azdev-0.1.77}/HISTORY.rst +12 -0
- {azdev-0.1.74/azdev.egg-info → azdev-0.1.77}/PKG-INFO +13 -1
- {azdev-0.1.74 → azdev-0.1.77}/azdev/__init__.py +1 -1
- {azdev-0.1.74 → azdev-0.1.77}/azdev/help.py +3 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/extensions/version_upgrade.py +10 -1
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/secret.py +80 -36
- {azdev-0.1.74 → azdev-0.1.77}/azdev/params.py +10 -2
- {azdev-0.1.74 → azdev-0.1.77/azdev.egg-info}/PKG-INFO +13 -1
- {azdev-0.1.74 → azdev-0.1.77}/LICENSE +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/MANIFEST.in +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/README.md +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/README.rst +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/__main__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/commands.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/completer.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/config/__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/config/cli.flake8 +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/config/cli_pylintrc +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/config/ext.flake8 +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/config/ext_pylintrc +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/mod_templates/HISTORY.rst +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/mod_templates/README.rst +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/mod_templates/_client_factory.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/mod_templates/_help.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/mod_templates/_params.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/mod_templates/_validators.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/mod_templates/azext_metadata.json +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/mod_templates/blank__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/mod_templates/commands.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/mod_templates/custom.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/mod_templates/module__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/mod_templates/pkg_declare__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/mod_templates/setup.cfg +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/mod_templates/setup.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/mod_templates/test_service_scenario.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/cmdcov/__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/cmdcov/_macros.j2 +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/cmdcov/cmdcov.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/cmdcov/component.css +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/cmdcov/component.js +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/cmdcov/favicon.ico +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/cmdcov/index.j2 +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/cmdcov/index2.j2 +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/cmdcov/module.j2 +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/code_gen.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/command_change/__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/command_change/custom.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/command_change/util.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/constant.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/extensions/__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/extensions/util.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/help/__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/help/refdoc/__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/help/refdoc/conf.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/legal.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/linter/__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/linter/linter.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/linter/pylint_checkers/__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/linter/pylint_checkers/show_command.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/linter/rule_decorators.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/linter/rules/__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/linter/rules/ci_exclusions.yml +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/linter/rules/command_coverage_rules.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/linter/rules/command_group_rules.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/linter/rules/command_rules.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/linter/rules/help_rules.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/linter/rules/linter_exclusions.yml +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/linter/rules/parameter_rules.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/linter/util.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/performance.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/pypi.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/python_sdk.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/regex.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/resource.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/setup.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/statistics/__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/statistics/util.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/style.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/testtool/__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/testtool/incremental_strategy.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/testtool/profile_context.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/operations/testtool/pytest_runner.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/transformers.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/utilities/__init__.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/utilities/command.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/utilities/config.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/utilities/const.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/utilities/display.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/utilities/git_util.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/utilities/path.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/utilities/pypi.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/utilities/testing.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev/utilities/tools.py +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev.egg-info/SOURCES.txt +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev.egg-info/dependency_links.txt +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev.egg-info/entry_points.txt +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev.egg-info/requires.txt +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/azdev.egg-info/top_level.txt +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/pyproject.toml +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/setup.cfg +0 -0
- {azdev-0.1.74 → azdev-0.1.77}/setup.py +0 -0
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
Release History
|
|
4
4
|
===============
|
|
5
|
+
0.1.77
|
|
6
|
+
++++++
|
|
7
|
+
* `azdev extension cal-next-version`: Fix pre_num when tagged preview version with `major`, `minor`, `patch`.
|
|
8
|
+
|
|
9
|
+
0.1.76
|
|
10
|
+
++++++
|
|
11
|
+
* `azdev extension cal-next-version`: Fix preview to stable version case.
|
|
12
|
+
|
|
13
|
+
0.1.75
|
|
14
|
+
++++++
|
|
15
|
+
* `azdev scan/mask`: Add `--include-pattern` and `--exclude-pattern` to support filtering files within directory
|
|
16
|
+
|
|
5
17
|
0.1.74
|
|
6
18
|
++++++
|
|
7
19
|
* `azdev scan/mask`: New commands for scanning and masking secrets for files or string
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: azdev
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.77
|
|
4
4
|
Summary: Microsoft Azure CLI Developer Tools
|
|
5
5
|
Home-page: https://github.com/Azure/azure-cli-dev-tools
|
|
6
6
|
Author: Microsoft Corporation
|
|
@@ -146,6 +146,18 @@ License
|
|
|
146
146
|
|
|
147
147
|
Release History
|
|
148
148
|
===============
|
|
149
|
+
0.1.77
|
|
150
|
+
++++++
|
|
151
|
+
* `azdev extension cal-next-version`: Fix pre_num when tagged preview version with `major`, `minor`, `patch`.
|
|
152
|
+
|
|
153
|
+
0.1.76
|
|
154
|
+
++++++
|
|
155
|
+
* `azdev extension cal-next-version`: Fix preview to stable version case.
|
|
156
|
+
|
|
157
|
+
0.1.75
|
|
158
|
+
++++++
|
|
159
|
+
* `azdev scan/mask`: Add `--include-pattern` and `--exclude-pattern` to support filtering files within directory
|
|
160
|
+
|
|
149
161
|
0.1.74
|
|
150
162
|
++++++
|
|
151
163
|
* `azdev scan/mask`: New commands for scanning and masking secrets for files or string
|
|
@@ -193,6 +193,9 @@ helps['scan'] = """
|
|
|
193
193
|
- name: Recursively scan secrets for a directory and save results to specific file
|
|
194
194
|
text: |
|
|
195
195
|
azdev scan --directory-path /path/to/my/folder --recursive --scan-result-path /path/to/scan_result.json
|
|
196
|
+
- name: Scan secrets for all json files and yaml files within a directory
|
|
197
|
+
text: |
|
|
198
|
+
azdev scan --directory-path /path/to/my/folder --include-pattern *.yaml *.json
|
|
196
199
|
"""
|
|
197
200
|
|
|
198
201
|
helps['mask'] = """
|
|
@@ -123,18 +123,25 @@ class VersionUpgradeMod:
|
|
|
123
123
|
self.next_version.init_preview_version()
|
|
124
124
|
return
|
|
125
125
|
|
|
126
|
+
if self.next_version_pre_tag == VERSION_STABLE_TAG and self.is_preview:
|
|
127
|
+
# 2.0.0bN -> stable > 2.0.0
|
|
128
|
+
return
|
|
129
|
+
|
|
126
130
|
if self.next_version_segment_tag:
|
|
127
131
|
if self.next_version_segment_tag == VERSION_MAJOR_TAG:
|
|
128
132
|
self.next_version.major = self.version.major + 1
|
|
129
133
|
self.next_version.minor = 0
|
|
130
134
|
self.next_version.patch = 0
|
|
135
|
+
self.next_version.pre_num = 1
|
|
131
136
|
elif self.next_version_segment_tag == VERSION_MINOR_TAG:
|
|
132
137
|
self.next_version.minor = self.version.minor + 1
|
|
133
138
|
self.next_version.patch = 0
|
|
139
|
+
self.next_version.pre_num = 1
|
|
134
140
|
elif self.next_version_segment_tag == VERSION_PATCH_TAG:
|
|
135
141
|
self.next_version.patch = self.version.micro + 1
|
|
142
|
+
self.next_version.pre_num = 1
|
|
136
143
|
elif self.next_version_segment_tag == VERSION_PRE_TAG:
|
|
137
|
-
self.next_version.
|
|
144
|
+
self.next_version.pre_num = (self.version.pre and self.version.pre[1] or 0) + 1
|
|
138
145
|
else:
|
|
139
146
|
raise ValueError("Unsupported segment tag: {0}".format(self.next_version_segment_tag))
|
|
140
147
|
return
|
|
@@ -155,6 +162,8 @@ class VersionUpgradeMod:
|
|
|
155
162
|
self.next_version.major = self.version.major + 1
|
|
156
163
|
self.next_version.minor = 0
|
|
157
164
|
self.next_version.patch = 0
|
|
165
|
+
if self.is_preview:
|
|
166
|
+
self.next_version.pre_num = 1
|
|
158
167
|
elif len(self.diffs) > 0:
|
|
159
168
|
if self.is_preview:
|
|
160
169
|
self.next_version.pre_num = self.version.pre[1] + 1
|
|
@@ -14,7 +14,7 @@ from microsoft_security_utilities_secret_masker import (load_regex_patterns_from
|
|
|
14
14
|
logger = get_logger(__name__)
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
def _validate_data_path(file_path=None, directory_path=None, data=None):
|
|
17
|
+
def _validate_data_path(file_path=None, directory_path=None, include_pattern=None, exclude_pattern=None, data=None):
|
|
18
18
|
if file_path and directory_path:
|
|
19
19
|
raise ValueError('Can not specify file path and directory path at the same time')
|
|
20
20
|
if file_path and data:
|
|
@@ -28,6 +28,51 @@ def _validate_data_path(file_path=None, directory_path=None, data=None):
|
|
|
28
28
|
raise ValueError(f'invalid directory path:{directory_path}')
|
|
29
29
|
if file_path and not os.path.isfile(file_path):
|
|
30
30
|
raise ValueError(f'invalid file path:{file_path}')
|
|
31
|
+
if not directory_path and include_pattern:
|
|
32
|
+
raise ValueError('--include-pattern need to be used together with --directory-path')
|
|
33
|
+
if not directory_path and exclude_pattern:
|
|
34
|
+
raise ValueError('--exclude-pattern need to be used together with --directory-path')
|
|
35
|
+
if include_pattern and exclude_pattern:
|
|
36
|
+
raise ValueError('--include-pattern and --exclude-pattern are mutually exclusive')
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _is_file_name_in_patterns(filename, patterns):
|
|
40
|
+
if not filename or not patterns:
|
|
41
|
+
return None
|
|
42
|
+
import fnmatch
|
|
43
|
+
for pattern in patterns:
|
|
44
|
+
if fnmatch.fnmatch(filename, pattern):
|
|
45
|
+
return True
|
|
46
|
+
return False
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def _check_file_include_and_exclude_pattern(filename, include_pattern=None, exclude_pattern=None):
|
|
50
|
+
file_satisfied = True
|
|
51
|
+
if include_pattern and not _is_file_name_in_patterns(filename, include_pattern):
|
|
52
|
+
file_satisfied = False
|
|
53
|
+
if exclude_pattern and _is_file_name_in_patterns(filename, exclude_pattern):
|
|
54
|
+
file_satisfied = False
|
|
55
|
+
return file_satisfied
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _get_files_from_directory(directory_path, recursive=None, include_pattern=None, exclude_pattern=None):
|
|
59
|
+
target_files = []
|
|
60
|
+
if recursive:
|
|
61
|
+
for root, _, files in os.walk(directory_path):
|
|
62
|
+
for file in files:
|
|
63
|
+
if _check_file_include_and_exclude_pattern(file,
|
|
64
|
+
include_pattern=include_pattern,
|
|
65
|
+
exclude_pattern=exclude_pattern):
|
|
66
|
+
target_files.append(os.path.join(root, file))
|
|
67
|
+
else:
|
|
68
|
+
for file in os.listdir(directory_path):
|
|
69
|
+
if _check_file_include_and_exclude_pattern(file,
|
|
70
|
+
include_pattern=include_pattern,
|
|
71
|
+
exclude_pattern=exclude_pattern):
|
|
72
|
+
file = os.path.join(directory_path, file)
|
|
73
|
+
if os.path.isfile(file):
|
|
74
|
+
target_files.append(file)
|
|
75
|
+
return target_files
|
|
31
76
|
|
|
32
77
|
|
|
33
78
|
def _load_built_in_regex_patterns():
|
|
@@ -88,21 +133,17 @@ def _scan_secrets_for_string(data, custom_pattern=None):
|
|
|
88
133
|
return secrets
|
|
89
134
|
|
|
90
135
|
|
|
91
|
-
def scan_secrets(file_path=None, directory_path=None, recursive=False,
|
|
136
|
+
def scan_secrets(file_path=None, directory_path=None, recursive=False,
|
|
137
|
+
include_pattern=None, exclude_pattern=None, data=None,
|
|
92
138
|
save_scan_result=None, scan_result_path=None, custom_pattern=None):
|
|
93
|
-
_validate_data_path(file_path=file_path, directory_path=directory_path,
|
|
139
|
+
_validate_data_path(file_path=file_path, directory_path=directory_path,
|
|
140
|
+
include_pattern=include_pattern, exclude_pattern=exclude_pattern, data=data)
|
|
94
141
|
target_files = []
|
|
95
142
|
scan_results = {}
|
|
96
143
|
if directory_path:
|
|
97
144
|
directory_path = os.path.abspath(directory_path)
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
target_files.extend(os.path.join(root, file) for file in files)
|
|
101
|
-
else:
|
|
102
|
-
for file in os.listdir(directory_path):
|
|
103
|
-
file = os.path.join(directory_path, file)
|
|
104
|
-
if os.path.isfile(file):
|
|
105
|
-
target_files.append(file)
|
|
145
|
+
target_files = _get_files_from_directory(directory_path, recursive=recursive,
|
|
146
|
+
include_pattern=include_pattern, exclude_pattern=exclude_pattern)
|
|
106
147
|
if file_path:
|
|
107
148
|
file_path = os.path.abspath(file_path)
|
|
108
149
|
target_files.append(file_path)
|
|
@@ -114,7 +155,7 @@ def scan_secrets(file_path=None, directory_path=None, recursive=False, data=None
|
|
|
114
155
|
elif target_files:
|
|
115
156
|
for target_file in target_files:
|
|
116
157
|
logger.debug('start scanning secrets for %s', target_file)
|
|
117
|
-
with open(target_file) as f:
|
|
158
|
+
with open(target_file, encoding='utf8') as f:
|
|
118
159
|
data = f.read()
|
|
119
160
|
if not data:
|
|
120
161
|
continue
|
|
@@ -140,41 +181,37 @@ def scan_secrets(file_path=None, directory_path=None, recursive=False, data=None
|
|
|
140
181
|
file_folder = os.path.join(get_azdev_config_dir(), 'scan_results')
|
|
141
182
|
if not os.path.exists(file_folder):
|
|
142
183
|
os.mkdir(file_folder, 0o755)
|
|
143
|
-
|
|
144
|
-
result_file_name = 'scan_result_' + file_name.replace('.', '_') + '.json'
|
|
184
|
+
result_file_name = 'scan_result_' + datetime.now().strftime('%Y%m%d%H%M%S') + '.json'
|
|
145
185
|
scan_result_path = os.path.join(file_folder, result_file_name)
|
|
146
186
|
|
|
147
|
-
with open(scan_result_path, 'w') as f:
|
|
187
|
+
with open(scan_result_path, 'w', encoding='utf8') as f:
|
|
148
188
|
json.dump(scan_results, f)
|
|
149
189
|
logger.debug('store scanning results in %s', scan_result_path)
|
|
150
190
|
return {'secrets_detected': True, 'scan_result_path': os.path.abspath(scan_result_path)}
|
|
151
191
|
|
|
152
192
|
|
|
153
193
|
def _get_scan_results_from_saved_file(saved_scan_result_path,
|
|
154
|
-
file_path=None, directory_path=None, recursive=False,
|
|
194
|
+
file_path=None, directory_path=None, recursive=False,
|
|
195
|
+
include_pattern=None, exclude_pattern=None, data=None):
|
|
155
196
|
scan_results = {}
|
|
156
197
|
if not os.path.isfile(saved_scan_result_path):
|
|
157
198
|
raise ValueError(f'invalid saved scan result path:{saved_scan_result_path}')
|
|
158
|
-
with open(saved_scan_result_path) as f:
|
|
199
|
+
with open(saved_scan_result_path, encoding='utf8') as f:
|
|
159
200
|
saved_scan_results = json.load(f)
|
|
160
201
|
# filter saved scan results to keep those related with specified file(s)
|
|
161
|
-
_validate_data_path(file_path=file_path, directory_path=directory_path,
|
|
202
|
+
_validate_data_path(file_path=file_path, directory_path=directory_path,
|
|
203
|
+
include_pattern=include_pattern, exclude_pattern=exclude_pattern, data=data)
|
|
162
204
|
if file_path:
|
|
163
205
|
file_path = os.path.abspath(file_path)
|
|
164
206
|
if file_path in saved_scan_results:
|
|
165
207
|
scan_results[file_path] = saved_scan_results[file_path]
|
|
166
208
|
elif directory_path:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
else:
|
|
174
|
-
for file in os.listdir(directory_path):
|
|
175
|
-
file_full = os.path.join(directory_path, file)
|
|
176
|
-
if file_full in saved_scan_results:
|
|
177
|
-
scan_results[file_full] = saved_scan_results[file_full]
|
|
209
|
+
directory_path = os.path.abspath(directory_path)
|
|
210
|
+
target_files = _get_files_from_directory(directory_path, recursive=recursive,
|
|
211
|
+
include_pattern=include_pattern, exclude_pattern=exclude_pattern)
|
|
212
|
+
for target_file in target_files:
|
|
213
|
+
if target_file in saved_scan_results:
|
|
214
|
+
scan_results[target_file] = saved_scan_results[target_file]
|
|
178
215
|
else:
|
|
179
216
|
scan_results['raw_data'] = saved_scan_results['raw_data']
|
|
180
217
|
|
|
@@ -193,19 +230,26 @@ def _mask_secret_for_string(data, secret, redaction_type=None):
|
|
|
193
230
|
return data
|
|
194
231
|
|
|
195
232
|
|
|
196
|
-
def mask_secrets(file_path=None, directory_path=None, recursive=False,
|
|
233
|
+
def mask_secrets(file_path=None, directory_path=None, recursive=False,
|
|
234
|
+
include_pattern=None, exclude_pattern=None, data=None,
|
|
197
235
|
save_scan_result=None, scan_result_path=None, custom_pattern=None,
|
|
198
236
|
saved_scan_result_path=None, redaction_type='FIXED_VALUE', yes=None):
|
|
199
237
|
scan_results = {}
|
|
200
238
|
if saved_scan_result_path:
|
|
201
|
-
scan_results = _get_scan_results_from_saved_file(saved_scan_result_path,
|
|
202
|
-
|
|
239
|
+
scan_results = _get_scan_results_from_saved_file(saved_scan_result_path,
|
|
240
|
+
file_path=file_path,
|
|
241
|
+
directory_path=directory_path,
|
|
242
|
+
recursive=recursive,
|
|
243
|
+
include_pattern=include_pattern,
|
|
244
|
+
exclude_pattern=exclude_pattern,
|
|
245
|
+
data=data)
|
|
203
246
|
else:
|
|
204
|
-
scan_response = scan_secrets(file_path=file_path, directory_path=directory_path, recursive=recursive,
|
|
247
|
+
scan_response = scan_secrets(file_path=file_path, directory_path=directory_path, recursive=recursive,
|
|
248
|
+
include_pattern=include_pattern, exclude_pattern=exclude_pattern, data=data,
|
|
205
249
|
save_scan_result=save_scan_result, scan_result_path=scan_result_path,
|
|
206
250
|
custom_pattern=custom_pattern)
|
|
207
251
|
if save_scan_result and scan_response['scan_result_path']:
|
|
208
|
-
with open(scan_response['scan_result_path']) as f:
|
|
252
|
+
with open(scan_response['scan_result_path'], encoding='utf8') as f:
|
|
209
253
|
scan_results = json.load(f)
|
|
210
254
|
elif not save_scan_result:
|
|
211
255
|
scan_results = scan_response['scan_results']
|
|
@@ -235,13 +279,13 @@ def mask_secrets(file_path=None, directory_path=None, recursive=False, data=None
|
|
|
235
279
|
return mask_result
|
|
236
280
|
|
|
237
281
|
for scan_file_path, secrets in scan_results.items():
|
|
238
|
-
with open(scan_file_path, 'r') as f:
|
|
282
|
+
with open(scan_file_path, 'r', encoding='utf8') as f:
|
|
239
283
|
content = f.read()
|
|
240
284
|
if not content:
|
|
241
285
|
continue
|
|
242
286
|
for secret in secrets:
|
|
243
287
|
content = _mask_secret_for_string(content, secret, redaction_type)
|
|
244
|
-
with open(scan_file_path, 'w') as f:
|
|
288
|
+
with open(scan_file_path, 'w', encoding='utf8') as f:
|
|
245
289
|
f.write(content)
|
|
246
290
|
mask_result['mask'] = True
|
|
247
291
|
return mask_result
|
|
@@ -109,14 +109,22 @@ def load_arguments(self, _):
|
|
|
109
109
|
help='Path of the folder you want to scan secrets for')
|
|
110
110
|
c.argument('recursive', options_list=['--recursive', '-r'],
|
|
111
111
|
help='Scan the directory recursively')
|
|
112
|
+
c.argument('include_pattern', options_list=['--include-pattern', '--include'], nargs='*',
|
|
113
|
+
help="Space separated patterns used for files you want to include within the directory. "
|
|
114
|
+
"The supported patterns are '*', '?', '[seq]', and '[!seq]'. "
|
|
115
|
+
"For more information, please refer to https://docs.python.org/3/library/fnmatch.html")
|
|
116
|
+
c.argument('exclude_pattern', options_list=['--exclude-pattern', '--exclude'], nargs='*',
|
|
117
|
+
help="Space separated patterns used for files you want to exclude within the directory. "
|
|
118
|
+
"The supported patterns are '*', '?', '[seq]', and '[!seq]'. "
|
|
119
|
+
"For more information, please refer to https://docs.python.org/3/library/fnmatch.html")
|
|
112
120
|
c.argument('data', help='Raw string you want to scan secrets for')
|
|
113
|
-
c.argument('save_scan_result', options_list=['--save-scan-result', '--save'],
|
|
121
|
+
c.argument('save_scan_result', options_list=['--save-scan-result', '--save'], action='store_true',
|
|
114
122
|
help='Whether to save scan result to file or not')
|
|
115
123
|
c.argument('scan_result_path', options_list=['--scan-result-path', '--result'],
|
|
116
124
|
help='Path for the file you want to save the result in. '
|
|
117
125
|
'If specified, --save-scan-result will be True anyway. '
|
|
118
126
|
'If not speficied but set --save-scan-result to True, '
|
|
119
|
-
'the file will be saved as `
|
|
127
|
+
'the file will be saved as `scan_result_YYYYmmddHHMMSS.json` in your `.azdev` directory ')
|
|
120
128
|
c.argument('custom_pattern',
|
|
121
129
|
help='Additional patterns you want to apply or built-in patterns you want to exclude '
|
|
122
130
|
'for scanning. Can be json string or path to the json file.')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: azdev
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.77
|
|
4
4
|
Summary: Microsoft Azure CLI Developer Tools
|
|
5
5
|
Home-page: https://github.com/Azure/azure-cli-dev-tools
|
|
6
6
|
Author: Microsoft Corporation
|
|
@@ -146,6 +146,18 @@ License
|
|
|
146
146
|
|
|
147
147
|
Release History
|
|
148
148
|
===============
|
|
149
|
+
0.1.77
|
|
150
|
+
++++++
|
|
151
|
+
* `azdev extension cal-next-version`: Fix pre_num when tagged preview version with `major`, `minor`, `patch`.
|
|
152
|
+
|
|
153
|
+
0.1.76
|
|
154
|
+
++++++
|
|
155
|
+
* `azdev extension cal-next-version`: Fix preview to stable version case.
|
|
156
|
+
|
|
157
|
+
0.1.75
|
|
158
|
+
++++++
|
|
159
|
+
* `azdev scan/mask`: Add `--include-pattern` and `--exclude-pattern` to support filtering files within directory
|
|
160
|
+
|
|
149
161
|
0.1.74
|
|
150
162
|
++++++
|
|
151
163
|
* `azdev scan/mask`: New commands for scanning and masking secrets for files or string
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|