iam-policy-validator 1.10.3__py3-none-any.whl → 1.11.1__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.
- iam_policy_validator-1.11.1.dist-info/METADATA +782 -0
- {iam_policy_validator-1.10.3.dist-info → iam_policy_validator-1.11.1.dist-info}/RECORD +25 -21
- iam_validator/__version__.py +1 -1
- iam_validator/checks/action_condition_enforcement.py +27 -14
- iam_validator/checks/sensitive_action.py +123 -11
- iam_validator/checks/utils/policy_level_checks.py +47 -10
- iam_validator/commands/__init__.py +6 -0
- iam_validator/commands/completion.py +467 -0
- iam_validator/commands/query.py +485 -0
- iam_validator/commands/validate.py +21 -26
- iam_validator/core/config/category_suggestions.py +77 -0
- iam_validator/core/config/condition_requirements.py +105 -54
- iam_validator/core/config/defaults.py +82 -6
- iam_validator/core/config/wildcards.py +3 -0
- iam_validator/core/diff_parser.py +321 -0
- iam_validator/core/formatters/enhanced.py +34 -27
- iam_validator/core/models.py +2 -0
- iam_validator/core/pr_commenter.py +179 -51
- iam_validator/core/report.py +19 -17
- iam_validator/integrations/github_integration.py +250 -1
- iam_validator/sdk/__init__.py +33 -0
- iam_validator/sdk/query_utils.py +454 -0
- iam_policy_validator-1.10.3.dist-info/METADATA +0 -549
- {iam_policy_validator-1.10.3.dist-info → iam_policy_validator-1.11.1.dist-info}/WHEEL +0 -0
- {iam_policy_validator-1.10.3.dist-info → iam_policy_validator-1.11.1.dist-info}/entry_points.txt +0 -0
- {iam_policy_validator-1.10.3.dist-info → iam_policy_validator-1.11.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,467 @@
|
|
|
1
|
+
"""Generate shell completion scripts for iam-validator.
|
|
2
|
+
|
|
3
|
+
This command generates completion scripts for bash and zsh shells.
|
|
4
|
+
The generated scripts provide intelligent autocompletion for:
|
|
5
|
+
- Command names (validate, query, analyze, etc.)
|
|
6
|
+
- Command options (--service, --access-level, etc.)
|
|
7
|
+
- Cached AWS service names (for --service flag)
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
# Bash completion
|
|
11
|
+
iam-validator completion bash > ~/.bash_completion.d/iam-validator
|
|
12
|
+
source ~/.bash_completion.d/iam-validator
|
|
13
|
+
|
|
14
|
+
# Zsh completion
|
|
15
|
+
iam-validator completion zsh > ~/.zsh/completion/_iam-validator
|
|
16
|
+
# Then add to ~/.zshrc: fpath=(~/.zsh/completion $fpath)
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import argparse
|
|
20
|
+
import logging
|
|
21
|
+
|
|
22
|
+
from iam_validator.commands.base import Command
|
|
23
|
+
from iam_validator.core.aws_service.storage import ServiceFileStorage
|
|
24
|
+
|
|
25
|
+
logger = logging.getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class CompletionCommand(Command):
|
|
29
|
+
"""Generate shell completion scripts."""
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def name(self) -> str:
|
|
33
|
+
"""Command name."""
|
|
34
|
+
return "completion"
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def help(self) -> str:
|
|
38
|
+
"""Command help text."""
|
|
39
|
+
return "Generate shell completion scripts (bash or zsh)"
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def epilog(self) -> str:
|
|
43
|
+
"""Command epilog with examples."""
|
|
44
|
+
return """
|
|
45
|
+
examples:
|
|
46
|
+
# Generate bash completion
|
|
47
|
+
iam-validator completion bash > ~/.bash_completion.d/iam-validator
|
|
48
|
+
source ~/.bash_completion.d/iam-validator
|
|
49
|
+
|
|
50
|
+
# Generate zsh completion
|
|
51
|
+
iam-validator completion zsh > ~/.zsh/completion/_iam-validator
|
|
52
|
+
# Add to ~/.zshrc: fpath=(~/.zsh/completion $fpath)
|
|
53
|
+
|
|
54
|
+
# Direct evaluation (bash)
|
|
55
|
+
eval "$(iam-validator completion bash)"
|
|
56
|
+
|
|
57
|
+
# Direct evaluation (zsh)
|
|
58
|
+
eval "$(iam-validator completion zsh)"
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
def add_arguments(self, parser: argparse.ArgumentParser) -> None:
|
|
62
|
+
"""Add completion command arguments."""
|
|
63
|
+
parser.add_argument(
|
|
64
|
+
"shell",
|
|
65
|
+
choices=["bash", "zsh"],
|
|
66
|
+
help="Shell type to generate completion for",
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
async def execute(self, args: argparse.Namespace) -> int:
|
|
70
|
+
"""Execute completion command."""
|
|
71
|
+
try:
|
|
72
|
+
if args.shell == "bash":
|
|
73
|
+
script = self._generate_bash_completion()
|
|
74
|
+
else: # zsh
|
|
75
|
+
script = self._generate_zsh_completion()
|
|
76
|
+
|
|
77
|
+
print(script)
|
|
78
|
+
return 0
|
|
79
|
+
|
|
80
|
+
except Exception as e: # pylint: disable=broad-exception-caught
|
|
81
|
+
logger.error(f"Failed to generate completion: {e}", exc_info=True)
|
|
82
|
+
return 1
|
|
83
|
+
|
|
84
|
+
def _get_cached_services(self) -> list[str]:
|
|
85
|
+
"""Get list of cached AWS service names.
|
|
86
|
+
|
|
87
|
+
Returns:
|
|
88
|
+
List of service names that are cached locally.
|
|
89
|
+
Returns empty list if cache is not available.
|
|
90
|
+
"""
|
|
91
|
+
try:
|
|
92
|
+
storage = ServiceFileStorage()
|
|
93
|
+
cache_dir = storage.cache_directory
|
|
94
|
+
|
|
95
|
+
if not cache_dir.exists():
|
|
96
|
+
return []
|
|
97
|
+
|
|
98
|
+
# Look for cached service files
|
|
99
|
+
# Files are named like: s3_{hash}.json or services_list.json
|
|
100
|
+
services = set()
|
|
101
|
+
|
|
102
|
+
for cache_file in cache_dir.glob("*.json"):
|
|
103
|
+
filename = cache_file.stem
|
|
104
|
+
# Extract service name from cache filename
|
|
105
|
+
# Format: servicename_hash or services_list
|
|
106
|
+
if filename == "services_list":
|
|
107
|
+
continue
|
|
108
|
+
# Extract service name (before underscore)
|
|
109
|
+
if "_" in filename:
|
|
110
|
+
service_name = filename.split("_")[0]
|
|
111
|
+
services.add(service_name)
|
|
112
|
+
|
|
113
|
+
return sorted(list(services))
|
|
114
|
+
|
|
115
|
+
except Exception as e: # pylint: disable=broad-exception-caught
|
|
116
|
+
logger.debug(f"Could not load cached services: {e}")
|
|
117
|
+
return []
|
|
118
|
+
|
|
119
|
+
def _generate_bash_completion(self) -> str:
|
|
120
|
+
"""Generate bash completion script.
|
|
121
|
+
|
|
122
|
+
Returns:
|
|
123
|
+
Bash completion script as string
|
|
124
|
+
"""
|
|
125
|
+
cached_services = self._get_cached_services()
|
|
126
|
+
services_list = " ".join(cached_services) if cached_services else ""
|
|
127
|
+
|
|
128
|
+
return f'''# Bash completion for iam-validator
|
|
129
|
+
# Generated by: iam-validator completion bash
|
|
130
|
+
|
|
131
|
+
_iam_validator_completion() {{
|
|
132
|
+
local cur prev opts base
|
|
133
|
+
COMPREPLY=()
|
|
134
|
+
cur="${{COMP_WORDS[COMP_CWORD]}}"
|
|
135
|
+
prev="${{COMP_WORDS[COMP_CWORD-1]}}"
|
|
136
|
+
|
|
137
|
+
# Main commands
|
|
138
|
+
local commands="validate post-to-pr analyze cache sync-services query completion"
|
|
139
|
+
|
|
140
|
+
# Get the command (first non-option argument)
|
|
141
|
+
local cmd=""
|
|
142
|
+
for ((i=1; i<COMP_CWORD; i++)); do
|
|
143
|
+
if [[ ${{COMP_WORDS[i]}} != -* ]]; then
|
|
144
|
+
cmd=${{COMP_WORDS[i]}}
|
|
145
|
+
break
|
|
146
|
+
fi
|
|
147
|
+
done
|
|
148
|
+
|
|
149
|
+
# Complete main command if we're at the first argument
|
|
150
|
+
if [[ $COMP_CWORD -eq 1 ]]; then
|
|
151
|
+
COMPREPLY=( $(compgen -W "$commands" -- "$cur") )
|
|
152
|
+
return 0
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
# Completion based on previous argument
|
|
156
|
+
case "$prev" in
|
|
157
|
+
--service)
|
|
158
|
+
# Provide cached service names
|
|
159
|
+
local services="{services_list}"
|
|
160
|
+
COMPREPLY=( $(compgen -W "$services" -- "$cur") )
|
|
161
|
+
return 0
|
|
162
|
+
;;
|
|
163
|
+
--access-level)
|
|
164
|
+
COMPREPLY=( $(compgen -W "read write list tagging permissions-management" -- "$cur") )
|
|
165
|
+
return 0
|
|
166
|
+
;;
|
|
167
|
+
--format|-f)
|
|
168
|
+
COMPREPLY=( $(compgen -W "console enhanced json markdown html csv sarif" -- "$cur") )
|
|
169
|
+
return 0
|
|
170
|
+
;;
|
|
171
|
+
--policy-type|-t)
|
|
172
|
+
COMPREPLY=( $(compgen -W "IDENTITY_POLICY RESOURCE_POLICY TRUST_POLICY SERVICE_CONTROL_POLICY RESOURCE_CONTROL_POLICY" -- "$cur") )
|
|
173
|
+
return 0
|
|
174
|
+
;;
|
|
175
|
+
--output|-o)
|
|
176
|
+
# Context-aware: file for validate, format for query
|
|
177
|
+
if [[ "$cmd" == "query" ]]; then
|
|
178
|
+
COMPREPLY=( $(compgen -W "json yaml text" -- "$cur") )
|
|
179
|
+
else
|
|
180
|
+
COMPREPLY=( $(compgen -f -- "$cur") )
|
|
181
|
+
fi
|
|
182
|
+
return 0
|
|
183
|
+
;;
|
|
184
|
+
--path|-p|--config|-c|--custom-checks-dir|--aws-services-dir)
|
|
185
|
+
# File/directory completion
|
|
186
|
+
COMPREPLY=( $(compgen -f -- "$cur") )
|
|
187
|
+
return 0
|
|
188
|
+
;;
|
|
189
|
+
--resource-type|--condition|--name|--batch-size)
|
|
190
|
+
# Allow any input
|
|
191
|
+
return 0
|
|
192
|
+
;;
|
|
193
|
+
completion)
|
|
194
|
+
COMPREPLY=( $(compgen -W "bash zsh" -- "$cur") )
|
|
195
|
+
return 0
|
|
196
|
+
;;
|
|
197
|
+
esac
|
|
198
|
+
|
|
199
|
+
# Command-specific completions
|
|
200
|
+
case "$cmd" in
|
|
201
|
+
query)
|
|
202
|
+
# Check if we need to complete the query subcommand
|
|
203
|
+
local query_subcmd=""
|
|
204
|
+
for ((i=2; i<COMP_CWORD; i++)); do
|
|
205
|
+
if [[ ${{COMP_WORDS[i]}} =~ ^(action|arn|condition)$ ]]; then
|
|
206
|
+
query_subcmd=${{COMP_WORDS[i]}}
|
|
207
|
+
break
|
|
208
|
+
fi
|
|
209
|
+
done
|
|
210
|
+
|
|
211
|
+
if [[ -z "$query_subcmd" ]]; then
|
|
212
|
+
# Complete query subcommand
|
|
213
|
+
COMPREPLY=( $(compgen -W "action arn condition" -- "$cur") )
|
|
214
|
+
return 0
|
|
215
|
+
fi
|
|
216
|
+
|
|
217
|
+
# Complete options for query subcommands
|
|
218
|
+
local opts=""
|
|
219
|
+
case "$query_subcmd" in
|
|
220
|
+
action)
|
|
221
|
+
opts="--service --name --access-level --resource-type --condition --output"
|
|
222
|
+
;;
|
|
223
|
+
arn)
|
|
224
|
+
opts="--service --name --list-arn-types --output"
|
|
225
|
+
;;
|
|
226
|
+
condition)
|
|
227
|
+
opts="--service --name --output"
|
|
228
|
+
;;
|
|
229
|
+
esac
|
|
230
|
+
|
|
231
|
+
# Filter out already used options
|
|
232
|
+
local used_opts=""
|
|
233
|
+
for ((i=2; i<COMP_CWORD; i++)); do
|
|
234
|
+
if [[ ${{COMP_WORDS[i]}} == --* ]]; then
|
|
235
|
+
used_opts="$used_opts ${{COMP_WORDS[i]}}"
|
|
236
|
+
fi
|
|
237
|
+
done
|
|
238
|
+
|
|
239
|
+
local available_opts=""
|
|
240
|
+
for opt in $opts; do
|
|
241
|
+
if [[ ! " $used_opts " =~ " $opt " ]]; then
|
|
242
|
+
available_opts="$available_opts $opt"
|
|
243
|
+
fi
|
|
244
|
+
done
|
|
245
|
+
|
|
246
|
+
COMPREPLY=( $(compgen -W "$available_opts" -- "$cur") )
|
|
247
|
+
return 0
|
|
248
|
+
;;
|
|
249
|
+
validate)
|
|
250
|
+
opts="--path -p --stdin --format -f --output -o --no-recursive --fail-on-warnings --policy-type -t --github-comment --github-review --github-summary --verbose -v --config -c --custom-checks-dir --aws-services-dir --stream --batch-size --summary --severity-breakdown"
|
|
251
|
+
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
252
|
+
return 0
|
|
253
|
+
;;
|
|
254
|
+
post-to-pr)
|
|
255
|
+
opts="--report -r --create-review --no-review --add-summary --no-summary --config -c"
|
|
256
|
+
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
257
|
+
return 0
|
|
258
|
+
;;
|
|
259
|
+
analyze)
|
|
260
|
+
opts="--path -p --policy-type -t --region --profile --format -f --output -o --no-recursive --fail-on-warnings --github-comment --github-review --github-summary --run-all-checks --check-access-not-granted --check-access-resources --check-no-new-access --check-no-public-access --public-access-resource-type --verbose -v"
|
|
261
|
+
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
262
|
+
return 0
|
|
263
|
+
;;
|
|
264
|
+
cache)
|
|
265
|
+
# Check if we need to complete the cache subcommand
|
|
266
|
+
local cache_subcmd=""
|
|
267
|
+
for ((i=2; i<COMP_CWORD; i++)); do
|
|
268
|
+
if [[ ${{COMP_WORDS[i]}} =~ ^(info|list|clear|refresh|prefetch|location)$ ]]; then
|
|
269
|
+
cache_subcmd=${{COMP_WORDS[i]}}
|
|
270
|
+
break
|
|
271
|
+
fi
|
|
272
|
+
done
|
|
273
|
+
|
|
274
|
+
if [[ -z "$cache_subcmd" ]]; then
|
|
275
|
+
# Complete cache subcommand
|
|
276
|
+
COMPREPLY=( $(compgen -W "info list clear refresh prefetch location" -- "$cur") )
|
|
277
|
+
return 0
|
|
278
|
+
fi
|
|
279
|
+
# Cache subcommands have no additional options
|
|
280
|
+
return 0
|
|
281
|
+
;;
|
|
282
|
+
sync-services)
|
|
283
|
+
opts="--output-dir --max-concurrent"
|
|
284
|
+
COMPREPLY=( $(compgen -W "$opts" -- "$cur") )
|
|
285
|
+
return 0
|
|
286
|
+
;;
|
|
287
|
+
esac
|
|
288
|
+
|
|
289
|
+
return 0
|
|
290
|
+
}}
|
|
291
|
+
|
|
292
|
+
complete -F _iam_validator_completion iam-validator
|
|
293
|
+
'''
|
|
294
|
+
|
|
295
|
+
def _generate_zsh_completion(self) -> str:
|
|
296
|
+
"""Generate zsh completion script.
|
|
297
|
+
|
|
298
|
+
Returns:
|
|
299
|
+
Zsh completion script as string
|
|
300
|
+
"""
|
|
301
|
+
cached_services = self._get_cached_services()
|
|
302
|
+
# For zsh, we need to format as: 'service1' 'service2' ...
|
|
303
|
+
services_list = " ".join(f"'{svc}'" for svc in cached_services) if cached_services else ""
|
|
304
|
+
|
|
305
|
+
return f"""#compdef iam-validator
|
|
306
|
+
# Zsh completion for iam-validator
|
|
307
|
+
# Generated by: iam-validator completion zsh
|
|
308
|
+
|
|
309
|
+
_iam_validator() {{
|
|
310
|
+
local curcontext="$curcontext" state line
|
|
311
|
+
typeset -A opt_args
|
|
312
|
+
|
|
313
|
+
# Cached AWS services
|
|
314
|
+
local -a aws_services
|
|
315
|
+
aws_services=({services_list})
|
|
316
|
+
|
|
317
|
+
_arguments -C \\
|
|
318
|
+
'1: :_iam_validator_commands' \\
|
|
319
|
+
'*::arg:->args'
|
|
320
|
+
|
|
321
|
+
case $state in
|
|
322
|
+
args)
|
|
323
|
+
case $words[1] in
|
|
324
|
+
query)
|
|
325
|
+
local query_state
|
|
326
|
+
_arguments -C \\
|
|
327
|
+
'1: :_iam_validator_query_subcommands' \\
|
|
328
|
+
'*::arg:->query_args' && return 0
|
|
329
|
+
|
|
330
|
+
case $state in
|
|
331
|
+
query_args)
|
|
332
|
+
case $words[1] in
|
|
333
|
+
action)
|
|
334
|
+
_arguments \\
|
|
335
|
+
'--service[AWS service name]:service:($aws_services)' \\
|
|
336
|
+
'--name[Action name]:action name:' \\
|
|
337
|
+
'--access-level[Filter by access level]:access level:(read write list tagging permissions-management)' \\
|
|
338
|
+
'--resource-type[Filter by resource type]:resource type:' \\
|
|
339
|
+
'--condition[Filter by condition key]:condition key:' \\
|
|
340
|
+
'--output[Output format]:format:(json yaml text)'
|
|
341
|
+
;;
|
|
342
|
+
arn)
|
|
343
|
+
_arguments \\
|
|
344
|
+
'--service[AWS service name]:service:($aws_services)' \\
|
|
345
|
+
'--name[ARN resource type]:arn type:' \\
|
|
346
|
+
'--list-arn-types[List all ARN types]' \\
|
|
347
|
+
'--output[Output format]:format:(json yaml text)'
|
|
348
|
+
;;
|
|
349
|
+
condition)
|
|
350
|
+
_arguments \\
|
|
351
|
+
'--service[AWS service name]:service:($aws_services)' \\
|
|
352
|
+
'--name[Condition key name]:condition key:' \\
|
|
353
|
+
'--output[Output format]:format:(json yaml text)'
|
|
354
|
+
;;
|
|
355
|
+
esac
|
|
356
|
+
;;
|
|
357
|
+
esac
|
|
358
|
+
;;
|
|
359
|
+
validate)
|
|
360
|
+
_arguments \\
|
|
361
|
+
'*--path[Path to policy file or directory]:file:_files' \\
|
|
362
|
+
'*-p[Path to policy file or directory]:file:_files' \\
|
|
363
|
+
'--stdin[Read policy from stdin]' \\
|
|
364
|
+
'(--format -f)'{{--format,-f}}'[Output format]:format:(console enhanced json markdown html csv sarif)' \\
|
|
365
|
+
'(--output -o)'{{--output,-o}}'[Output file path]:file:_files' \\
|
|
366
|
+
'--no-recursive[Do not recursively search directories]' \\
|
|
367
|
+
'--fail-on-warnings[Fail validation if warnings are found]' \\
|
|
368
|
+
'(--policy-type -t)'{{--policy-type,-t}}'[Type of IAM policy]:policy type:(IDENTITY_POLICY RESOURCE_POLICY TRUST_POLICY SERVICE_CONTROL_POLICY RESOURCE_CONTROL_POLICY)' \\
|
|
369
|
+
'--github-comment[Post summary comment to PR]' \\
|
|
370
|
+
'--github-review[Create line-specific review comments]' \\
|
|
371
|
+
'--github-summary[Write to GitHub Actions job summary]' \\
|
|
372
|
+
'(--verbose -v)'{{--verbose,-v}}'[Enable verbose logging]' \\
|
|
373
|
+
'(--config -c)'{{--config,-c}}'[Configuration file]:file:_files' \\
|
|
374
|
+
'--custom-checks-dir[Custom checks directory]:directory:_directories' \\
|
|
375
|
+
'--aws-services-dir[AWS service definitions directory]:directory:_directories' \\
|
|
376
|
+
'--stream[Process files one-by-one]' \\
|
|
377
|
+
'--batch-size[Policies per batch]:number:' \\
|
|
378
|
+
'--summary[Show Executive Summary section]' \\
|
|
379
|
+
'--severity-breakdown[Show Issue Severity Breakdown section]'
|
|
380
|
+
;;
|
|
381
|
+
post-to-pr)
|
|
382
|
+
_arguments \\
|
|
383
|
+
'(--report -r)'{{--report,-r}}'[Path to JSON report file]:file:_files' \\
|
|
384
|
+
'--create-review[Create line-specific review comments]' \\
|
|
385
|
+
'--no-review[Do not create line-specific review comments]' \\
|
|
386
|
+
'--add-summary[Add summary comment]' \\
|
|
387
|
+
'--no-summary[Do not add summary comment]' \\
|
|
388
|
+
'(--config -c)'{{--config,-c}}'[Configuration file]:file:_files'
|
|
389
|
+
;;
|
|
390
|
+
analyze)
|
|
391
|
+
_arguments \\
|
|
392
|
+
'*--path[Path to policy file or directory]:file:_files' \\
|
|
393
|
+
'*-p[Path to policy file or directory]:file:_files' \\
|
|
394
|
+
'(--policy-type -t)'{{--policy-type,-t}}'[Type of IAM policy]:policy type:(IDENTITY_POLICY RESOURCE_POLICY SERVICE_CONTROL_POLICY)' \\
|
|
395
|
+
'--region[AWS region]:region:' \\
|
|
396
|
+
'--profile[AWS profile]:profile:' \\
|
|
397
|
+
'(--format -f)'{{--format,-f}}'[Output format]:format:(console json markdown)' \\
|
|
398
|
+
'(--output -o)'{{--output,-o}}'[Output file path]:file:_files' \\
|
|
399
|
+
'--no-recursive[Do not recursively search directories]' \\
|
|
400
|
+
'--fail-on-warnings[Fail validation if warnings are found]' \\
|
|
401
|
+
'--github-comment[Post validation results as GitHub PR comment]' \\
|
|
402
|
+
'--github-review[Create line-specific review comments on PR]' \\
|
|
403
|
+
'--github-summary[Write validation summary to GitHub Actions job summary]' \\
|
|
404
|
+
'--run-all-checks[Run full validation checks if Access Analyzer passes]' \\
|
|
405
|
+
'*--check-access-not-granted[Actions to check are NOT granted]:action:' \\
|
|
406
|
+
'*--check-access-resources[Resources to check]:resource:' \\
|
|
407
|
+
'--check-no-new-access[Path to existing policy]:file:_files' \\
|
|
408
|
+
'--check-no-public-access[Check that resource policy does not allow public access]' \\
|
|
409
|
+
'*--public-access-resource-type[Resource type for public access check]:resource type:' \\
|
|
410
|
+
'(--verbose -v)'{{--verbose,-v}}'[Enable verbose logging]'
|
|
411
|
+
;;
|
|
412
|
+
cache)
|
|
413
|
+
_arguments \\
|
|
414
|
+
'1: :(info list clear refresh prefetch location)'
|
|
415
|
+
;;
|
|
416
|
+
sync-services)
|
|
417
|
+
_arguments \\
|
|
418
|
+
'--output-dir[Output directory]:directory:_directories' \\
|
|
419
|
+
'--max-concurrent[Maximum concurrent downloads]:number:'
|
|
420
|
+
;;
|
|
421
|
+
completion)
|
|
422
|
+
_arguments \\
|
|
423
|
+
'1: :(bash zsh)'
|
|
424
|
+
;;
|
|
425
|
+
esac
|
|
426
|
+
;;
|
|
427
|
+
esac
|
|
428
|
+
}}
|
|
429
|
+
|
|
430
|
+
_iam_validator_commands() {{
|
|
431
|
+
local -a commands
|
|
432
|
+
commands=(
|
|
433
|
+
'validate:Validate IAM policies'
|
|
434
|
+
'post-to-pr:Post validation results to GitHub PR'
|
|
435
|
+
'analyze:Analyze IAM policies using AWS IAM Access Analyzer'
|
|
436
|
+
'cache:Manage AWS service definition cache'
|
|
437
|
+
'sync-services:Sync/download all AWS service definitions for offline use'
|
|
438
|
+
'query:Query AWS service definitions (actions, ARNs, condition keys)'
|
|
439
|
+
'completion:Generate shell completion scripts (bash or zsh)'
|
|
440
|
+
)
|
|
441
|
+
_describe 'command' commands
|
|
442
|
+
}}
|
|
443
|
+
|
|
444
|
+
_iam_validator_query_subcommands() {{
|
|
445
|
+
local -a subcommands
|
|
446
|
+
subcommands=(
|
|
447
|
+
'action:Query IAM actions'
|
|
448
|
+
'arn:Query ARN formats'
|
|
449
|
+
'condition:Query condition keys'
|
|
450
|
+
)
|
|
451
|
+
_describe 'query subcommand' subcommands
|
|
452
|
+
}}
|
|
453
|
+
|
|
454
|
+
_iam_validator "$@"
|
|
455
|
+
"""
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
# For testing
|
|
459
|
+
if __name__ == "__main__":
|
|
460
|
+
import asyncio
|
|
461
|
+
import sys
|
|
462
|
+
|
|
463
|
+
cmd = CompletionCommand()
|
|
464
|
+
arg_parser = argparse.ArgumentParser()
|
|
465
|
+
cmd.add_arguments(arg_parser)
|
|
466
|
+
parsed_args = arg_parser.parse_args()
|
|
467
|
+
sys.exit(asyncio.run(cmd.execute(parsed_args)))
|