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
|
||||
default: False
|
||||
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 = '''
|
||||
|
@ -165,10 +174,8 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
|||
:param query: a formatted query string
|
||||
:return the JSON response containing a list of instances.
|
||||
'''
|
||||
module = GcpMockModule(params)
|
||||
auth = GcpSession(module, 'compute')
|
||||
response = auth.get(link, params={'filter': query})
|
||||
return self._return_if_object(module, response)
|
||||
response = self.auth_session.get(link, params={'filter': query})
|
||||
return self._return_if_object(self.fake_module, response)
|
||||
|
||||
def _get_zones(self, project, config_data):
|
||||
'''
|
||||
|
@ -232,7 +239,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
|||
|
||||
return result
|
||||
|
||||
def _format_items(self, items):
|
||||
def _format_items(self, items, project_disks):
|
||||
'''
|
||||
:param items: A list of hosts
|
||||
'''
|
||||
|
@ -252,9 +259,10 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
|||
network['subnetwork'] = self._format_network_info(network['subnetwork'])
|
||||
|
||||
host['project'] = host['selfLink'].split('/')[6]
|
||||
host['image'] = self._get_image(host, project_disks)
|
||||
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 config_data: configuration data
|
||||
|
@ -263,7 +271,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
|||
if not items:
|
||||
return
|
||||
if format_items:
|
||||
items = self._format_items(items)
|
||||
items = self._format_items(items, project_disks)
|
||||
|
||||
for host in items:
|
||||
self._populate_host(host)
|
||||
|
@ -328,6 +336,71 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
|||
return accessConfig[u'natIP']
|
||||
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):
|
||||
'''
|
||||
: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'),
|
||||
}
|
||||
|
||||
self.fake_module = GcpMockModule(params)
|
||||
self.auth_session = GcpSession(self.fake_module, 'compute')
|
||||
|
||||
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
|
||||
if cache:
|
||||
cache = self.get_option('cache')
|
||||
|
@ -373,7 +454,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
|||
results = self._cache[cache_key]
|
||||
for project in results:
|
||||
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:
|
||||
cache_needs_update = True
|
||||
|
||||
|
@ -390,7 +471,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
|||
link = self._instances % (project, zone)
|
||||
params['zone'] = zone
|
||||
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')
|
||||
|
||||
if cache_needs_update:
|
||||
|
|
Loading…
Reference in a new issue