Beispiel #1
0
    def scan(self) -> GraphSet:
        """Perform a scan on all of the resource classes in this GraphSpec and return
        a GraphSet containing the scanned data.

        Returns:
            GraphSet representing results of scanning this GraphSpec's resource_spec_classes.
        """

        resources: List[Resource] = []
        errors: List[str] = []
        stats = MultilevelCounter()
        start_time = int(time.time())
        logger = Logger()
        for resource_spec_class in self.resource_spec_classes:
            with logger.bind(resource_type=str(resource_spec_class.type_name)):
                logger.debug(event=LogEvent.ScanResourceTypeStart)
                resource_scan_result = resource_spec_class.scan(
                    scan_accessor=self.scan_accessor)
                resources += resource_scan_result.resources
                errors += resource_scan_result.errors
                stats.merge(resource_scan_result.stats)
                logger.debug(event=LogEvent.ScanResourceTypeEnd)
        end_time = int(time.time())
        return GraphSet(
            name=self.name,
            version=self.version,
            start_time=start_time,
            end_time=end_time,
            resources=resources,
            errors=errors,
            stats=stats,
        )
Beispiel #2
0
    def get_session(self,
                    account_id: str,
                    region: Optional[str] = None) -> boto3.Session:
        """Get a boto3 session for a given account.

        Args:
            account_id: target account id
            region: session region

        Returns:
            boto3.Session object
        """
        logger = Logger()
        with logger.bind(auth_account_id=account_id):
            if self.multi_hop_accessors:
                for mha in self.multi_hop_accessors:  # pylint: disable=not-an-iterable
                    with logger.bind(auth_accessor=str(mha)):
                        try:
                            session = mha.get_session(account_id=account_id,
                                                      region=region)
                            return session
                        except Exception as ex:
                            logger.debug(event=LogEvent.AuthToAccountFailure,
                                         exception=str(ex))

                raise AccountAuthException(
                    f"Unable to access {account_id} using {str(self)}")
            # local run mode
            session = boto3.Session(region_name=region)
            sts_client = session.client("sts")
            sts_account_id = sts_client.get_caller_identity()["Account"]
            if sts_account_id != account_id:
                raise ValueError(
                    f"BUG: sts_account_id {sts_account_id} != {account_id}")
            return session
Beispiel #3
0
    def get_session(self,
                    account_id: str,
                    region: Optional[str] = None) -> boto3.Session:
        """Get a session for an account_id by iterating through the :class:`.AccessStep`s
        of this :class:`.MultiHopAccessor`.

        Args:
             account_id: account to access
             region: region to use during session creation.

        Returns:
            boto3 Session for accessing account_id
        """
        logger = Logger()
        cws = boto3.Session(region_name=region)
        for access_step in self.access_steps:
            access_account_id = access_step.account_id if access_step.account_id else account_id
            role_name = access_step.role_name
            external_id = access_step.external_id
            session_cache_value = self.session_cache.get(
                account_id=access_account_id,
                role_name=role_name,
                role_session_name=self.role_session_name,
                region=region,
            )
            if session_cache_value is None:
                logger.debug(event=LogEvent.AuthToAccountStart)
                sts_client = cws.client("sts")
                role_arn = f"arn:aws:iam::{access_account_id}:role/{role_name}"
                assume_args = {
                    "RoleArn": role_arn,
                    "RoleSessionName": self.role_session_name
                }
                if external_id:
                    assume_args["ExternalId"] = external_id

                assume_resp = sts_client.assume_role(**assume_args)
                creds = assume_resp["Credentials"]
                expiration = creds["Expiration"]
                cws = boto3.Session(
                    aws_access_key_id=creds["AccessKeyId"],
                    aws_secret_access_key=creds["SecretAccessKey"],
                    aws_session_token=creds["SessionToken"],
                    region_name=region,
                )
                self.session_cache.put(
                    session=cws,
                    expiration=expiration,
                    account_id=access_account_id,
                    role_name=role_name,
                    role_session_name=self.role_session_name,
                    region=region,
                )
                logger.debug(event=LogEvent.AuthToAccountEnd)
            else:
                cws = session_cache_value.session
        return cws
    def scan(self) -> List[Resource]:
        """Perform a scan on all of the resource classes in this GraphSpec and return
        a list of Resource objects.

        Returns:
            List of Resource objects
        """
        resources: List[Resource] = []
        logger = Logger()
        for resource_spec_class in self.resource_spec_classes:
            with logger.bind(resource_type=str(resource_spec_class.type_name)):
                logger.debug(event=LogEvent.ScanResourceTypeStart)
                scanned_resources = resource_spec_class.scan(
                    scan_accessor=self.scan_accessor)
                resources += scanned_resources
                logger.debug(event=LogEvent.ScanResourceTypeEnd)
        return resources