Repository: cloud-custodian/cloud-custodian

Issue:
Cannot set Owners for aws.ami resource
**Describe the bug**
My intent is to search all canonical public AMIs and return the most recent ones that match my filter. 

I'm unable to set the `Owners` key for `aws.ami`.

I'm also unable to find documentation on `Owners` key.

**To Reproduce**

Run policy

```
custodian-cask run -c test-policies/ami-new.yml --dryrun -s out --region us-east-1 --verbose --cache-period 0
```

**Expected behavior**
Search not my account but canonical's account to find the latest AMI

**Background (please complete the following information):**
 - Policy: [please exclude any account/sensitive information]
```yaml
policies:
  - name: ami-latest-canonical
    resource: ami
    query:
      # canonical owner
      Owners: ["099720109477"]
    filters:
      - type: image-age
        days: 60
        op: lte
```

```
2020-04-08 20:30:00,023: custodian.commands:ERROR invalid policy file: /home/custodian/ami-new.yml error: Failed to validate policy ami-new 
 Error on policy:ami-new resource:ami
{'Owners': ['099720109477']} is not of type 'array'

Failed validating 'type' in schema[14]['allOf'][0]['properties']['query']:
    {'items': {'type': 'object'}, 'type': 'array'}

On instance['query']:
    {'Owners': ['099720109477']}
2020-04-08 20:30:00,024: custodian.commands:ERROR Found 1 errors.  Exiting.
```

**Additional context**
Add any other context about the problem here.



Discussion:

Resolving patch:
diff --git a/c7n/resources/ami.py b/c7n/resources/ami.py
--- a/c7n/resources/ami.py
+++ b/c7n/resources/ami.py
@@ -24,7 +24,7 @@
 from c7n.manager import resources
 from c7n.query import QueryResourceManager, DescribeSource, TypeInfo
 from c7n.resolver import ValuesFrom
-from c7n.utils import local_session, type_schema, chunks
+from c7n.utils import local_session, type_schema, chunks, merge_dict_list
 
 
 log = logging.getLogger('custodian.ami')
@@ -45,7 +45,10 @@ class resource_type(TypeInfo):
         date = 'CreationDate'
 
     def resources(self, query=None):
-        query = query or {}
+        if query is None and 'query' in self.data:
+            query = merge_dict_list(self.data['query'])
+        elif query is None:
+            query = {}
         if query.get('Owners') is None:
             query['Owners'] = ['self']
         return super(AMI, self).resources(query=query)
diff --git a/c7n/utils.py b/c7n/utils.py
--- a/c7n/utils.py
+++ b/c7n/utils.py
@@ -668,6 +668,17 @@ def get_annotation_prefix(s):
     return 'c7n:{}'.format(s)
 
 
+def merge_dict_list(dict_iter):
+    """take an list of dictionaries and merge them.
+
+    last dict wins/overwrites on keys.
+    """
+    result = {}
+    for d in dict_iter:
+        result.update(d)
+    return result
+
+
 def merge_dict(a, b):
     """Perform a merge of dictionaries a and b
 


Test patch:
diff --git a/tests/data/placebo/test_ami_sse/ec2.DescribeImages_1.json b/tests/data/placebo/test_ami_sse/ec2.DescribeImages_1.json
new file mode 100644
--- /dev/null
+++ b/tests/data/placebo/test_ami_sse/ec2.DescribeImages_1.json
@@ -0,0 +1,46 @@
+{
+    "status_code": 200,
+    "data": {
+        "Images": [
+            {
+                "Architecture": "x86_64",
+                "CreationDate": "2018-07-25T16:07:17.000Z",
+                "ImageId": "ami-b04847cf",
+                "ImageLocation": "123456789123/ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-20180724",
+                "ImageType": "machine",
+                "Public": true,
+                "OwnerId": "123456789123",
+                "State": "available",
+                "BlockDeviceMappings": [
+                    {
+                        "DeviceName": "/dev/sda1",
+                        "Ebs": {
+                            "DeleteOnTermination": true,
+                            "SnapshotId": "snap-03eeb5be1266fe28d",
+                            "VolumeSize": 8,
+                            "VolumeType": "gp2",
+                            "Encrypted": false
+                        }
+                    },
+                    {
+                        "DeviceName": "/dev/sdb",
+                        "VirtualName": "ephemeral0"
+                    },
+                    {
+                        "DeviceName": "/dev/sdc",
+                        "VirtualName": "ephemeral1"
+                    }
+                ],
+                "Description": "Canonical, Ubuntu, 18.04 LTS, amd64 bionic image build on 2018-07-24",
+                "EnaSupport": true,
+                "Hypervisor": "xen",
+                "Name": "ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-20180724",
+                "RootDeviceName": "/dev/sda1",
+                "RootDeviceType": "ebs",
+                "SriovNetSupport": "simple",
+                "VirtualizationType": "hvm"
+            }
+        ],
+        "ResponseMetadata": {}
+    }
+}
diff --git a/tests/test_ami.py b/tests/test_ami.py
--- a/tests/test_ami.py
+++ b/tests/test_ami.py
@@ -37,6 +37,20 @@ def test_query(self):
         resources = p.run()
         self.assertEqual(len(resources), 1)
 
+    def test_ami_ssq(self):
+        factory = self.replay_flight_data('test_ami_sse')
+        p = self.load_policy({
+            'name': 'ubuntu-bionic',
+            'resource': 'aws.ami',
+            'query': [
+                {'Owners': ["123456789123"]},
+                {'Filters': [
+                    {'Name': 'name',
+                     'Values': ["ubuntu/images/hvm-ssd/ubuntu-bionic*"]}]}]},
+            session_factory=factory)
+        resources = p.run()
+        self.assertEqual(resources[0]['OwnerId'], '123456789123')
+
     def test_err_ami(self):
         factory = self.replay_flight_data("test_ami_not_found_err")
         ami_id = 'ami-123f000eee1f9f654'
diff --git a/tests/test_utils.py b/tests/test_utils.py
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -131,6 +131,12 @@ def test_all_proxy_with_full_url(self):
 
 class UtilTest(BaseTest):
 
+    def test_merge_dict_list(self):
+
+        assert utils.merge_dict_list([
+            {'a': 1, 'x': 0}, {'b': 2, 'x': 0}, {'c': 3, 'x': 1}]) == {
+                'a': 1, 'b': 2, 'c': 3, 'x': 1}
+
     def test_merge_dict(self):
         a = {'detail': {'eventName': ['CreateSubnet'],
                     'eventSource': ['ec2.amazonaws.com']},