moto: 'owner-id' for DescribeImages is not yet supported

i am trying to test out a routine to manage our AMIs. the process involves filtering the AMIs by owner (aws account id) of the images to pull back a smaller set from aws. turns out, owner-id is not yet supported.

moto, boto3, botocore

i installed it using sudo pip3 install -r requirements.txt and moto is in that file.

Name: moto Version: 1.0.1 Summary: A library that allows your python tests to easily mock out the boto library Home-page: https://github.com/spulec/moto Author: Steve Pulec Author-email: spulec@gmail.com License: Apache Location: /usr/lib/python3.5/site-packages Requires: requests, python-dateutil, cookies, mock, boto3, six, werkzeug, pyaml, xmltodict, Jinja2, pytz, dicttoxml, boto

Name: boto3 Version: 1.4.4 Summary: The AWS SDK for Python Home-page: https://github.com/boto/boto3 Author: Amazon Web Services Author-email: UNKNOWN License: Apache License 2.0 Location: /usr/lib/python3.5/site-packages Requires: jmespath, s3transfer, botocore

Name: botocore Version: 1.5.95 Summary: Low-level, data-driven core of boto 3. Home-page: https://github.com/boto/botocore Author: Amazon Web Services Author-email: UNKNOWN License: Apache License 2.0 Location: /usr/lib/python3.5/site-packages Requires: python-dateutil, jmespath, docutils

stack trace from pytest

$ pytest -v test/test_manage_amis.py 
================================================================ test session starts =================================================================
platform linux -- Python 3.5.3, pytest-3.2.2, py-1.4.34, pluggy-0.4.0 -- /usr/bin/python3
cachedir: .cache
rootdir: /home/mock/projects/engineering-puppet, inifile:
collected 1 item                                                                                                                                      

test/test_manage_amis.py::TestManageAmis::test_get_images_generated_by_deployment_tools FAILED

====================================================================== FAILURES ======================================================================
____________________________________________ TestManageAmis.test_get_images_generated_by_deployment_tools ____________________________________________

self = <test_manage_amis.TestManageAmis testMethod=test_get_images_generated_by_deployment_tools>

    @mock_ec2
    @mock_sts
    def test_get_images_generated_by_deployment_tools(self):
        # setup
        resource = boto3.resource('ec2', region_name='us-east-1')
        client = boto3.client('ec2', region_name='us-east-1')
        session = manage_amis.get_session('111133335555', region='us-east-1')
    
        all_images = list()
        ami_tags = {'Key': 'tools_info',
                    'Value': str({'user': 'jenkins', 'aws-ami': 'ami-ffff9999'})}
    
        # generate tools images
        tools_ami_ids = ['1234abcd', 'abcd1234', '1a2b3c4d', 'a1b2c3d4', '12ab34cd', 'dc43ba21']
        for ami_id in tools_ami_ids:
            response = client.run_instances(ImageId="ami-{}".format(ami_id), MinCount=1, MaxCount=2)
            instance_id = response['Instances'][0]['InstanceId']
            image = client.create_image(InstanceId=instance_id, Name="test-{}".format(ami_id))
            client.create_tags(Resources=[image['ImageId']], Tags=[ami_tags])
            all_images.append(image['ImageId'])
            client.terminate_instances(InstanceIds=[instance_id])
            client.run_instances(ImageId=image['ImageId'], MinCount=1, MaxCount=2)
    
        # generate non tools images
        non_tools_ami_ids = ['5678efab', 'efab5678', '5a6b7c8d']
        for ami_id in non_tools_ami_ids:
            response = client.run_instances(ImageId="ami-{}".format(ami_id), MinCount=1, MaxCount=2)
            instance_id = response['Instances'][0]['InstanceId']
            image = client.create_image(InstanceId=instance_id, Name="test-{}".format(ami_id))
            all_images.append(image['ImageId'])
            client.terminate_instances(InstanceIds=[instance_id])
            client.run_instances(ImageId=image['ImageId'], MinCount=1, MaxCount=2)
    
    
        # test the function
>       amis = manage_amis.get_images_generated_by_deployment_tools(session, '111133335555')

test/test_manage_amis.py:77: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
manage-amis.py:186: in get_images_generated_by_deployment_tools
    images = ec2.describe_images(Filters=image_filter)['Images']
/usr/lib/python3.5/site-packages/botocore/client.py:310: in _api_call
    return self._make_api_call(operation_name, kwargs)
/usr/lib/python3.5/site-packages/botocore/client.py:586: in _make_api_call
    operation_model, request_dict)
/usr/lib/python3.5/site-packages/botocore/endpoint.py:141: in make_request
    return self._send_request(request_dict, operation_model)
/usr/lib/python3.5/site-packages/botocore/endpoint.py:170: in _send_request
    success_response, exception):
/usr/lib/python3.5/site-packages/botocore/endpoint.py:249: in _needs_retry
    caught_exception=caught_exception, request_dict=request_dict)
/usr/lib/python3.5/site-packages/botocore/hooks.py:227: in emit
    return self._emit(event_name, kwargs)
/usr/lib/python3.5/site-packages/botocore/hooks.py:210: in _emit
    response = handler(**kwargs)
/usr/lib/python3.5/site-packages/botocore/retryhandler.py:183: in __call__
    if self._checker(attempts, response, caught_exception):
/usr/lib/python3.5/site-packages/botocore/retryhandler.py:251: in __call__
    caught_exception)
/usr/lib/python3.5/site-packages/botocore/retryhandler.py:269: in _should_retry
    return self._checker(attempt_number, response, caught_exception)
/usr/lib/python3.5/site-packages/botocore/retryhandler.py:317: in __call__
    caught_exception)
/usr/lib/python3.5/site-packages/botocore/retryhandler.py:223: in __call__
    attempt_number, caught_exception)
/usr/lib/python3.5/site-packages/botocore/retryhandler.py:359: in _check_caught_exception
    raise caught_exception
/usr/lib/python3.5/site-packages/botocore/endpoint.py:204: in _get_response
    proxies=self.proxies, timeout=self.timeout)
/usr/lib/python3.5/site-packages/botocore/vendored/requests/sessions.py:573: in send
    r = adapter.send(request, **kwargs)
/usr/lib/python3.5/site-packages/moto/packages/responses/responses.py:302: in unbound_on_send
    return self._on_request(adapter, request, *a, **kwargs)
/usr/lib/python3.5/site-packages/moto/packages/responses/responses.py:255: in _on_request
    status, r_headers, body = match['callback'](request)
/usr/lib/python3.5/site-packages/moto/core/utils.py:164: in __call__
    result = self.callback(request, request.url, request.headers)
/usr/lib/python3.5/site-packages/moto/core/responses.py:111: in dispatch
    return cls()._dispatch(*args, **kwargs)
/usr/lib/python3.5/site-packages/moto/core/responses.py:179: in _dispatch
    return self.call_action()
/usr/lib/python3.5/site-packages/moto/core/responses.py:196: in call_action
    response = method()
/usr/lib/python3.5/site-packages/moto/ec2/responses/amis.py:48: in describe_images
    ami_ids=ami_ids, filters=filters, exec_users=exec_users)
/usr/lib/python3.5/site-packages/moto/ec2/models.py:1068: in describe_images
    return generic_filter(filters, images)
/usr/lib/python3.5/site-packages/moto/ec2/utils.py:493: in generic_filter
    objects = [obj for obj in objects if is_filter_matching(
/usr/lib/python3.5/site-packages/moto/ec2/utils.py:494: in <listcomp>
    obj, _filter, _filter_value)]
/usr/lib/python3.5/site-packages/moto/ec2/utils.py:471: in is_filter_matching
    value = obj.get_filter_value(filter)
/usr/lib/python3.5/site-packages/moto/ec2/models.py:1026: in get_filter_value
    "The filter '{0}' for DescribeImages".format(filter_name))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <moto.ec2.models.EC2Backend object at 0x7f920f63df98>, blurb = "The filter 'owner-id' for DescribeImages"

    def raise_not_implemented_error(self, blurb):
        msg = "{0} has not been implemented in Moto yet." \
              " Feel free to open an issue at" \
              " https://github.com/spulec/moto/issues".format(blurb)
>       raise NotImplementedError(msg)
E       NotImplementedError: The filter 'owner-id' for DescribeImages has not been implemented in Moto yet. Feel free to open an issue at https://github.com/spulec/moto/issues

/usr/lib/python3.5/site-packages/moto/ec2/models.py:3596: NotImplementedError
---------------------------------------------------------------- Captured stderr call ----------------------------------------------------------------
2017-09-26 15:05:32,581 [INFO    ] : root : get_session : 118 : Getting session token...
2017-09-26 15:05:32,954 [INFO    ] : root : get_images_generated_by_deployment_tools : 185 : Fetching AMI objects for account id 111133335555...

function call

the call where the tag is being specified is in the manage-ami.py file. the routing from that below:

def get_images_generated_by_deployment_tools(session, account_id):
    """
    get all the images generated by our deployment tools.
    param session: boto3 session ot establish connection to account
     type session: boto3.session.Session class
    param accound_id: id of the account to filter the images down to ours
     type account_id: string
    returns: list of ...
    """
    # get an ec2 session client
    LOG.debug("Creating EC2 session...")
    ec2 = session.client('ec2', region_name='us-east-1')

    # this process is similar to the tag_images fetch, but the filter is different here.
    # we want to narrow down this list as much as possible. and not filtering by account 
    # id will return ALL AMIs, over 85,000 at the time of this coding.
    LOG.debug("""Set filter to look for owner-id = "{}" and tag-key = "tools_info" """.format(account_id))
    image_filter = [{'Name': 'owner-id', 'Values': [account_id]},
                    {'Name': 'tag-key', 'Values': ['tools_info']}]

    # we only care about the images
    LOG.info("Fetching AMI objects for account id {}...".format(account_id))
    images = ec2.describe_images(Filters=image_filter)['Images']

    # we only care about the image ids of the cared-about images from above
    LOG.debug("Getting AMI ids from the list of images...")
    image_ids = [v for i in images for k,v in i.items() if k == "ImageId"]

    return image_ids

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 21

Most upvoted comments

ah, ok.

i have tried this, gotten to the pull request, but one of the files is showing changes i didn’t make, so i will need to do this again to make sure the files are correct. i need to head out right now, but i’ll try to submit later.