Repository: cloud-custodian/cloud-custodian

Issue:
max resources should only compare resource count to the specified resource in the policy
max resources compares resource count in filters that query other resources with the max-resources specified in the policy:

```yaml
policies:
  - name: asg
    resource: asg
    max-resources: 30
    filters:
      - type: image-age
        op: ge
        days: 60
```

```
policy: xxxx exceeded resource limit: 30 found: 368: ResourceLimitExceeded
Traceback (most recent call last):
File "/var/task/custodian_policy.py", line 4, in run
return handler.dispatch_event(event, context)
File "/var/task/c7n/handler.py", line 91, in dispatch_event
p.push(event, context)
File "/var/task/c7n/policy.py", line 831, in push
return mode.run(event, lambda_ctx)
File "/var/task/c7n/policy.py", line 446, in run
resources, event)
File "/var/task/c7n/manager.py", line 91, in filter_resources
resources = f.process(resources, event)
File "/var/task/c7n/resources/asg.py", line 590, in process
self.initialize(asgs)
File "/var/task/c7n/resources/asg.py", line 598, in initialize
results = self.manager.get_resource_manager('ami').resources()
File "/var/task/c7n/resources/ami.py", line 60, in resources
return super(AMI, self).resources(query=query)
File "/var/task/c7n/query.py", line 426, in resources
self.check_resource_limit(len(resources), resource_count)
File "/var/task/c7n/query.py", line 440, in check_resource_limit
"max-resources", p.max_resources, selection_count, population_count)
ResourceLimitExceeded: policy: xxxx exceeded resource limit: 30 found: 368
```

image-age pulls ami's and is doing the evaluation on the number of AMI's, not the number of ASG's


Discussion:

Resolving patch:
diff --git a/c7n/query.py b/c7n/query.py
--- a/c7n/query.py
+++ b/c7n/query.py
@@ -423,7 +423,8 @@ def resources(self, query=None):
         resources = self.filter_resources(resources)
 
         # Check if we're out of a policies execution limits.
-        self.check_resource_limit(len(resources), resource_count)
+        if self.data == self.ctx.policy.data:
+            self.check_resource_limit(len(resources), resource_count)
         return resources
 
     def check_resource_limit(self, selection_count, population_count):


Test patch:
diff --git a/tests/data/placebo/test_policy_resource_count_with_filter/autoscaling.DescribeAutoScalingGroups_1.json b/tests/data/placebo/test_policy_resource_count_with_filter/autoscaling.DescribeAutoScalingGroups_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_policy_resource_count_with_filter/autoscaling.DescribeAutoScalingGroups_1.json
@@ -0,0 +1,64 @@
+{
+    "status_code": 200,
+    "data": {
+        "AutoScalingGroups": [
+            {
+                "AutoScalingGroupName": "test",
+                "AutoScalingGroupARN": "arn:aws:autoscaling:us-east-1:644160558196:autoScalingGroup:5f82d6d0-6b46-4e63-9cd2-2a65fb4993d4:autoScalingGroupName/test",
+                "LaunchConfigurationName": "test",
+                "MinSize": 1,
+                "MaxSize": 1,
+                "DesiredCapacity": 1,
+                "DefaultCooldown": 300,
+                "AvailabilityZones": [
+                    "us-east-1d"
+                ],
+                "LoadBalancerNames": [],
+                "TargetGroupARNs": [],
+                "HealthCheckType": "EC2",
+                "HealthCheckGracePeriod": 300,
+                "Instances": [
+                    {
+                        "InstanceId": "i-0721eb1ac90540eed",
+                        "AvailabilityZone": "us-east-1d",
+                        "LifecycleState": "InService",
+                        "HealthStatus": "Healthy",
+                        "LaunchConfigurationName": "test",
+                        "ProtectedFromScaleIn": false
+                    }
+                ],
+                "CreatedTime": {
+                    "__class__": "datetime",
+                    "year": 2018,
+                    "month": 9,
+                    "day": 19,
+                    "hour": 22,
+                    "minute": 42,
+                    "second": 13,
+                    "microsecond": 37000
+                },
+                "SuspendedProcesses": [],
+                "VPCZoneIdentifier": "subnet-3a334610",
+                "EnabledMetrics": [],
+                "Tags": [],
+                "TerminationPolicies": [
+                    "Default"
+                ],
+                "NewInstancesProtectedFromScaleIn": false,
+                "ServiceLinkedRoleARN": "arn:aws:iam::644160558196:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling"
+            }
+        ],
+        "ResponseMetadata": {
+            "RequestId": "94d2982b-bc5d-11e8-926c-61d353ddbdec",
+            "HTTPStatusCode": 200,
+            "HTTPHeaders": {
+                "x-amzn-requestid": "94d2982b-bc5d-11e8-926c-61d353ddbdec",
+                "content-type": "text/xml",
+                "content-length": "2057",
+                "vary": "Accept-Encoding",
+                "date": "Wed, 19 Sep 2018 22:44:34 GMT"
+            },
+            "RetryAttempts": 0
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_policy_resource_count_with_filter/autoscaling.DescribeLaunchConfigurations_1.json b/tests/data/placebo/test_policy_resource_count_with_filter/autoscaling.DescribeLaunchConfigurations_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_policy_resource_count_with_filter/autoscaling.DescribeLaunchConfigurations_1.json
@@ -0,0 +1,57 @@
+{
+    "status_code": 200,
+    "data": {
+        "LaunchConfigurations": [
+            {
+                "LaunchConfigurationName": "test",
+                "LaunchConfigurationARN": "arn:aws:autoscaling:us-east-1:644160558196:launchConfiguration:d1d0f8b4-0a19-426f-8558-92b1652c7384:launchConfigurationName/test",
+                "ImageId": "ami-08ad7d3e6aa17c472",
+                "KeyName": "",
+                "SecurityGroups": [
+                    "sg-0c3b95fa1ac946098"
+                ],
+                "ClassicLinkVPCSecurityGroups": [],
+                "UserData": "",
+                "InstanceType": "t1.micro",
+                "KernelId": "",
+                "RamdiskId": "",
+                "BlockDeviceMappings": [
+                    {
+                        "DeviceName": "/dev/sda1",
+                        "Ebs": {
+                            "SnapshotId": "snap-0d606a352ae1f6a8a",
+                            "VolumeSize": 8,
+                            "VolumeType": "gp2",
+                            "DeleteOnTermination": true
+                        }
+                    }
+                ],
+                "InstanceMonitoring": {
+                    "Enabled": false
+                },
+                "CreatedTime": {
+                    "__class__": "datetime",
+                    "year": 2018,
+                    "month": 9,
+                    "day": 19,
+                    "hour": 22,
+                    "minute": 42,
+                    "second": 3,
+                    "microsecond": 56000
+                },
+                "EbsOptimized": false
+            }
+        ],
+        "ResponseMetadata": {
+            "RequestId": "9550c8e1-bc5d-11e8-8258-f16d61b79e93",
+            "HTTPStatusCode": 200,
+            "HTTPHeaders": {
+                "x-amzn-requestid": "9550c8e1-bc5d-11e8-8258-f16d61b79e93",
+                "content-type": "text/xml",
+                "content-length": "1561",
+                "date": "Wed, 19 Sep 2018 22:44:35 GMT"
+            },
+            "RetryAttempts": 0
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/data/placebo/test_policy_resource_count_with_filter/ec2.DescribeImages_1.json b/tests/data/placebo/test_policy_resource_count_with_filter/ec2.DescribeImages_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_policy_resource_count_with_filter/ec2.DescribeImages_1.json
@@ -0,0 +1,75 @@
+{
+    "status_code": 200,
+    "data": {
+        "Images": [
+            {
+                "Architecture": "x86_64",
+                "CreationDate": "2018-09-19T22:38:01.000Z",
+                "ImageId": "ami-08ad7d3e6aa17c472",
+                "ImageLocation": "644160558196/test-image",
+                "ImageType": "machine",
+                "Public": false,
+                "OwnerId": "644160558196",
+                "State": "available",
+                "BlockDeviceMappings": [
+                    {
+                        "DeviceName": "/dev/sda1",
+                        "Ebs": {
+                            "Encrypted": false,
+                            "DeleteOnTermination": true,
+                            "SnapshotId": "snap-0d606a352ae1f6a8a",
+                            "VolumeSize": 8,
+                            "VolumeType": "gp2"
+                        }
+                    }
+                ],
+                "Description": "",
+                "Hypervisor": "xen",
+                "Name": "test-image",
+                "RootDeviceName": "/dev/sda1",
+                "RootDeviceType": "ebs",
+                "VirtualizationType": "paravirtual"
+            },
+            {
+                "Architecture": "x86_64",
+                "CreationDate": "2018-09-19T22:38:10.000Z",
+                "ImageId": "ami-0b8c027cdf5929808",
+                "ImageLocation": "644160558196/test-image-2",
+                "ImageType": "machine",
+                "Public": false,
+                "OwnerId": "644160558196",
+                "State": "available",
+                "BlockDeviceMappings": [
+                    {
+                        "DeviceName": "/dev/sda1",
+                        "Ebs": {
+                            "Encrypted": false,
+                            "DeleteOnTermination": true,
+                            "SnapshotId": "snap-0507048b4551a4ab4",
+                            "VolumeSize": 8,
+                            "VolumeType": "gp2"
+                        }
+                    }
+                ],
+                "Description": "",
+                "Hypervisor": "xen",
+                "Name": "test-image-2",
+                "RootDeviceName": "/dev/sda1",
+                "RootDeviceType": "ebs",
+                "VirtualizationType": "paravirtual"
+            }
+        ],
+        "ResponseMetadata": {
+            "RequestId": "e0cb8999-be23-4eea-8f04-25fbb4a7551b",
+            "HTTPStatusCode": 200,
+            "HTTPHeaders": {
+                "content-type": "text/xml;charset=UTF-8",
+                "content-length": "2727",
+                "vary": "Accept-Encoding",
+                "date": "Wed, 19 Sep 2018 22:44:35 GMT",
+                "server": "AmazonEC2"
+            },
+            "RetryAttempts": 0
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/test_policy.py b/tests/test_policy.py
--- a/tests/test_policy.py
+++ b/tests/test_policy.py
@@ -525,6 +525,24 @@ def test_policy_resource_limits_count(self):
             session_factory=session_factory
         )
 
+    def test_policy_resource_limits_with_filter(self):
+        session_factory = self.replay_flight_data(
+            "test_policy_resource_count_with_filter")
+        p = self.load_policy(
+            {
+                "name": "asg-with-image-age-resource-count",
+                "resource": "asg",
+                "max-resources": 1,
+                "filters": [{
+                    "type": "image-age",
+                    "op": "ge",
+                    "days": 0
+                }]
+            },
+            session_factory=session_factory)
+        resources = p.run()
+        self.assertTrue(resources)
+
     def test_policy_metrics(self):
         session_factory = self.replay_flight_data("test_policy_metrics")
         p = self.load_policy(