def official_flatcar_ami_release(ec2_client: BaseClient) -> Optional[str]: """Check stable.release.flatcar-linux.net for the latest flatcar AMI. Verify it's on AWS.""" # Flatcar images only live for 9 months. # Rather than hardcode a list of AMIs by region that will die, we use # their JSON feed of the current ones. JSON_FEED_URL = 'https://stable.release.flatcar-linux.net/amd64-usr/current/flatcar_production_ami_all.json' region = ec2_client._client_config.region_name feed = json.loads(urllib.request.urlopen(JSON_FEED_URL).read()) try: for ami_record in feed['amis']: # Scan the list of regions if ami_record['name'] == region: # When we find ours, return the AMI ID ami = ami_record['hvm'] # verify it exists on AWS response = ec2_client.describe_images(Filters=[{ 'Name': 'image-id', 'Values': [ami] }]) if len( response['Images'] ) == 1 and response['Images'][0]['State'] == 'available': return ami # We didn't find it logger.warning( f'Flatcar image feed at {JSON_FEED_URL} does not have an image for region {region}' ) except KeyError: # We didn't see a field we need logger.warning( f'Flatcar image feed at {JSON_FEED_URL} does not have expected format' )
def aws_marketplace_flatcar_ami_search(ec2_client: BaseClient) -> Optional[str]: """Query AWS for all AMI names matching 'Flatcar-stable-*' and return the most recent one.""" response: dict = ec2_client.describe_images(Owners=['aws-marketplace'], Filters=[{'Name': 'name', 'Values': ['Flatcar-stable-*']}]) latest: dict = {'CreationDate': '0lder than atoms.'} for image in response['Images']: if image["Architecture"] == "x86_64" and image["State"] == "available": if image['CreationDate'] > latest['CreationDate']: latest = image return latest.get('ImageId', None)
def list_from_aws(cls: Type["EC2ImageResourceSpec"], client: BaseClient, account_id: str, region: str) -> ListFromAWSResult: """Return a dict of dicts of the format: {'image_1_arn': {image_1_dict}, 'image_2_arn': {image_2_dict}, ...} Where the dicts represent results from describe_images.""" images = {} resp = client.describe_images(Owners=["self"]) for image in resp["Images"]: image_id = image["ImageId"] resource_arn = cls.generate_arn(account_id=account_id, region=region, resource_id=image_id) images[resource_arn] = image return ListFromAWSResult(resources=images)
def list_from_aws(cls: Type["EC2ImageResourceSpec"], client: BaseClient, account_id: str, region: str) -> ListFromAWSResult: """Return a dict of dicts of the format: {'image_1_arn': {image_1_dict}, 'image_2_arn': {image_2_dict}, ...} Where the dicts represent results from describe_images.""" images = {} resp = client.describe_images(Owners=["self"]) for image in resp["Images"]: image_id = image["ImageId"] time.sleep( 0.25) # seems necessary to avoid frequent RequestLimitExceeded perms_resp = client.describe_image_attribute( Attribute="launchPermission", ImageId=image_id) launch_permissions = perms_resp["LaunchPermissions"] image["LaunchPermissions"] = launch_permissions resource_arn = cls.generate_arn(account_id, region, image_id) images[resource_arn] = image return ListFromAWSResult(resources=images)
def get_ami_ids_names(client: BaseClient, ami_ids: Set[str]) -> Dict[str, str]: """Get a dict of ami ids to ami names""" resp = client.describe_images(ImageIds=list(ami_ids)) images = resp["Images"] ami_ids_names = {image["ImageId"]: image["Name"] for image in images} return ami_ids_names