def from_dict(cls: Type["GraphSet"], data: Dict[str, Any]) -> "GraphSet": """Create a GraphSet from a dict. Args: data: dict of Resource data Returns: GraphSet object """ resources: List[Resource] = [] name = data["name"] start_time = data["start_time"] end_time = data["end_time"] version = data["version"] errors = data["errors"] stats = MultilevelCounter.from_dict(data["stats"]) for resource_id, resource_data in data["resources"].items(): resource = Resource.from_dict(resource_id, resource_data) resources.append(resource) return cls( name=name, version=version, start_time=start_time, end_time=end_time, resources=resources, errors=errors, stats=stats, )
def test_from_dict(self): data = { "count": 2, "foo": { "count": 1, "boo": { "count": 1, "goo": { "count": 1 } } }, "boo": { "count": 1, "goo": { "count": 1, "moo": { "count": 1 } } }, } ml_counter = MultilevelCounter.from_dict(data) self.assertDictEqual(ml_counter.to_dict(), data)
def run_scan( muxer: AWSScanMuxer, config: Config, artifact_writer: ArtifactWriter, artifact_reader: ArtifactReader, ) -> Tuple[ScanManifest, GraphSet]: if config.scan.scan_sub_accounts: account_ids = get_sub_account_ids(config.scan.accounts, config.access.accessor) else: account_ids = config.scan.accounts account_scan_plan = AccountScanPlan(account_ids=account_ids, regions=config.scan.regions, accessor=config.access.accessor) logger = Logger() logger.info(event=AWSLogEvents.ScanAWSAccountsStart) # now combine account_scan_results and org_details to build a ScanManifest scanned_accounts: List[str] = [] artifacts: List[str] = [] errors: Dict[str, List[str]] = {} unscanned_accounts: List[str] = [] stats = MultilevelCounter() graph_set = None for account_scan_manifest in muxer.scan( account_scan_plan=account_scan_plan): account_id = account_scan_manifest.account_id if account_scan_manifest.artifacts: for account_scan_artifact in account_scan_manifest.artifacts: artifacts.append(account_scan_artifact) artifact_graph_set_dict = artifact_reader.read_json( account_scan_artifact) artifact_graph_set = GraphSet.from_dict( artifact_graph_set_dict) if graph_set is None: graph_set = artifact_graph_set else: graph_set.merge(artifact_graph_set) if account_scan_manifest.errors: errors[account_id] = account_scan_manifest.errors unscanned_accounts.append(account_id) else: scanned_accounts.append(account_id) else: unscanned_accounts.append(account_id) account_stats = MultilevelCounter.from_dict( account_scan_manifest.api_call_stats) stats.merge(account_stats) if graph_set is None: raise Exception("BUG: No graph_set generated.") master_artifact_path = artifact_writer.write_json(name="master", data=graph_set.to_dict()) logger.info(event=AWSLogEvents.ScanAWSAccountsEnd) start_time = graph_set.start_time end_time = graph_set.end_time scan_manifest = ScanManifest( scanned_accounts=scanned_accounts, master_artifact=master_artifact_path, artifacts=artifacts, errors=errors, unscanned_accounts=unscanned_accounts, api_call_stats=stats.to_dict(), start_time=start_time, end_time=end_time, ) artifact_writer.write_json("manifest", data=scan_manifest.to_dict()) return scan_manifest, graph_set
def scan( muxer: AWSScanMuxer, account_ids: List[str], regions: List[str], accessor: Accessor, artifact_writer: ArtifactWriter, artifact_reader: ArtifactReader, scan_sub_accounts: bool = False, ) -> ScanManifest: if scan_sub_accounts: account_ids = get_sub_account_ids(account_ids, accessor) account_scan_plans = build_account_scan_plans(accessor=accessor, account_ids=account_ids, regions=regions) logger = Logger() logger.info(event=AWSLogEvents.ScanAWSAccountsStart) account_scan_manifests = muxer.scan(account_scan_plans=account_scan_plans) # now combine account_scan_results and org_details to build a ScanManifest scanned_accounts: List[Dict[str, str]] = [] artifacts: List[str] = [] errors: Dict[str, List[str]] = {} unscanned_accounts: List[Dict[str, str]] = [] stats = MultilevelCounter() for account_scan_manifest in account_scan_manifests: account_id = account_scan_manifest.account_id if account_scan_manifest.artifacts: artifacts += account_scan_manifest.artifacts if account_scan_manifest.errors: errors[account_id] = account_scan_manifest.errors unscanned_accounts.append(account_id) else: scanned_accounts.append(account_id) else: unscanned_accounts.append(account_id) account_stats = MultilevelCounter.from_dict( account_scan_manifest.api_call_stats) stats.merge(account_stats) graph_set = None for artifact_path in artifacts: artifact_dict = artifact_reader.read_artifact(artifact_path) artifact_graph_set = GraphSet.from_dict(artifact_dict) if graph_set is None: graph_set = artifact_graph_set else: graph_set.merge(artifact_graph_set) master_artifact_path = None if graph_set: master_artifact_path = artifact_writer.write_artifact( name="master", data=graph_set.to_dict()) logger.info(event=AWSLogEvents.ScanAWSAccountsEnd) if graph_set: start_time = graph_set.start_time end_time = graph_set.end_time else: start_time, end_time = None, None return ScanManifest( scanned_accounts=scanned_accounts, master_artifact=master_artifact_path, artifacts=artifacts, errors=errors, unscanned_accounts=unscanned_accounts, api_call_stats=stats.to_dict(), start_time=start_time, end_time=end_time, )