mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Bugfix/52688 gcp compute missing image (#54468)
* adding (optionally) image information to inventory var * add boot image mapping to gcp_compute instance data for all disk image data in the configured zones Signed-off-by: Adam Miller <admiller@redhat.com>
This commit is contained in:
parent
ba50c6e06e
commit
75d733afd2
2 changed files with 93 additions and 9 deletions
3
changelogs/gcp-compute-add-image.yaml
Normal file
3
changelogs/gcp-compute-add-image.yaml
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
---
|
||||||
|
minor_changes:
|
||||||
|
- gcp_compute - add the image field to map to disk source iamges in the configured zones bringing it in line with old gce inventory script data
|
|
@ -75,6 +75,15 @@ DOCUMENTATION = '''
|
||||||
type: bool
|
type: bool
|
||||||
default: False
|
default: False
|
||||||
version_added: '2.8'
|
version_added: '2.8'
|
||||||
|
retrieve_image_info:
|
||||||
|
description:
|
||||||
|
- Populate the C(image) host fact for the instances returned with the GCP image name
|
||||||
|
- By default this plugin does not attempt to resolve the boot image of an instance to the image name cataloged in GCP
|
||||||
|
because of the performance overhead of the task.
|
||||||
|
- Unless this option is enabled, the C(image) host variable will be C(null)
|
||||||
|
type: bool
|
||||||
|
default: False
|
||||||
|
version_added: '2.8'
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
|
@ -165,10 +174,8 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
:param query: a formatted query string
|
:param query: a formatted query string
|
||||||
:return the JSON response containing a list of instances.
|
:return the JSON response containing a list of instances.
|
||||||
'''
|
'''
|
||||||
module = GcpMockModule(params)
|
response = self.auth_session.get(link, params={'filter': query})
|
||||||
auth = GcpSession(module, 'compute')
|
return self._return_if_object(self.fake_module, response)
|
||||||
response = auth.get(link, params={'filter': query})
|
|
||||||
return self._return_if_object(module, response)
|
|
||||||
|
|
||||||
def _get_zones(self, project, config_data):
|
def _get_zones(self, project, config_data):
|
||||||
'''
|
'''
|
||||||
|
@ -232,7 +239,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _format_items(self, items):
|
def _format_items(self, items, project_disks):
|
||||||
'''
|
'''
|
||||||
:param items: A list of hosts
|
:param items: A list of hosts
|
||||||
'''
|
'''
|
||||||
|
@ -252,9 +259,10 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
network['subnetwork'] = self._format_network_info(network['subnetwork'])
|
network['subnetwork'] = self._format_network_info(network['subnetwork'])
|
||||||
|
|
||||||
host['project'] = host['selfLink'].split('/')[6]
|
host['project'] = host['selfLink'].split('/')[6]
|
||||||
|
host['image'] = self._get_image(host, project_disks)
|
||||||
return items
|
return items
|
||||||
|
|
||||||
def _add_hosts(self, items, config_data, format_items=True):
|
def _add_hosts(self, items, config_data, format_items=True, project_disks=None):
|
||||||
'''
|
'''
|
||||||
:param items: A list of hosts
|
:param items: A list of hosts
|
||||||
:param config_data: configuration data
|
:param config_data: configuration data
|
||||||
|
@ -263,7 +271,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
if not items:
|
if not items:
|
||||||
return
|
return
|
||||||
if format_items:
|
if format_items:
|
||||||
items = self._format_items(items)
|
items = self._format_items(items, project_disks)
|
||||||
|
|
||||||
for host in items:
|
for host in items:
|
||||||
self._populate_host(host)
|
self._populate_host(host)
|
||||||
|
@ -328,6 +336,71 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
return accessConfig[u'natIP']
|
return accessConfig[u'natIP']
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def _get_image(self, instance, project_disks):
|
||||||
|
'''
|
||||||
|
:param instance: A instance response from GCP
|
||||||
|
:return the image of this instance or None
|
||||||
|
'''
|
||||||
|
image = None
|
||||||
|
if project_disks and 'disks' in instance:
|
||||||
|
for disk in instance['disks']:
|
||||||
|
if disk.get('boot'):
|
||||||
|
image = project_disks[disk["source"]]
|
||||||
|
return image
|
||||||
|
|
||||||
|
def _get_project_disks(self, config_data, query):
|
||||||
|
'''
|
||||||
|
project space disk images
|
||||||
|
'''
|
||||||
|
|
||||||
|
try:
|
||||||
|
self._project_disks
|
||||||
|
except AttributeError:
|
||||||
|
self._project_disks = {}
|
||||||
|
request_params = {'maxResults': 500, 'filter': query}
|
||||||
|
|
||||||
|
for project in config_data['projects']:
|
||||||
|
session_responses = []
|
||||||
|
page_token = True
|
||||||
|
while page_token:
|
||||||
|
response = self.auth_session.get(
|
||||||
|
'https://www.googleapis.com/compute/v1/projects/{0}/aggregated/disks'.format(project),
|
||||||
|
params=request_params
|
||||||
|
)
|
||||||
|
response_json = response.json()
|
||||||
|
if 'nextPageToken' in response_json:
|
||||||
|
request_params['pageToken'] = response_json['nextPageToken']
|
||||||
|
elif 'pageToken' in request_params:
|
||||||
|
del request_params['pageToken']
|
||||||
|
|
||||||
|
if 'items' in response_json:
|
||||||
|
session_responses.append(response_json)
|
||||||
|
page_token = 'pageToken' in request_params
|
||||||
|
|
||||||
|
for response in session_responses:
|
||||||
|
if 'items' in response:
|
||||||
|
# example k would be a zone or region name
|
||||||
|
# example v would be { "disks" : [], "otherkey" : "..." }
|
||||||
|
for zone_or_region, aggregate in response['items'].items():
|
||||||
|
if 'zones' in zone_or_region:
|
||||||
|
if 'disks' in aggregate:
|
||||||
|
zone = zone_or_region.replace('zones/', '')
|
||||||
|
for disk in aggregate['disks']:
|
||||||
|
if 'zones' in config_data and zone in config_data['zones']:
|
||||||
|
# If zones specified, only store those zones' data
|
||||||
|
if 'sourceImage' in disk:
|
||||||
|
self._project_disks[disk['selfLink']] = disk['sourceImage'].split('/')[-1]
|
||||||
|
else:
|
||||||
|
self._project_disks[disk['selfLink']] = disk['selfLink'].split('/')[-1]
|
||||||
|
|
||||||
|
else:
|
||||||
|
if 'sourceImage' in disk:
|
||||||
|
self._project_disks[disk['selfLink']] = disk['sourceImage'].split('/')[-1]
|
||||||
|
else:
|
||||||
|
self._project_disks[disk['selfLink']] = disk['selfLink'].split('/')[-1]
|
||||||
|
|
||||||
|
return self._project_disks
|
||||||
|
|
||||||
def _get_privateip(self, item):
|
def _get_privateip(self, item):
|
||||||
'''
|
'''
|
||||||
:param item: A host response from GCP
|
:param item: A host response from GCP
|
||||||
|
@ -358,8 +431,16 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
'service_account_email': self.get_option('service_account_email'),
|
'service_account_email': self.get_option('service_account_email'),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.fake_module = GcpMockModule(params)
|
||||||
|
self.auth_session = GcpSession(self.fake_module, 'compute')
|
||||||
|
|
||||||
query = self._get_query_options(params['filters'])
|
query = self._get_query_options(params['filters'])
|
||||||
|
|
||||||
|
if self.get_option('retrieve_image_info'):
|
||||||
|
project_disks = self._get_project_disks(config_data, query)
|
||||||
|
else:
|
||||||
|
project_disks = None
|
||||||
|
|
||||||
# Cache logic
|
# Cache logic
|
||||||
if cache:
|
if cache:
|
||||||
cache = self.get_option('cache')
|
cache = self.get_option('cache')
|
||||||
|
@ -373,7 +454,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
results = self._cache[cache_key]
|
results = self._cache[cache_key]
|
||||||
for project in results:
|
for project in results:
|
||||||
for zone in results[project]:
|
for zone in results[project]:
|
||||||
self._add_hosts(results[project][zone], config_data, False)
|
self._add_hosts(results[project][zone], config_data, False, project_disks=project_disks)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
cache_needs_update = True
|
cache_needs_update = True
|
||||||
|
|
||||||
|
@ -390,7 +471,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
link = self._instances % (project, zone)
|
link = self._instances % (project, zone)
|
||||||
params['zone'] = zone
|
params['zone'] = zone
|
||||||
resp = self.fetch_list(params, link, query)
|
resp = self.fetch_list(params, link, query)
|
||||||
self._add_hosts(resp.get('items'), config_data)
|
self._add_hosts(resp.get('items'), config_data, project_disks=project_disks)
|
||||||
cached_data[project][zone] = resp.get('items')
|
cached_data[project][zone] = resp.get('items')
|
||||||
|
|
||||||
if cache_needs_update:
|
if cache_needs_update:
|
||||||
|
|
Loading…
Reference in a new issue