Repository: cloud-custodian/cloud-custodian

Issue:
Error using event-rule invalid-targets filter
### Describe the bug

Attempting to clean up event rules with invalid targets, c7n throws an error
"TypeError: argument of type 'NoneType' is not iterable"

### What did you expect to happen?

run the policy without crashing

### Cloud Provider

Amazon Web Services (AWS)

### Cloud Custodian version and dependency information

```shell
Custodian:   0.9.17
Python:      3.7.9 (v3.7.9:13c94747c7, Aug 15 2020, 01:31:08) 
             [Clang 6.0 (clang-600.0.57)]
Platform:    posix.uname_result(sysname='Darwin', nodename='38f9d3ae684c', release='20.6.0', version='Darwin Kernel Version 20.6.0: Tue Apr 19 21:04:45 PDT 2022; root:xnu-7195.141.29~1/RELEASE_X86_64', machine='x86_64')
Using venv:  False
Docker: False
Installed: 

argcomplete==1.12.3
attrs==19.1.0
boto3==1.21.8
botocore==1.24.8
cffi==1.13.2
cryptography==36.0.1
importlib-metadata==4.11.1
jmespath==0.9.4
jsonschema==3.2.0
more-itertools==7.2.0
pycparser==2.19
pyrsistent==0.15.4
python-dateutil==2.8.2
pyyaml==6.0
s3transfer==0.5.2
setuptools==47.1.0
six==1.12.0
tabulate==0.8.7
typing-extensions==4.1.1
urllib3==1.26.8
zipp==0.6.0
```


### Policy

```shell
policies:
  - name: event-rule-invalid-target
    resource: event-rule
    filters:
      - type: value
        key: ManagedBy
        op: not-in
        value: 'amazonaws.com'
        value_type: swap
      - type: invalid-targets
        all: true 
    actions:
      - type: delete
        force: true
```


### Relevant log/traceback output

```shell
% custodian run --cache-period=30 --profile myProfile -v -s ~/c7nout -c test.yml -p event-rule-invalid-target -r us-east-1     
2022-07-06 17:08:34,722: custodian.commands:DEBUG Loaded file test.yml. Contains 16 policies
2022-07-06 17:08:36,491: custodian.output:DEBUG Storing output with <LogFile file:///Users/john_wick/c7nout/event-rule-invalid-target/custodian-run.log>
2022-07-06 17:08:36,503: custodian.policy:DEBUG Running policy:event-rule-invalid-target resource:event-rule region:us-east-1 c7n:0.9.17
2022-07-06 17:08:36,511: custodian.cache:DEBUG Using cache file /Users/john_wick/.cache/cloud-custodian.cache
2022-07-06 17:08:36,511: custodian.resources.eventrule:DEBUG Using cached c7n.resources.cw.EventRule: 1989
2022-07-06 17:16:55,368: custodian.cache:DEBUG Using cache file /Users/john_wick/.cache/cloud-custodian.cache
...
2022-07-06 17:18:37,849: custodian.cache:DEBUG Using cache file /Users/john_wick/.cache/cloud-custodian.cache
len(identities) != 1. Actual value: 2
identities:
['AccountServiceListenerQueue', 'AccountServiceListenerQueue']
2022-07-06 17:18:39,524: custodian.cache:DEBUG Using cache file /Users/john_wick/.cache/cloud-custodian.cache
...
2022-07-06 17:18:44,685: custodian.cache:DEBUG Using cache file /Users/john_wick/.cache/cloud-custodian.cache
2022-07-06 17:18:46,319: custodian.output:DEBUG metric:PolicyException Count:1 policy:event-rule-invalid-target restype:event-rule
2022-07-06 17:18:46,319: custodian.output:DEBUG metric:ApiCalls Count:1858 policy:event-rule-invalid-target restype:event-rule
2022-07-06 17:18:46,319: custodian.output:ERROR Error while executing policy
Traceback (most recent call last):
  File ".../site-packages/c7n/policy.py", line 290, in run
    resources = self.policy.resource_manager.resources()
  File ".../site-packages/c7n/query.py", line 536, in resources
    resources = self.filter_resources(resources)
  File ".../site-packages/c7n/manager.py", line 111, in filter_resources
    resources = f.process(resources, event)
  File ".../site-packages/c7n/resources/cw.py", line 249, in process
    resolved = arn_resolver.resolve(r['c7n:ChildArns'])
  File ".../site-packages/c7n/resources/aws.py", line 180, in resolve
    rmanager = self.manager.get_resource_manager(rtype)
  File ".../site-packages/c7n/manager.py", line 82, in get_resource_manager
    if '.' in resource_type:
TypeError: argument of type 'NoneType' is not iterable
2022-07-06 17:18:46,325: custodian.commands:ERROR Error while executing policy event-rule-invalid-target, continuing
Traceback (most recent call last):
  File ".../site-packages/c7n/commands.py", line 301, in run
    policy()
  File ".../site-packages/c7n/policy.py", line 1242, in __call__
    resources = mode.run()
  File ".../site-packages/c7n/policy.py", line 290, in run
    resources = self.policy.resource_manager.resources()
  File ".../site-packages/c7n/query.py", line 536, in resources
    resources = self.filter_resources(resources)
  File ".../site-packages/c7n/manager.py", line 111, in filter_resources
    resources = f.process(resources, event)
  File ".../site-packages/c7n/resources/cw.py", line 249, in process
    resolved = arn_resolver.resolve(r['c7n:ChildArns'])
  File ".../site-packages/c7n/resources/aws.py", line 180, in resolve
    rmanager = self.manager.get_resource_manager(rtype)
  File ".../site-packages/c7n/manager.py", line 82, in get_resource_manager
    if '.' in resource_type:
TypeError: argument of type 'NoneType' is not iterable
2022-07-06 17:18:46,326: custodian.commands:ERROR The following policies had errors while executing
 - event-rule-invalid-target
```


### Extra information or context

I got the policy working by adding "if rtype is not None:" at line 180 in the resolve method of ArnResolver Class in aws.py, like this:
```
   def resolve(self, arns):
        arns = map(Arn.parse, arns)
        a_service = operator.attrgetter('service')
        a_resource = operator.attrgetter('resource_type')
        kfunc = lambda a: (a_service(a), a_resource(a))  # noqa
        arns = sorted(arns, key=kfunc)
        results = {}
        for (service, arn_type), arn_set in itertools.groupby(arns, key=kfunc):
            arn_set = list(arn_set)
            rtype = ArnResolver.resolve_type(arn_set[0])
            if rtype is not None:
                rmanager = self.manager.get_resource_manager(rtype)
                if rtype == 'sns':
                    resources = rmanager.get_resources(
                        [rarn.arn for rarn in arn_set])
                else:
                    resources = rmanager.get_resources(
                        [rarn.resource for rarn in arn_set])
                for rarn, r in zip(rmanager.get_arns(resources), resources):
                    results[rarn] = r

                for rarn in arn_set:
                    if rarn.arn not in results:
                        results[rarn.arn] = None
        return results


Discussion:
thanks for the bug report, I'd like to understand this a bit more, we should add some debugging as we walk the different resource types that are valid targets for the event rules.
if your patching the code, I'd really like to understand what the arn set and arns are if the rtype is none. 
Looks like there are event-rules that trigger on `event schedule` and have 0 targets. From my understanding, these rules just drop an event to the default event bus. @kapilt do you mind if I pick this one up? 
Sure, go for it, thanks
Looks like AWS used to have arns(for their internal use) that the user didn't have the capability to interpret since they are not valid resources from the user point of view.

Checked in few of our legacy accounts and found a target like `arn:aws:automation:us-east-1:123456789:action/EBSCreateSnapshot/EBSCreateSnapshot_SL-Create-Snapshots`. It doesn't look like a valid resource type to me

I couldn't find anything about them in my investigation except that AWS created them as a target where users wanted ebs volume snapshots to be created at a certain interval. Went ahead and created a new rule for that and looks like they fixed the arn to `arn:aws:events:us-east-1:644160558196:target/create-snapshot` as seen in the screenshot below

![image](https://user-images.githubusercontent.com/22061271/183490009-2240294a-e1b8-4d3f-bdf1-3fc2a17679c1.png)

I think event-bus is another target type that needs to be added

Resolving patch:
diff --git a/c7n/resources/cw.py b/c7n/resources/cw.py
--- a/c7n/resources/cw.py
+++ b/c7n/resources/cw.py
@@ -194,6 +194,19 @@ class ValidEventRuleTargetFilter(ChildResourceFilter):
     )
 
     permissions = ('events:ListTargetsByRule',)
+    supported_resources = (
+        "aws.sqs",
+        "aws.event-bus",
+        "aws.lambda",
+        "aws.ecs",
+        "aws.ecs-task",
+        "aws.kinesis",
+        "aws.sns",
+        "aws.ssm-parameter",
+        "aws.batch-compute",
+        "aws.codepipeline",
+        "aws.step-machine",
+    )
 
     def validate(self):
         """
@@ -223,21 +236,11 @@ def get_rules_with_children(self, resources):
     def process(self, resources, event=None):
         # Due to lazy loading of resources, we need to explicilty load the following
         # potential targets for a event rule target:
-        load_resources(
-            [
-                "aws.sqs",
-                "aws.lambda",
-                "aws.ecs-cluster",
-                "aws.ecs-task",
-                "aws.kinesis",
-                "aws.sns",
-                "aws.ssm-parameter",
-                "aws.batch-compute",
-                "aws.codepipeline",
-            ]
-        )
+
+        load_resources(list(self.supported_resources))
         arn_resolver = ArnResolver(self.manager)
         resources = self.get_rules_with_children(resources)
+        resources = [r for r in resources if self.filter_unsupported_resources(r)]
         results = []
 
         if self.data.get('all'):
@@ -254,6 +257,14 @@ def process(self, resources, event=None):
                 results.append(r)
         return results
 
+    def filter_unsupported_resources(self, r):
+        for carn in r.get('c7n:ChildArns'):
+            if 'aws.' + str(ArnResolver.resolve_type(carn)) not in self.supported_resources:
+                self.log.info(
+                    f"Skipping resource {r.get('Arn')}, target type {carn} is not supported")
+                return False
+            return True
+
 
 @EventRule.action_registry.register('delete')
 class EventRuleDelete(BaseAction):


Test patch:
diff --git a/tests/test_cwe.py b/tests/test_cwe.py
--- a/tests/test_cwe.py
+++ b/tests/test_cwe.py
@@ -7,6 +7,7 @@
 from .common import event_data, BaseTest
 
 from c7n.cwe import CloudWatchEvents
+from c7n.resources import cw
 
 
 @terraform('event_bridge_bus')
@@ -136,6 +137,16 @@ def test_event_rule_invalid_targets_all(self):
         resources = policy.run()
         self.assertEqual(len(resources), 0)
 
+    def test_filter_resource_with_unknown_target(self):
+        r = {
+            'Name': 'test-ebs-snapshot',
+            'Arn': 'arn:aws:events:us-east-1:644160558196:rule/test-ebs-snapshot',
+            'c7n:ChildArns': ['arn:aws:events:us-east-1:644160558196:target/create-snapshot',
+                            'arn:aws:lambda:us-east-1:644160558196:function:custodian-code']
+        }
+        self.assertFalse(
+            cw.ValidEventRuleTargetFilter('event-rule').filter_unsupported_resources(r))
+
 
 class CloudWatchEventsFacadeTest(TestCase):