diff --git a/salt/cloud/clouds/ec2.py b/salt/cloud/clouds/ec2.py index adaaf1f73fd2..40d68e16640c 100644 --- a/salt/cloud/clouds/ec2.py +++ b/salt/cloud/clouds/ec2.py @@ -1214,21 +1214,28 @@ def get_imageid(vm_): ) if image.startswith('ami-'): return image + else: + return _get_imageid_from_image_name(image) + + +def _get_imageid_from_image_name(image_name): + ''' + Returns most recent 'ami-*' imageId matching image name + ''' # a poor man's cache - if not hasattr(get_imageid, 'images'): - get_imageid.images = {} - elif image in get_imageid.images: - return get_imageid.images[image] + if not hasattr(_get_imageid_from_image_name, 'images'): + _get_imageid_from_image_name.images = {} + elif image_name in _get_imageid_from_image_name.images: + return _get_imageid_from_image_name.images[image_name] params = {'Action': 'DescribeImages', 'Filter.0.Name': 'name', - 'Filter.0.Value.0': image} + 'Filter.0.Value.0': image_name} # Query AWS, sort by 'creationDate' and get the last imageId - _t = lambda x: datetime.datetime.strptime(x['creationDate'], '%Y-%m-%dT%H:%M:%S.%fZ') image_id = sorted(aws.query(params, location=get_location(), provider=get_provider(), opts=__opts__, sigver='4'), - lambda i, j: salt.utils.compat.cmp(_t(i), _t(j)) + key=lambda x: datetime.datetime.strptime(x['creationDate'], '%Y-%m-%dT%H:%M:%S.%fZ') )[-1]['imageId'] - get_imageid.images[image] = image_id + _get_imageid_from_image_name.images[image_name] = image_id return image_id diff --git a/tests/unit/cloud/clouds/test_ec2.py b/tests/unit/cloud/clouds/test_ec2.py index d6da53090142..13603ae38965 100644 --- a/tests/unit/cloud/clouds/test_ec2.py +++ b/tests/unit/cloud/clouds/test_ec2.py @@ -87,3 +87,20 @@ def test_get_password_data(self, query, get_provider, get_location, _get_node): ) assert ret['passwordData'] == PASS_DATA assert ret['password'] == 'testp4ss!' + + @patch('salt.cloud.clouds.ec2.get_location') + @patch('salt.cloud.clouds.ec2.get_provider') + @patch('salt.utils.aws.query') + def test__get_imageid_by_name(self, query, get_provider, get_location): + # Trimmed list and stripped dictionary keys for brevity + query.return_value = [ + {u'creationDate': '2019-01-30T23:40:58.000Z', u'imageId': 'ami-02eac2c0129f6376b'}, + {u'creationDate': '2019-03-15T00:08:05.000Z', u'imageId': 'ami-089ccd342f0be98ab'}, + {u'creationDate': '2018-05-14T17:19:51.000Z', u'imageId': 'ami-4b6bff34'}, + {u'creationDate': '2018-01-12T20:33:32.000Z', u'imageId': 'ami-4bf3d731'}] + get_location.return_value = 'us-west2' + get_provider.return_value = 'ec2' + + # Mock makes argument irrelevant; illustrates value used to obtain mock + imageid = ec2._get_imageid_from_image_name('CentOS Linux 7*') + assert imageid == 'ami-089ccd342f0be98ab'