Skip to content

Commit

Permalink
Merge pull request #49 from kntrain/improve-errorhandle
Browse files Browse the repository at this point in the history
This list of patches splits out the raw listing from the filtered listings, and should allow better handling of different kinds of errors in the long term. In the short term, it adds the possibility to "unfilter" the automatically applied filters that until now were baked in.
  • Loading branch information
JohannesEbke authored Apr 13, 2021
2 parents 80c4c8c + 2055571 commit 5f4e644
Show file tree
Hide file tree
Showing 7 changed files with 758 additions and 270 deletions.
34 changes: 34 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,40 @@ region, and operation used to find them. They can be dumped with::
aws-list-all show data/ec2_*
aws-list-all show --verbose data/ec2_DescribeSecurityGroups_eu-west-1.json

Special treatment and removal of default resources which are performed by default during
data handling can be omitted with --unfilter and following arguments:
- cloudfront
- medialive
- ssmListCommands
- snsListSubscriptions
- athenaWorkGroups
- listEventBuses
- xRayGroups
- route53Resolver
- kmsListAliases
- appstreamImages
- cloudsearch
- cloudTrail
- cloudWatch
- iamPolicies
- s3Owner
- ecsClustersFailure
- pinpointGetApps
- ssmBaselines
- dbSecurityGroups
- dbParameterGroups
- dbClusterParameterGroups
- dbOptionGroups
- ec2VPC
- ec2Subnets
- ec2SecurityGroups
- ec2RouteTables
- ec2NetworkAcls
- ec2FpgaImages
- workmailDeletedOrganizations
- elasticacheSubnetGroups


How do I really list everything?
------------------------------------------------

Expand Down
27 changes: 25 additions & 2 deletions aws_list_all/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ def main():
action='append',
help='Restrict querying to the given operation (can be specified multiple times)'
)
query.add_argument(
'-u',
'--unfilter',
action='append',
help='Exclude given default-value filter from being applied (can be specified multiple times)'
)
query.add_argument('-p', '--parallel', default=32, type=int, help='Number of request to do in parallel')
query.add_argument('-d', '--directory', default='.', help='Directory to save result listings to')
query.add_argument('-v', '--verbose', action='count', help='Print detailed info during run')
Expand All @@ -83,6 +89,15 @@ def main():
)
show.add_argument('listingfile', nargs='*', help='listing file(s) to load and print')
show.add_argument('-v', '--verbose', action='count', help='print given listing files with detailed info')
show.add_argument('-n', '--not_found', default=False, action='store_true', help='additionally print listing files of resources not found')
show.add_argument('-e', '--errors', default=False, action='store_true', help='additionally print listing files of resources where queries resulted in errors')
show.add_argument('-d', '--denied', default=False, action='store_true', help='additionally print listing files of resources with "missing permission" errors')
show.add_argument(
'-u',
'--unfilter',
action='append',
help='Exclude given default-value filter from being applied (can be specified multiple times)'
)

# Introspection debugging is not the main function. So we put it all into a subcommand.
introspect = subparsers.add_parser(
Expand Down Expand Up @@ -157,12 +172,20 @@ def main():
args.operation,
verbose=args.verbose or 0,
parallel=args.parallel,
selected_profile=args.profile
selected_profile=args.profile,
unfilter=args.unfilter
)
elif args.command == 'show':
if args.listingfile:
increase_limit_nofiles()
do_list_files(args.listingfile, verbose=args.verbose or 0)
do_list_files(
args.listingfile,
verbose=args.verbose or 0,
not_found=args.not_found,
errors=args.errors,
denied=args.denied,
unfilter=args.unfilter
)
else:
show.print_help()
return 1
Expand Down
156 changes: 156 additions & 0 deletions aws_list_all/apply_filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import json
import os
import sys

from .fixing_filter import *
from .resource_filter import *

def apply_filters(listing, unfilterList, response, complete):
"""Apply filters for operations to be handled in a special way or
to remove default resources from the response"""
apply_complete = complete

if not('cloudfront' in unfilterList):
filter = CloudfrontFilter()
filter.execute(listing, response)

if not('medialive' in unfilterList):
filter = MedialiveFilter()
filter.execute(listing, response)

if not('ssmListCommands' in unfilterList):
filter = SSMListCommandsFilter()
filter.execute(listing, response)

if not('snsListSubscriptions' in unfilterList):
filter = SNSListSubscriptionsFilter()
filter.execute(listing, response)

if not('athenaWorkGroups' in unfilterList):
filter = AthenaWorkGroupsFilter()
filter.execute(listing, response)

if not('listEventBuses' in unfilterList):
filter = ListEventBusesFilter()
filter.execute(listing, response)

if not('xRayGroups' in unfilterList):
filter = XRayGroupsFilter()
filter.execute(listing, response)

if not('route53Resolver' in unfilterList):
filter = Route53ResolverFilter()
filter.execute(listing, response)

filter = CountFilter(apply_complete)
filter.execute(listing, response)
apply_complete = filter.complete

filter = QuantityFilter(apply_complete)
filter.execute(listing, response)
apply_complete = filter.complete

filter = NeutralThingFilter()
filter.execute(listing, response)

filter = BadThingFilter(apply_complete)
filter.execute(listing, response)
apply_complete = filter.complete

if not('kmsListAliases' in unfilterList):
filter = KMSListAliasesFilter()
filter.execute(listing, response)

if not('appstreamImages' in unfilterList):
filter = AppstreamImagesFilter()
filter.execute(listing, response)

if not('cloudsearch' in unfilterList):
filter = CloudsearchFilter()
filter.execute(listing, response)

if not('cloudTrail' in unfilterList):
filter = CloudTrailFilter()
filter.execute(listing, response)

if not('cloudWatch' in unfilterList):
filter = CloudWatchFilter()
filter.execute(listing, response)

if not('iamPolicies' in unfilterList):
filter = IAMPoliciesFilter()
filter.execute(listing, response)

if not('s3Owner' in unfilterList):
filter = S3OwnerFilter()
filter.execute(listing, response)

if not('ecsClustersFailure' in unfilterList):
filter = ECSClustersFailureFilter()
filter.execute(listing, response)

if not('pinpointGetApps' in unfilterList):
filter = PinpointGetAppsFilter()
filter.execute(listing, response)

if not('ssmBaselines' in unfilterList):
filter = SSMBaselinesFilter()
filter.execute(listing, response)

if not('dbSecurityGroups' in unfilterList):
filter = DBSecurityGroupsFilter()
filter.execute(listing, response)

if not('dbParameterGroups' in unfilterList):
filter = DBParameterGroupsFilter()
filter.execute(listing, response)

if not('dbClusterParameterGroups' in unfilterList):
filter = DBClusterParameterGroupsFilter()
filter.execute(listing, response)

if not('dbOptionGroups' in unfilterList):
filter = DBOptionGroupsFilter()
filter.execute(listing, response)

if not('ec2VPC' in unfilterList):
filter = EC2VPCFilter()
filter.execute(listing, response)

if not('ec2Subnets' in unfilterList):
filter = EC2SubnetsFilter()
filter.execute(listing, response)

if not('ec2SecurityGroups' in unfilterList):
filter = EC2SecurityGroupsFilter()
filter.execute(listing, response)

if not('ec2RouteTables' in unfilterList):
filter = EC2RouteTablesFilter()
filter.execute(listing, response)

if not('ec2NetworkAcls' in unfilterList):
filter = EC2NetworkAclsFilter()
filter.execute(listing, response)

if not('ec2FpgaImages' in unfilterList):
filter = EC2FpgaImagesFilter()
filter.execute(listing, response)

if not('workmailDeletedOrganizations' in unfilterList):
filter = WorkmailDeletedOrganizationsFilter()
filter.execute(listing, response)

if not('elasticacheSubnetGroups' in unfilterList):
filter = ElasticacheSubnetGroupsFilter()
filter.execute(listing, response)

filter = NextTokenFilter(apply_complete)
filter.execute(listing, response)
apply_complete = filter.complete

return apply_complete




61 changes: 61 additions & 0 deletions aws_list_all/fixing_filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import json
import pprint

import boto3

from .client import get_client

class CountFilter:
def __init__(self, complete):
self.complete = complete

def execute(self, listing, response):
if 'Count' in response:
if 'MaxResults' in response:
if response['MaxResults'] <= response['Count']:
self.complete = False
del response['MaxResults']
del response['Count']

class QuantityFilter:
def __init__(self, complete):
self.complete = complete

def execute(self, listing, response):
if 'Quantity' in response:
if 'MaxItems' in response:
if response['MaxItems'] <= response['Quantity']:
self.complete = False
del response['MaxItems']
del response['Quantity']

class NeutralThingFilter:
def execute(self, listing, response):
for neutral_thing in ('MaxItems', 'MaxResults', 'Quantity'):
if neutral_thing in response:
del response[neutral_thing]

class BadThingFilter:
def __init__(self, complete):
self.complete = complete

def execute(self, listing, response):
for bad_thing in (
'hasMoreResults', 'IsTruncated', 'Truncated', 'HasMoreApplications', 'HasMoreDeliveryStreams',
'HasMoreStreams', 'NextToken', 'NextMarker', 'nextMarker', 'Marker'
):
if bad_thing in response:
if response[bad_thing]:
self.complete = False
del response[bad_thing]

class NextTokenFilter:
def __init__(self, complete):
self.complete = complete

def execute(self, listing, response):
# interpret nextToken in several services
if (listing.service, listing.operation) in (('inspector', 'ListFindings'), ('logs', 'DescribeLogGroups')):
if response.get('nextToken'):
self.complete = False
del response['nextToken']
Loading

0 comments on commit 5f4e644

Please sign in to comment.