inventory plugins: use f-strings (#9323)
* inventory plugins: use f-strings * add changelog fragpull/8437/merge
parent
cb2cd00cd1
commit
1d8f0b2942
|
@ -0,0 +1,14 @@
|
||||||
|
minor_changes:
|
||||||
|
- cobbler inventory plugin - use f-strings instead of interpolations or ``format`` (https://github.com/ansible-collections/community.general/pull/9323).
|
||||||
|
- gitlab_runners inventory plugin - use f-strings instead of interpolations or ``format`` (https://github.com/ansible-collections/community.general/pull/9323).
|
||||||
|
- icinga2 inventory plugin - use f-strings instead of interpolations or ``format`` (https://github.com/ansible-collections/community.general/pull/9323).
|
||||||
|
- linode inventory plugin - use f-strings instead of interpolations or ``format`` (https://github.com/ansible-collections/community.general/pull/9323).
|
||||||
|
- lxd inventory plugin - use f-strings instead of interpolations or ``format`` (https://github.com/ansible-collections/community.general/pull/9323).
|
||||||
|
- nmap inventory plugin - use f-strings instead of interpolations or ``format`` (https://github.com/ansible-collections/community.general/pull/9323).
|
||||||
|
- online inventory plugin - use f-strings instead of interpolations or ``format`` (https://github.com/ansible-collections/community.general/pull/9323).
|
||||||
|
- opennebula inventory plugin - use f-strings instead of interpolations or ``format`` (https://github.com/ansible-collections/community.general/pull/9323).
|
||||||
|
- proxmox inventory plugin - use f-strings instead of interpolations or ``format`` (https://github.com/ansible-collections/community.general/pull/9323).
|
||||||
|
- scaleway inventory plugin - use f-strings instead of interpolations or ``format`` (https://github.com/ansible-collections/community.general/pull/9323).
|
||||||
|
- stackpath_compute inventory plugin - use f-strings instead of interpolations or ``format`` (https://github.com/ansible-collections/community.general/pull/9323).
|
||||||
|
- virtualbox inventory plugin - use f-strings instead of interpolations or ``format`` (https://github.com/ansible-collections/community.general/pull/9323).
|
||||||
|
- xen_orchestra inventory plugin - use f-strings instead of interpolations or ``format`` (https://github.com/ansible-collections/community.general/pull/9323).
|
|
@ -160,7 +160,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||||
raise AnsibleError('Could not import xmlrpc client library')
|
raise AnsibleError('Could not import xmlrpc client library')
|
||||||
|
|
||||||
if self.connection is None:
|
if self.connection is None:
|
||||||
self.display.vvvv('Connecting to %s\n' % self.cobbler_url)
|
self.display.vvvv(f'Connecting to {self.cobbler_url}\n')
|
||||||
self.connection = xmlrpc_client.Server(self.cobbler_url, allow_none=True)
|
self.connection = xmlrpc_client.Server(self.cobbler_url, allow_none=True)
|
||||||
self.token = None
|
self.token = None
|
||||||
if self.get_option('user') is not None:
|
if self.get_option('user') is not None:
|
||||||
|
@ -211,7 +211,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||||
return self._cache[self.cache_key]['systems']
|
return self._cache[self.cache_key]['systems']
|
||||||
|
|
||||||
def _add_safe_group_name(self, group, child=None):
|
def _add_safe_group_name(self, group, child=None):
|
||||||
group_name = self.inventory.add_group(to_safe_group_name('%s%s' % (self.get_option('group_prefix'), group.lower().replace(" ", ""))))
|
group_name = self.inventory.add_group(to_safe_group_name(f"{self.get_option('group_prefix')}{group.lower().replace(' ', '')}"))
|
||||||
if child is not None:
|
if child is not None:
|
||||||
self.inventory.add_child(group_name, child)
|
self.inventory.add_child(group_name, child)
|
||||||
return group_name
|
return group_name
|
||||||
|
@ -243,16 +243,16 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||||
|
|
||||||
for profile in self._get_profiles():
|
for profile in self._get_profiles():
|
||||||
if profile['parent']:
|
if profile['parent']:
|
||||||
self.display.vvvv('Processing profile %s with parent %s\n' % (profile['name'], profile['parent']))
|
self.display.vvvv(f"Processing profile {profile['name']} with parent {profile['parent']}\n")
|
||||||
if not self._exclude_profile(profile['parent']):
|
if not self._exclude_profile(profile['parent']):
|
||||||
parent_group_name = self._add_safe_group_name(profile['parent'])
|
parent_group_name = self._add_safe_group_name(profile['parent'])
|
||||||
self.display.vvvv('Added profile parent group %s\n' % parent_group_name)
|
self.display.vvvv(f'Added profile parent group {parent_group_name}\n')
|
||||||
if not self._exclude_profile(profile['name']):
|
if not self._exclude_profile(profile['name']):
|
||||||
group_name = self._add_safe_group_name(profile['name'])
|
group_name = self._add_safe_group_name(profile['name'])
|
||||||
self.display.vvvv('Added profile group %s\n' % group_name)
|
self.display.vvvv(f'Added profile group {group_name}\n')
|
||||||
self.inventory.add_child(parent_group_name, group_name)
|
self.inventory.add_child(parent_group_name, group_name)
|
||||||
else:
|
else:
|
||||||
self.display.vvvv('Processing profile %s without parent\n' % profile['name'])
|
self.display.vvvv(f"Processing profile {profile['name']} without parent\n")
|
||||||
# Create a hierarchy of profile names
|
# Create a hierarchy of profile names
|
||||||
profile_elements = profile['name'].split('-')
|
profile_elements = profile['name'].split('-')
|
||||||
i = 0
|
i = 0
|
||||||
|
@ -260,12 +260,12 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||||
profile_group = '-'.join(profile_elements[0:i + 1])
|
profile_group = '-'.join(profile_elements[0:i + 1])
|
||||||
profile_group_child = '-'.join(profile_elements[0:i + 2])
|
profile_group_child = '-'.join(profile_elements[0:i + 2])
|
||||||
if self._exclude_profile(profile_group):
|
if self._exclude_profile(profile_group):
|
||||||
self.display.vvvv('Excluding profile %s\n' % profile_group)
|
self.display.vvvv(f'Excluding profile {profile_group}\n')
|
||||||
break
|
break
|
||||||
group_name = self._add_safe_group_name(profile_group)
|
group_name = self._add_safe_group_name(profile_group)
|
||||||
self.display.vvvv('Added profile group %s\n' % group_name)
|
self.display.vvvv(f'Added profile group {group_name}\n')
|
||||||
child_group_name = self._add_safe_group_name(profile_group_child)
|
child_group_name = self._add_safe_group_name(profile_group_child)
|
||||||
self.display.vvvv('Added profile child group %s to %s\n' % (child_group_name, group_name))
|
self.display.vvvv(f'Added profile child group {child_group_name} to {group_name}\n')
|
||||||
self.inventory.add_child(group_name, child_group_name)
|
self.inventory.add_child(group_name, child_group_name)
|
||||||
i = i + 1
|
i = i + 1
|
||||||
|
|
||||||
|
@ -273,7 +273,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||||
self.group = to_safe_group_name(self.get_option('group'))
|
self.group = to_safe_group_name(self.get_option('group'))
|
||||||
if self.group is not None and self.group != '':
|
if self.group is not None and self.group != '':
|
||||||
self.inventory.add_group(self.group)
|
self.inventory.add_group(self.group)
|
||||||
self.display.vvvv('Added site group %s\n' % self.group)
|
self.display.vvvv(f'Added site group {self.group}\n')
|
||||||
|
|
||||||
ip_addresses = {}
|
ip_addresses = {}
|
||||||
ipv6_addresses = {}
|
ipv6_addresses = {}
|
||||||
|
@ -286,14 +286,14 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||||
interfaces = host['interfaces']
|
interfaces = host['interfaces']
|
||||||
|
|
||||||
if set(host['mgmt_classes']) & set(self.include_mgmt_classes):
|
if set(host['mgmt_classes']) & set(self.include_mgmt_classes):
|
||||||
self.display.vvvv('Including host %s in mgmt_classes %s\n' % (host['name'], host['mgmt_classes']))
|
self.display.vvvv(f"Including host {host['name']} in mgmt_classes {host['mgmt_classes']}\n")
|
||||||
else:
|
else:
|
||||||
if self._exclude_profile(host['profile']):
|
if self._exclude_profile(host['profile']):
|
||||||
self.display.vvvv('Excluding host %s in profile %s\n' % (host['name'], host['profile']))
|
self.display.vvvv(f"Excluding host {host['name']} in profile {host['profile']}\n")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if set(host['mgmt_classes']) & set(self.exclude_mgmt_classes):
|
if set(host['mgmt_classes']) & set(self.exclude_mgmt_classes):
|
||||||
self.display.vvvv('Excluding host %s in mgmt_classes %s\n' % (host['name'], host['mgmt_classes']))
|
self.display.vvvv(f"Excluding host {host['name']} in mgmt_classes {host['mgmt_classes']}\n")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# hostname is often empty for non-static IP hosts
|
# hostname is often empty for non-static IP hosts
|
||||||
|
@ -303,21 +303,21 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||||
this_dns_name = ivalue.get('dns_name', None)
|
this_dns_name = ivalue.get('dns_name', None)
|
||||||
if this_dns_name is not None and this_dns_name != "":
|
if this_dns_name is not None and this_dns_name != "":
|
||||||
hostname = make_unsafe(this_dns_name)
|
hostname = make_unsafe(this_dns_name)
|
||||||
self.display.vvvv('Set hostname to %s from %s\n' % (hostname, iname))
|
self.display.vvvv(f'Set hostname to {hostname} from {iname}\n')
|
||||||
|
|
||||||
if hostname == '':
|
if hostname == '':
|
||||||
self.display.vvvv('Cannot determine hostname for host %s, skipping\n' % host['name'])
|
self.display.vvvv(f"Cannot determine hostname for host {host['name']}, skipping\n")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.inventory.add_host(hostname)
|
self.inventory.add_host(hostname)
|
||||||
self.display.vvvv('Added host %s hostname %s\n' % (host['name'], hostname))
|
self.display.vvvv(f"Added host {host['name']} hostname {hostname}\n")
|
||||||
|
|
||||||
# Add host to profile group
|
# Add host to profile group
|
||||||
if host['profile'] != '':
|
if host['profile'] != '':
|
||||||
group_name = self._add_safe_group_name(host['profile'], child=hostname)
|
group_name = self._add_safe_group_name(host['profile'], child=hostname)
|
||||||
self.display.vvvv('Added host %s to profile group %s\n' % (hostname, group_name))
|
self.display.vvvv(f'Added host {hostname} to profile group {group_name}\n')
|
||||||
else:
|
else:
|
||||||
self.display.warning('Host %s has an empty profile\n' % (hostname))
|
self.display.warning(f'Host {hostname} has an empty profile\n')
|
||||||
|
|
||||||
# Add host to groups specified by group_by fields
|
# Add host to groups specified by group_by fields
|
||||||
for group_by in self.group_by:
|
for group_by in self.group_by:
|
||||||
|
@ -327,7 +327,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||||
groups = [host[group_by]] if isinstance(host[group_by], str) else host[group_by]
|
groups = [host[group_by]] if isinstance(host[group_by], str) else host[group_by]
|
||||||
for group in groups:
|
for group in groups:
|
||||||
group_name = self._add_safe_group_name(group, child=hostname)
|
group_name = self._add_safe_group_name(group, child=hostname)
|
||||||
self.display.vvvv('Added host %s to group_by %s group %s\n' % (hostname, group_by, group_name))
|
self.display.vvvv(f'Added host {hostname} to group_by {group_by} group {group_name}\n')
|
||||||
|
|
||||||
# Add to group for this inventory
|
# Add to group for this inventory
|
||||||
if self.group is not None:
|
if self.group is not None:
|
||||||
|
@ -377,7 +377,7 @@ class InventoryModule(BaseInventoryPlugin, Cacheable):
|
||||||
try:
|
try:
|
||||||
self.inventory.set_variable(hostname, 'cobbler', make_unsafe(host))
|
self.inventory.set_variable(hostname, 'cobbler', make_unsafe(host))
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
self.display.warning("Could not set host info for %s: %s" % (hostname, to_text(e)))
|
self.display.warning(f"Could not set host info for {hostname}: {to_text(e)}")
|
||||||
|
|
||||||
if self.get_option('want_ip_addresses'):
|
if self.get_option('want_ip_addresses'):
|
||||||
self.inventory.set_variable(self.group, 'cobbler_ipv4_addresses', make_unsafe(ip_addresses))
|
self.inventory.set_variable(self.group, 'cobbler_ipv4_addresses', make_unsafe(ip_addresses))
|
||||||
|
|
|
@ -124,7 +124,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||||
# Create groups based on variable values and add the corresponding hosts to it
|
# Create groups based on variable values and add the corresponding hosts to it
|
||||||
self._add_host_to_keyed_groups(self.get_option('keyed_groups'), host_attrs, host, strict=strict)
|
self._add_host_to_keyed_groups(self.get_option('keyed_groups'), host_attrs, host, strict=strict)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise AnsibleParserError('Unable to fetch hosts from GitLab API, this was the original exception: %s' % to_native(e))
|
raise AnsibleParserError(f'Unable to fetch hosts from GitLab API, this was the original exception: {to_native(e)}')
|
||||||
|
|
||||||
def verify_file(self, path):
|
def verify_file(self, path):
|
||||||
"""Return the possibly of a file being consumable by this plugin."""
|
"""Return the possibly of a file being consumable by this plugin."""
|
||||||
|
|
|
@ -141,7 +141,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||||
'User-Agent': "ansible-icinga2-inv",
|
'User-Agent': "ansible-icinga2-inv",
|
||||||
'Accept': "application/json",
|
'Accept': "application/json",
|
||||||
}
|
}
|
||||||
api_status_url = self.icinga2_url + "/status"
|
api_status_url = f"{self.icinga2_url}/status"
|
||||||
request_args = {
|
request_args = {
|
||||||
'headers': self.headers,
|
'headers': self.headers,
|
||||||
'url_username': self.icinga2_user,
|
'url_username': self.icinga2_user,
|
||||||
|
@ -151,7 +151,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||||
open_url(api_status_url, **request_args)
|
open_url(api_status_url, **request_args)
|
||||||
|
|
||||||
def _post_request(self, request_url, data=None):
|
def _post_request(self, request_url, data=None):
|
||||||
self.display.vvv("Requested URL: %s" % request_url)
|
self.display.vvv(f"Requested URL: {request_url}")
|
||||||
request_args = {
|
request_args = {
|
||||||
'headers': self.headers,
|
'headers': self.headers,
|
||||||
'url_username': self.icinga2_user,
|
'url_username': self.icinga2_user,
|
||||||
|
@ -160,42 +160,38 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||||
}
|
}
|
||||||
if data is not None:
|
if data is not None:
|
||||||
request_args['data'] = json.dumps(data)
|
request_args['data'] = json.dumps(data)
|
||||||
self.display.vvv("Request Args: %s" % request_args)
|
self.display.vvv(f"Request Args: {request_args}")
|
||||||
try:
|
try:
|
||||||
response = open_url(request_url, **request_args)
|
response = open_url(request_url, **request_args)
|
||||||
except HTTPError as e:
|
except HTTPError as e:
|
||||||
try:
|
try:
|
||||||
error_body = json.loads(e.read().decode())
|
error_body = json.loads(e.read().decode())
|
||||||
self.display.vvv("Error returned: {0}".format(error_body))
|
self.display.vvv(f"Error returned: {error_body}")
|
||||||
except Exception:
|
except Exception:
|
||||||
error_body = {"status": None}
|
error_body = {"status": None}
|
||||||
if e.code == 404 and error_body.get('status') == "No objects found.":
|
if e.code == 404 and error_body.get('status') == "No objects found.":
|
||||||
raise AnsibleParserError("Host filter returned no data. Please confirm your host_filter value is valid")
|
raise AnsibleParserError("Host filter returned no data. Please confirm your host_filter value is valid")
|
||||||
raise AnsibleParserError("Unexpected data returned: {0} -- {1}".format(e, error_body))
|
raise AnsibleParserError(f"Unexpected data returned: {e} -- {error_body}")
|
||||||
|
|
||||||
response_body = response.read()
|
response_body = response.read()
|
||||||
json_data = json.loads(response_body.decode('utf-8'))
|
json_data = json.loads(response_body.decode('utf-8'))
|
||||||
self.display.vvv("Returned Data: %s" % json.dumps(json_data, indent=4, sort_keys=True))
|
self.display.vvv(f"Returned Data: {json.dumps(json_data, indent=4, sort_keys=True)}")
|
||||||
if 200 <= response.status <= 299:
|
if 200 <= response.status <= 299:
|
||||||
return json_data
|
return json_data
|
||||||
if response.status == 404 and json_data['status'] == "No objects found.":
|
if response.status == 404 and json_data['status'] == "No objects found.":
|
||||||
raise AnsibleParserError(
|
raise AnsibleParserError(
|
||||||
"API returned no data -- Response: %s - %s"
|
f"API returned no data -- Response: {response.status} - {json_data['status']}")
|
||||||
% (response.status, json_data['status']))
|
|
||||||
if response.status == 401:
|
if response.status == 401:
|
||||||
raise AnsibleParserError(
|
raise AnsibleParserError(
|
||||||
"API was unable to complete query -- Response: %s - %s"
|
f"API was unable to complete query -- Response: {response.status} - {json_data['status']}")
|
||||||
% (response.status, json_data['status']))
|
|
||||||
if response.status == 500:
|
if response.status == 500:
|
||||||
raise AnsibleParserError(
|
raise AnsibleParserError(
|
||||||
"API Response - %s - %s"
|
f"API Response - {json_data['status']} - {json_data['errors']}")
|
||||||
% (json_data['status'], json_data['errors']))
|
|
||||||
raise AnsibleParserError(
|
raise AnsibleParserError(
|
||||||
"Unexpected data returned - %s - %s"
|
f"Unexpected data returned - {json_data['status']} - {json_data['errors']}")
|
||||||
% (json_data['status'], json_data['errors']))
|
|
||||||
|
|
||||||
def _query_hosts(self, hosts=None, attrs=None, joins=None, host_filter=None):
|
def _query_hosts(self, hosts=None, attrs=None, joins=None, host_filter=None):
|
||||||
query_hosts_url = "{0}/objects/hosts".format(self.icinga2_url)
|
query_hosts_url = f"{self.icinga2_url}/objects/hosts"
|
||||||
self.headers['X-HTTP-Method-Override'] = 'GET'
|
self.headers['X-HTTP-Method-Override'] = 'GET'
|
||||||
data_dict = dict()
|
data_dict = dict()
|
||||||
if hosts:
|
if hosts:
|
||||||
|
@ -302,7 +298,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||||
if self.templar.is_template(self.icinga2_password):
|
if self.templar.is_template(self.icinga2_password):
|
||||||
self.icinga2_password = self.templar.template(variable=self.icinga2_password, disable_lookups=False)
|
self.icinga2_password = self.templar.template(variable=self.icinga2_password, disable_lookups=False)
|
||||||
|
|
||||||
self.icinga2_url = self.icinga2_url.rstrip('/') + '/v1'
|
self.icinga2_url = f"{self.icinga2_url.rstrip('/')}/v1"
|
||||||
|
|
||||||
# Not currently enabled
|
# Not currently enabled
|
||||||
# self.cache_key = self.get_cache_key(path)
|
# self.cache_key = self.get_cache_key(path)
|
||||||
|
|
|
@ -161,7 +161,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
try:
|
try:
|
||||||
self.instances = self.client.linode.instances()
|
self.instances = self.client.linode.instances()
|
||||||
except LinodeApiError as exception:
|
except LinodeApiError as exception:
|
||||||
raise AnsibleError('Linode client raised: %s' % exception)
|
raise AnsibleError(f'Linode client raised: {exception}')
|
||||||
|
|
||||||
def _add_groups(self):
|
def _add_groups(self):
|
||||||
"""Add Linode instance groups to the dynamic inventory."""
|
"""Add Linode instance groups to the dynamic inventory."""
|
||||||
|
|
|
@ -211,7 +211,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
with open(path, 'r') as json_file:
|
with open(path, 'r') as json_file:
|
||||||
return json.load(json_file)
|
return json.load(json_file)
|
||||||
except (IOError, json.decoder.JSONDecodeError) as err:
|
except (IOError, json.decoder.JSONDecodeError) as err:
|
||||||
raise AnsibleParserError('Could not load the test data from {0}: {1}'.format(to_native(path), to_native(err)))
|
raise AnsibleParserError(f'Could not load the test data from {to_native(path)}: {to_native(err)}')
|
||||||
|
|
||||||
def save_json_data(self, path, file_name=None):
|
def save_json_data(self, path, file_name=None):
|
||||||
"""save data as json
|
"""save data as json
|
||||||
|
@ -241,7 +241,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
with open(os.path.abspath(os.path.join(cwd, *path)), 'w') as json_file:
|
with open(os.path.abspath(os.path.join(cwd, *path)), 'w') as json_file:
|
||||||
json.dump(self.data, json_file)
|
json.dump(self.data, json_file)
|
||||||
except IOError as err:
|
except IOError as err:
|
||||||
raise AnsibleParserError('Could not save data: {0}'.format(to_native(err)))
|
raise AnsibleParserError(f'Could not save data: {to_native(err)}')
|
||||||
|
|
||||||
def verify_file(self, path):
|
def verify_file(self, path):
|
||||||
"""Check the config
|
"""Check the config
|
||||||
|
@ -281,7 +281,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
if not isinstance(url, str):
|
if not isinstance(url, str):
|
||||||
return False
|
return False
|
||||||
if not url.startswith(('unix:', 'https:')):
|
if not url.startswith(('unix:', 'https:')):
|
||||||
raise AnsibleError('URL is malformed: {0}'.format(to_native(url)))
|
raise AnsibleError(f'URL is malformed: {to_native(url)}')
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _connect_to_socket(self):
|
def _connect_to_socket(self):
|
||||||
|
@ -306,7 +306,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
return socket_connection
|
return socket_connection
|
||||||
except LXDClientException as err:
|
except LXDClientException as err:
|
||||||
error_storage[url] = err
|
error_storage[url] = err
|
||||||
raise AnsibleError('No connection to the socket: {0}'.format(to_native(error_storage)))
|
raise AnsibleError(f'No connection to the socket: {to_native(error_storage)}')
|
||||||
|
|
||||||
def _get_networks(self):
|
def _get_networks(self):
|
||||||
"""Get Networknames
|
"""Get Networknames
|
||||||
|
@ -355,7 +355,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
# }
|
# }
|
||||||
url = '/1.0/instances'
|
url = '/1.0/instances'
|
||||||
if self.project:
|
if self.project:
|
||||||
url = url + '?{0}'.format(urlencode(dict(project=self.project)))
|
url = f"{url}?{urlencode(dict(project=self.project))}"
|
||||||
|
|
||||||
instances = self.socket.do('GET', url)
|
instances = self.socket.do('GET', url)
|
||||||
|
|
||||||
|
@ -383,10 +383,10 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
config = {}
|
config = {}
|
||||||
if isinstance(branch, (tuple, list)):
|
if isinstance(branch, (tuple, list)):
|
||||||
config[name] = {branch[1]: self.socket.do(
|
config[name] = {branch[1]: self.socket.do(
|
||||||
'GET', '/1.0/{0}/{1}/{2}?{3}'.format(to_native(branch[0]), to_native(name), to_native(branch[1]), urlencode(dict(project=self.project))))}
|
'GET', f'/1.0/{to_native(branch[0])}/{to_native(name)}/{to_native(branch[1])}?{urlencode(dict(project=self.project))}')}
|
||||||
else:
|
else:
|
||||||
config[name] = {branch: self.socket.do(
|
config[name] = {branch: self.socket.do(
|
||||||
'GET', '/1.0/{0}/{1}?{2}'.format(to_native(branch), to_native(name), urlencode(dict(project=self.project))))}
|
'GET', f'/1.0/{to_native(branch)}/{to_native(name)}?{urlencode(dict(project=self.project))}')}
|
||||||
return config
|
return config
|
||||||
|
|
||||||
def get_instance_data(self, names):
|
def get_instance_data(self, names):
|
||||||
|
@ -449,7 +449,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
None
|
None
|
||||||
Returns:
|
Returns:
|
||||||
dict(network_configuration): network config"""
|
dict(network_configuration): network config"""
|
||||||
instance_network_interfaces = self._get_data_entry('instances/{0}/state/metadata/network'.format(instance_name))
|
instance_network_interfaces = self._get_data_entry(f'instances/{instance_name}/state/metadata/network')
|
||||||
network_configuration = None
|
network_configuration = None
|
||||||
if instance_network_interfaces:
|
if instance_network_interfaces:
|
||||||
network_configuration = {}
|
network_configuration = {}
|
||||||
|
@ -462,7 +462,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
address_set['family'] = address.get('family')
|
address_set['family'] = address.get('family')
|
||||||
address_set['address'] = address.get('address')
|
address_set['address'] = address.get('address')
|
||||||
address_set['netmask'] = address.get('netmask')
|
address_set['netmask'] = address.get('netmask')
|
||||||
address_set['combined'] = address.get('address') + '/' + address.get('netmask')
|
address_set['combined'] = f"{address.get('address')}/{address.get('netmask')}"
|
||||||
network_configuration[interface_name].append(address_set)
|
network_configuration[interface_name].append(address_set)
|
||||||
return network_configuration
|
return network_configuration
|
||||||
|
|
||||||
|
@ -479,7 +479,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
None
|
None
|
||||||
Returns:
|
Returns:
|
||||||
str(prefered_interface): None or interface name"""
|
str(prefered_interface): None or interface name"""
|
||||||
instance_network_interfaces = self._get_data_entry('inventory/{0}/network_interfaces'.format(instance_name))
|
instance_network_interfaces = self._get_data_entry(f'inventory/{instance_name}/network_interfaces')
|
||||||
prefered_interface = None # init
|
prefered_interface = None # init
|
||||||
if instance_network_interfaces: # instance have network interfaces
|
if instance_network_interfaces: # instance have network interfaces
|
||||||
# generator if interfaces which start with the desired pattern
|
# generator if interfaces which start with the desired pattern
|
||||||
|
@ -516,7 +516,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
# "network":"lxdbr0",
|
# "network":"lxdbr0",
|
||||||
# "type":"nic"},
|
# "type":"nic"},
|
||||||
vlan_ids = {}
|
vlan_ids = {}
|
||||||
devices = self._get_data_entry('instances/{0}/instances/metadata/expanded_devices'.format(to_native(instance_name)))
|
devices = self._get_data_entry(f'instances/{to_native(instance_name)}/instances/metadata/expanded_devices')
|
||||||
for device in devices:
|
for device in devices:
|
||||||
if 'network' in devices[device]:
|
if 'network' in devices[device]:
|
||||||
if devices[device]['network'] in network_vlans:
|
if devices[device]['network'] in network_vlans:
|
||||||
|
@ -579,7 +579,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
else:
|
else:
|
||||||
path[instance_name][key] = value
|
path[instance_name][key] = value
|
||||||
except KeyError as err:
|
except KeyError as err:
|
||||||
raise AnsibleParserError("Unable to store Information: {0}".format(to_native(err)))
|
raise AnsibleParserError(f"Unable to store Information: {to_native(err)}")
|
||||||
|
|
||||||
def extract_information_from_instance_configs(self):
|
def extract_information_from_instance_configs(self):
|
||||||
"""Process configuration information
|
"""Process configuration information
|
||||||
|
@ -600,24 +600,24 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
|
|
||||||
for instance_name in self.data['instances']:
|
for instance_name in self.data['instances']:
|
||||||
self._set_data_entry(instance_name, 'os', self._get_data_entry(
|
self._set_data_entry(instance_name, 'os', self._get_data_entry(
|
||||||
'instances/{0}/instances/metadata/config/image.os'.format(instance_name)))
|
f'instances/{instance_name}/instances/metadata/config/image.os'))
|
||||||
self._set_data_entry(instance_name, 'release', self._get_data_entry(
|
self._set_data_entry(instance_name, 'release', self._get_data_entry(
|
||||||
'instances/{0}/instances/metadata/config/image.release'.format(instance_name)))
|
f'instances/{instance_name}/instances/metadata/config/image.release'))
|
||||||
self._set_data_entry(instance_name, 'version', self._get_data_entry(
|
self._set_data_entry(instance_name, 'version', self._get_data_entry(
|
||||||
'instances/{0}/instances/metadata/config/image.version'.format(instance_name)))
|
f'instances/{instance_name}/instances/metadata/config/image.version'))
|
||||||
self._set_data_entry(instance_name, 'profile', self._get_data_entry(
|
self._set_data_entry(instance_name, 'profile', self._get_data_entry(
|
||||||
'instances/{0}/instances/metadata/profiles'.format(instance_name)))
|
f'instances/{instance_name}/instances/metadata/profiles'))
|
||||||
self._set_data_entry(instance_name, 'location', self._get_data_entry(
|
self._set_data_entry(instance_name, 'location', self._get_data_entry(
|
||||||
'instances/{0}/instances/metadata/location'.format(instance_name)))
|
f'instances/{instance_name}/instances/metadata/location'))
|
||||||
self._set_data_entry(instance_name, 'state', self._get_data_entry(
|
self._set_data_entry(instance_name, 'state', self._get_data_entry(
|
||||||
'instances/{0}/instances/metadata/config/volatile.last_state.power'.format(instance_name)))
|
f'instances/{instance_name}/instances/metadata/config/volatile.last_state.power'))
|
||||||
self._set_data_entry(instance_name, 'type', self._get_data_entry(
|
self._set_data_entry(instance_name, 'type', self._get_data_entry(
|
||||||
'instances/{0}/instances/metadata/type'.format(instance_name)))
|
f'instances/{instance_name}/instances/metadata/type'))
|
||||||
self._set_data_entry(instance_name, 'network_interfaces', self.extract_network_information_from_instance_config(instance_name))
|
self._set_data_entry(instance_name, 'network_interfaces', self.extract_network_information_from_instance_config(instance_name))
|
||||||
self._set_data_entry(instance_name, 'preferred_interface', self.get_prefered_instance_network_interface(instance_name))
|
self._set_data_entry(instance_name, 'preferred_interface', self.get_prefered_instance_network_interface(instance_name))
|
||||||
self._set_data_entry(instance_name, 'vlan_ids', self.get_instance_vlans(instance_name))
|
self._set_data_entry(instance_name, 'vlan_ids', self.get_instance_vlans(instance_name))
|
||||||
self._set_data_entry(instance_name, 'project', self._get_data_entry(
|
self._set_data_entry(instance_name, 'project', self._get_data_entry(
|
||||||
'instances/{0}/instances/metadata/project'.format(instance_name)))
|
f'instances/{instance_name}/instances/metadata/project'))
|
||||||
|
|
||||||
def build_inventory_network(self, instance_name):
|
def build_inventory_network(self, instance_name):
|
||||||
"""Add the network interfaces of the instance to the inventory
|
"""Add the network interfaces of the instance to the inventory
|
||||||
|
@ -651,18 +651,18 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
None
|
None
|
||||||
Returns:
|
Returns:
|
||||||
dict(interface_name: ip)"""
|
dict(interface_name: ip)"""
|
||||||
prefered_interface = self._get_data_entry('inventory/{0}/preferred_interface'.format(instance_name)) # name or None
|
prefered_interface = self._get_data_entry(f'inventory/{instance_name}/preferred_interface') # name or None
|
||||||
prefered_instance_network_family = self.prefered_instance_network_family
|
prefered_instance_network_family = self.prefered_instance_network_family
|
||||||
|
|
||||||
ip_address = ''
|
ip_address = ''
|
||||||
if prefered_interface:
|
if prefered_interface:
|
||||||
interface = self._get_data_entry('inventory/{0}/network_interfaces/{1}'.format(instance_name, prefered_interface))
|
interface = self._get_data_entry(f'inventory/{instance_name}/network_interfaces/{prefered_interface}')
|
||||||
for config in interface:
|
for config in interface:
|
||||||
if config['family'] == prefered_instance_network_family:
|
if config['family'] == prefered_instance_network_family:
|
||||||
ip_address = config['address']
|
ip_address = config['address']
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
interfaces = self._get_data_entry('inventory/{0}/network_interfaces'.format(instance_name))
|
interfaces = self._get_data_entry(f'inventory/{instance_name}/network_interfaces')
|
||||||
for interface in interfaces.values():
|
for interface in interfaces.values():
|
||||||
for config in interface:
|
for config in interface:
|
||||||
if config['family'] == prefered_instance_network_family:
|
if config['family'] == prefered_instance_network_family:
|
||||||
|
@ -670,7 +670,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
break
|
break
|
||||||
return ip_address
|
return ip_address
|
||||||
|
|
||||||
if self._get_data_entry('inventory/{0}/network_interfaces'.format(instance_name)): # instance have network interfaces
|
if self._get_data_entry(f'inventory/{instance_name}/network_interfaces'): # instance have network interfaces
|
||||||
self.inventory.set_variable(instance_name, 'ansible_connection', 'ssh')
|
self.inventory.set_variable(instance_name, 'ansible_connection', 'ssh')
|
||||||
self.inventory.set_variable(instance_name, 'ansible_host', make_unsafe(interface_selection(instance_name)))
|
self.inventory.set_variable(instance_name, 'ansible_host', make_unsafe(interface_selection(instance_name)))
|
||||||
else:
|
else:
|
||||||
|
@ -691,7 +691,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
Returns:
|
Returns:
|
||||||
None"""
|
None"""
|
||||||
for instance_name in self.data['inventory']:
|
for instance_name in self.data['inventory']:
|
||||||
instance_state = str(self._get_data_entry('inventory/{0}/state'.format(instance_name)) or "STOPPED").lower()
|
instance_state = str(self._get_data_entry(f'inventory/{instance_name}/state') or "STOPPED").lower()
|
||||||
|
|
||||||
# Only consider instances that match the "state" filter, if self.state is not None
|
# Only consider instances that match the "state" filter, if self.state is not None
|
||||||
if self.filter:
|
if self.filter:
|
||||||
|
@ -703,34 +703,34 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
# add network information
|
# add network information
|
||||||
self.build_inventory_network(instance_name)
|
self.build_inventory_network(instance_name)
|
||||||
# add os
|
# add os
|
||||||
v = self._get_data_entry('inventory/{0}/os'.format(instance_name))
|
v = self._get_data_entry(f'inventory/{instance_name}/os')
|
||||||
if v:
|
if v:
|
||||||
self.inventory.set_variable(instance_name, 'ansible_lxd_os', make_unsafe(v.lower()))
|
self.inventory.set_variable(instance_name, 'ansible_lxd_os', make_unsafe(v.lower()))
|
||||||
# add release
|
# add release
|
||||||
v = self._get_data_entry('inventory/{0}/release'.format(instance_name))
|
v = self._get_data_entry(f'inventory/{instance_name}/release')
|
||||||
if v:
|
if v:
|
||||||
self.inventory.set_variable(
|
self.inventory.set_variable(
|
||||||
instance_name, 'ansible_lxd_release', make_unsafe(v.lower()))
|
instance_name, 'ansible_lxd_release', make_unsafe(v.lower()))
|
||||||
# add profile
|
# add profile
|
||||||
self.inventory.set_variable(
|
self.inventory.set_variable(
|
||||||
instance_name, 'ansible_lxd_profile', make_unsafe(self._get_data_entry('inventory/{0}/profile'.format(instance_name))))
|
instance_name, 'ansible_lxd_profile', make_unsafe(self._get_data_entry(f'inventory/{instance_name}/profile')))
|
||||||
# add state
|
# add state
|
||||||
self.inventory.set_variable(
|
self.inventory.set_variable(
|
||||||
instance_name, 'ansible_lxd_state', make_unsafe(instance_state))
|
instance_name, 'ansible_lxd_state', make_unsafe(instance_state))
|
||||||
# add type
|
# add type
|
||||||
self.inventory.set_variable(
|
self.inventory.set_variable(
|
||||||
instance_name, 'ansible_lxd_type', make_unsafe(self._get_data_entry('inventory/{0}/type'.format(instance_name))))
|
instance_name, 'ansible_lxd_type', make_unsafe(self._get_data_entry(f'inventory/{instance_name}/type')))
|
||||||
# add location information
|
# add location information
|
||||||
if self._get_data_entry('inventory/{0}/location'.format(instance_name)) != "none": # wrong type by lxd 'none' != 'None'
|
if self._get_data_entry(f'inventory/{instance_name}/location') != "none": # wrong type by lxd 'none' != 'None'
|
||||||
self.inventory.set_variable(
|
self.inventory.set_variable(
|
||||||
instance_name, 'ansible_lxd_location', make_unsafe(self._get_data_entry('inventory/{0}/location'.format(instance_name))))
|
instance_name, 'ansible_lxd_location', make_unsafe(self._get_data_entry(f'inventory/{instance_name}/location')))
|
||||||
# add VLAN_ID information
|
# add VLAN_ID information
|
||||||
if self._get_data_entry('inventory/{0}/vlan_ids'.format(instance_name)):
|
if self._get_data_entry(f'inventory/{instance_name}/vlan_ids'):
|
||||||
self.inventory.set_variable(
|
self.inventory.set_variable(
|
||||||
instance_name, 'ansible_lxd_vlan_ids', make_unsafe(self._get_data_entry('inventory/{0}/vlan_ids'.format(instance_name))))
|
instance_name, 'ansible_lxd_vlan_ids', make_unsafe(self._get_data_entry(f'inventory/{instance_name}/vlan_ids')))
|
||||||
# add project
|
# add project
|
||||||
self.inventory.set_variable(
|
self.inventory.set_variable(
|
||||||
instance_name, 'ansible_lxd_project', make_unsafe(self._get_data_entry('inventory/{0}/project'.format(instance_name))))
|
instance_name, 'ansible_lxd_project', make_unsafe(self._get_data_entry(f'inventory/{instance_name}/project')))
|
||||||
|
|
||||||
def build_inventory_groups_location(self, group_name):
|
def build_inventory_groups_location(self, group_name):
|
||||||
"""create group by attribute: location
|
"""create group by attribute: location
|
||||||
|
@ -792,7 +792,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
network = ipaddress.ip_network(to_text(self.groupby[group_name].get('attribute')))
|
network = ipaddress.ip_network(to_text(self.groupby[group_name].get('attribute')))
|
||||||
except ValueError as err:
|
except ValueError as err:
|
||||||
raise AnsibleParserError(
|
raise AnsibleParserError(
|
||||||
'Error while parsing network range {0}: {1}'.format(self.groupby[group_name].get('attribute'), to_native(err)))
|
f"Error while parsing network range {self.groupby[group_name].get('attribute')}: {to_native(err)}")
|
||||||
|
|
||||||
for instance_name in self.inventory.hosts:
|
for instance_name in self.inventory.hosts:
|
||||||
if self.data['inventory'][instance_name].get('network_interfaces') is not None:
|
if self.data['inventory'][instance_name].get('network_interfaces') is not None:
|
||||||
|
@ -997,12 +997,12 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
elif self.groupby[group_name].get('type') == 'project':
|
elif self.groupby[group_name].get('type') == 'project':
|
||||||
self.build_inventory_groups_project(group_name)
|
self.build_inventory_groups_project(group_name)
|
||||||
else:
|
else:
|
||||||
raise AnsibleParserError('Unknown group type: {0}'.format(to_native(group_name)))
|
raise AnsibleParserError(f'Unknown group type: {to_native(group_name)}')
|
||||||
|
|
||||||
if self.groupby:
|
if self.groupby:
|
||||||
for group_name in self.groupby:
|
for group_name in self.groupby:
|
||||||
if not group_name.isalnum():
|
if not group_name.isalnum():
|
||||||
raise AnsibleParserError('Invalid character(s) in groupname: {0}'.format(to_native(group_name)))
|
raise AnsibleParserError(f'Invalid character(s) in groupname: {to_native(group_name)}')
|
||||||
group_type(make_unsafe(group_name))
|
group_type(make_unsafe(group_name))
|
||||||
|
|
||||||
def build_inventory(self):
|
def build_inventory(self):
|
||||||
|
@ -1039,7 +1039,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
None"""
|
None"""
|
||||||
iter_keys = list(self.data['instances'].keys())
|
iter_keys = list(self.data['instances'].keys())
|
||||||
for instance_name in iter_keys:
|
for instance_name in iter_keys:
|
||||||
if self._get_data_entry('instances/{0}/instances/metadata/type'.format(instance_name)) != self.type_filter:
|
if self._get_data_entry(f'instances/{instance_name}/instances/metadata/type') != self.type_filter:
|
||||||
del self.data['instances'][instance_name]
|
del self.data['instances'][instance_name]
|
||||||
|
|
||||||
def _populate(self):
|
def _populate(self):
|
||||||
|
@ -1120,6 +1120,6 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
self.url = self.get_option('url')
|
self.url = self.get_option('url')
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
raise AnsibleParserError(
|
raise AnsibleParserError(
|
||||||
'All correct options required: {0}'.format(to_native(err)))
|
f'All correct options required: {to_native(err)}')
|
||||||
# Call our internal helper to populate the dynamic inventory
|
# Call our internal helper to populate the dynamic inventory
|
||||||
self._populate()
|
self._populate()
|
||||||
|
|
|
@ -178,7 +178,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
try:
|
try:
|
||||||
self._nmap = get_bin_path('nmap')
|
self._nmap = get_bin_path('nmap')
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
raise AnsibleParserError('nmap inventory plugin requires the nmap cli tool to work: {0}'.format(to_native(e)))
|
raise AnsibleParserError(f'nmap inventory plugin requires the nmap cli tool to work: {to_native(e)}')
|
||||||
|
|
||||||
super(InventoryModule, self).parse(inventory, loader, path, cache=cache)
|
super(InventoryModule, self).parse(inventory, loader, path, cache=cache)
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
p = Popen(cmd, stdout=PIPE, stderr=PIPE)
|
p = Popen(cmd, stdout=PIPE, stderr=PIPE)
|
||||||
stdout, stderr = p.communicate()
|
stdout, stderr = p.communicate()
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
raise AnsibleParserError('Failed to run nmap, rc=%s: %s' % (p.returncode, to_native(stderr)))
|
raise AnsibleParserError(f'Failed to run nmap, rc={p.returncode}: {to_native(stderr)}')
|
||||||
|
|
||||||
# parse results
|
# parse results
|
||||||
host = None
|
host = None
|
||||||
|
@ -259,7 +259,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
try:
|
try:
|
||||||
t_stdout = to_text(stdout, errors='surrogate_or_strict')
|
t_stdout = to_text(stdout, errors='surrogate_or_strict')
|
||||||
except UnicodeError as e:
|
except UnicodeError as e:
|
||||||
raise AnsibleParserError('Invalid (non unicode) input returned: %s' % to_native(e))
|
raise AnsibleParserError(f'Invalid (non unicode) input returned: {to_native(e)}')
|
||||||
|
|
||||||
for line in t_stdout.splitlines():
|
for line in t_stdout.splitlines():
|
||||||
hits = self.find_host.match(line)
|
hits = self.find_host.match(line)
|
||||||
|
@ -300,7 +300,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
results[-1]['ports'] = ports
|
results[-1]['ports'] = ports
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise AnsibleParserError("failed to parse %s: %s " % (to_native(path), to_native(e)))
|
raise AnsibleParserError(f"failed to parse {to_native(path)}: {to_native(e)} ")
|
||||||
|
|
||||||
if cache_needs_update:
|
if cache_needs_update:
|
||||||
self._cache[cache_key] = results
|
self._cache[cache_key] = results
|
||||||
|
|
|
@ -138,7 +138,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
try:
|
try:
|
||||||
response = open_url(url, headers=self.headers)
|
response = open_url(url, headers=self.headers)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.display.warning("An error happened while fetching: %s" % url)
|
self.display.warning(f"An error happened while fetching: {url}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -245,8 +245,8 @@ class InventoryModule(BaseInventoryPlugin):
|
||||||
}
|
}
|
||||||
|
|
||||||
self.headers = {
|
self.headers = {
|
||||||
'Authorization': "Bearer %s" % token,
|
'Authorization': f"Bearer {token}",
|
||||||
'User-Agent': "ansible %s Python %s" % (ansible_version, python_version.split(' ', 1)[0]),
|
'User-Agent': f"ansible {ansible_version} Python {python_version.split(' ', 1)[0]}",
|
||||||
'Content-type': 'application/json'
|
'Content-type': 'application/json'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,9 +128,9 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||||
authstring = fp.read().rstrip()
|
authstring = fp.read().rstrip()
|
||||||
username, password = authstring.split(":")
|
username, password = authstring.split(":")
|
||||||
except (OSError, IOError):
|
except (OSError, IOError):
|
||||||
raise AnsibleError("Could not find or read ONE_AUTH file at '{e}'".format(e=authfile))
|
raise AnsibleError(f"Could not find or read ONE_AUTH file at '{authfile}'")
|
||||||
except Exception:
|
except Exception:
|
||||||
raise AnsibleError("Error occurs when reading ONE_AUTH file at '{e}'".format(e=authfile))
|
raise AnsibleError(f"Error occurs when reading ONE_AUTH file at '{authfile}'")
|
||||||
|
|
||||||
auth_params = namedtuple('auth', ('url', 'username', 'password'))
|
auth_params = namedtuple('auth', ('url', 'username', 'password'))
|
||||||
|
|
||||||
|
@ -166,13 +166,13 @@ class InventoryModule(BaseInventoryPlugin, Constructable):
|
||||||
if not (auth.username and auth.password):
|
if not (auth.username and auth.password):
|
||||||
raise AnsibleError('API Credentials missing. Check OpenNebula inventory file.')
|
raise AnsibleError('API Credentials missing. Check OpenNebula inventory file.')
|
||||||
else:
|
else:
|
||||||
one_client = pyone.OneServer(auth.url, session=auth.username + ':' + auth.password)
|
one_client = pyone.OneServer(auth.url, session=f"{auth.username}:{auth.password}")
|
||||||
|
|
||||||
# get hosts (VMs)
|
# get hosts (VMs)
|
||||||
try:
|
try:
|
||||||
vm_pool = one_client.vmpool.infoextended(-2, -1, -1, 3)
|
vm_pool = one_client.vmpool.infoextended(-2, -1, -1, 3)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise AnsibleError("Something happened during XML-RPC call: {e}".format(e=to_native(e)))
|
raise AnsibleError(f"Something happened during XML-RPC call: {to_native(e)}")
|
||||||
|
|
||||||
return vm_pool
|
return vm_pool
|
||||||
|
|
||||||
|
|
|
@ -284,12 +284,12 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
if self.proxmox_password:
|
if self.proxmox_password:
|
||||||
credentials = urlencode({'username': self.proxmox_user, 'password': self.proxmox_password})
|
credentials = urlencode({'username': self.proxmox_user, 'password': self.proxmox_password})
|
||||||
a = self._get_session()
|
a = self._get_session()
|
||||||
ret = a.post('%s/api2/json/access/ticket' % self.proxmox_url, data=credentials)
|
ret = a.post(f'{self.proxmox_url}/api2/json/access/ticket', data=credentials)
|
||||||
json = ret.json()
|
json = ret.json()
|
||||||
self.headers = {
|
self.headers = {
|
||||||
# only required for POST/PUT/DELETE methods, which we are not using currently
|
# only required for POST/PUT/DELETE methods, which we are not using currently
|
||||||
# 'CSRFPreventionToken': json['data']['CSRFPreventionToken'],
|
# 'CSRFPreventionToken': json['data']['CSRFPreventionToken'],
|
||||||
'Cookie': 'PVEAuthCookie={0}'.format(json['data']['ticket'])
|
'Cookie': f"PVEAuthCookie={json['data']['ticket']}"
|
||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
# Clean and format token components
|
# Clean and format token components
|
||||||
|
@ -341,23 +341,23 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
return make_unsafe(self._cache[self.cache_key][url])
|
return make_unsafe(self._cache[self.cache_key][url])
|
||||||
|
|
||||||
def _get_nodes(self):
|
def _get_nodes(self):
|
||||||
return self._get_json("%s/api2/json/nodes" % self.proxmox_url)
|
return self._get_json(f"{self.proxmox_url}/api2/json/nodes")
|
||||||
|
|
||||||
def _get_pools(self):
|
def _get_pools(self):
|
||||||
return self._get_json("%s/api2/json/pools" % self.proxmox_url)
|
return self._get_json(f"{self.proxmox_url}/api2/json/pools")
|
||||||
|
|
||||||
def _get_lxc_per_node(self, node):
|
def _get_lxc_per_node(self, node):
|
||||||
return self._get_json("%s/api2/json/nodes/%s/lxc" % (self.proxmox_url, node))
|
return self._get_json(f"{self.proxmox_url}/api2/json/nodes/{node}/lxc")
|
||||||
|
|
||||||
def _get_qemu_per_node(self, node):
|
def _get_qemu_per_node(self, node):
|
||||||
return self._get_json("%s/api2/json/nodes/%s/qemu" % (self.proxmox_url, node))
|
return self._get_json(f"{self.proxmox_url}/api2/json/nodes/{node}/qemu")
|
||||||
|
|
||||||
def _get_members_per_pool(self, pool):
|
def _get_members_per_pool(self, pool):
|
||||||
ret = self._get_json("%s/api2/json/pools/%s" % (self.proxmox_url, pool))
|
ret = self._get_json(f"{self.proxmox_url}/api2/json/pools/{pool}")
|
||||||
return ret['members']
|
return ret['members']
|
||||||
|
|
||||||
def _get_node_ip(self, node):
|
def _get_node_ip(self, node):
|
||||||
ret = self._get_json("%s/api2/json/nodes/%s/network" % (self.proxmox_url, node))
|
ret = self._get_json(f"{self.proxmox_url}/api2/json/nodes/{node}/network")
|
||||||
|
|
||||||
for iface in ret:
|
for iface in ret:
|
||||||
try:
|
try:
|
||||||
|
@ -371,7 +371,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
if status_key not in properties or not properties[status_key] == 'running':
|
if status_key not in properties or not properties[status_key] == 'running':
|
||||||
return
|
return
|
||||||
|
|
||||||
ret = self._get_json("%s/api2/json/nodes/%s/lxc/%s/interfaces" % (self.proxmox_url, node, vmid), ignore_errors=[501])
|
ret = self._get_json(f"{self.proxmox_url}/api2/json/nodes/{node}/lxc/{vmid}/interfaces", ignore_errors=[501])
|
||||||
if not ret:
|
if not ret:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -398,9 +398,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ifaces = self._get_json(
|
ifaces = self._get_json(
|
||||||
"%s/api2/json/nodes/%s/%s/%s/agent/network-get-interfaces" % (
|
f"{self.proxmox_url}/api2/json/nodes/{node}/{vmtype}/{vmid}/agent/network-get-interfaces"
|
||||||
self.proxmox_url, node, vmtype, vmid
|
|
||||||
)
|
|
||||||
)['result']
|
)['result']
|
||||||
|
|
||||||
if "error" in ifaces:
|
if "error" in ifaces:
|
||||||
|
@ -418,7 +416,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
result.append({
|
result.append({
|
||||||
'name': iface['name'],
|
'name': iface['name'],
|
||||||
'mac-address': iface['hardware-address'] if 'hardware-address' in iface else '',
|
'mac-address': iface['hardware-address'] if 'hardware-address' in iface else '',
|
||||||
'ip-addresses': ["%s/%s" % (ip['ip-address'], ip['prefix']) for ip in iface['ip-addresses']] if 'ip-addresses' in iface else []
|
'ip-addresses': [f"{ip['ip-address']}/{ip['prefix']}" for ip in iface['ip-addresses']] if 'ip-addresses' in iface else []
|
||||||
})
|
})
|
||||||
except requests.HTTPError:
|
except requests.HTTPError:
|
||||||
pass
|
pass
|
||||||
|
@ -426,7 +424,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _get_vm_config(self, properties, node, vmid, vmtype, name):
|
def _get_vm_config(self, properties, node, vmid, vmtype, name):
|
||||||
ret = self._get_json("%s/api2/json/nodes/%s/%s/%s/config" % (self.proxmox_url, node, vmtype, vmid))
|
ret = self._get_json(f"{self.proxmox_url}/api2/json/nodes/{node}/{vmtype}/{vmid}/config")
|
||||||
|
|
||||||
properties[self._fact('node')] = node
|
properties[self._fact('node')] = node
|
||||||
properties[self._fact('vmid')] = vmid
|
properties[self._fact('vmid')] = vmid
|
||||||
|
@ -442,13 +440,13 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
try:
|
try:
|
||||||
# fixup disk images as they have no key
|
# fixup disk images as they have no key
|
||||||
if config == 'rootfs' or config.startswith(('virtio', 'sata', 'ide', 'scsi')):
|
if config == 'rootfs' or config.startswith(('virtio', 'sata', 'ide', 'scsi')):
|
||||||
value = ('disk_image=' + value)
|
value = f"disk_image={value}"
|
||||||
|
|
||||||
# Additional field containing parsed tags as list
|
# Additional field containing parsed tags as list
|
||||||
if config == 'tags':
|
if config == 'tags':
|
||||||
stripped_value = value.strip()
|
stripped_value = value.strip()
|
||||||
if stripped_value:
|
if stripped_value:
|
||||||
parsed_key = key + "_parsed"
|
parsed_key = f"{key}_parsed"
|
||||||
properties[parsed_key] = [tag.strip() for tag in stripped_value.replace(',', ';').split(";")]
|
properties[parsed_key] = [tag.strip() for tag in stripped_value.replace(',', ';').split(";")]
|
||||||
|
|
||||||
# The first field in the agent string tells you whether the agent is enabled
|
# The first field in the agent string tells you whether the agent is enabled
|
||||||
|
@ -464,7 +462,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
if agent_enabled:
|
if agent_enabled:
|
||||||
agent_iface_value = self._get_agent_network_interfaces(node, vmid, vmtype)
|
agent_iface_value = self._get_agent_network_interfaces(node, vmid, vmtype)
|
||||||
if agent_iface_value:
|
if agent_iface_value:
|
||||||
agent_iface_key = self.to_safe('%s%s' % (key, "_interfaces"))
|
agent_iface_key = self.to_safe(f'{key}_interfaces')
|
||||||
properties[agent_iface_key] = agent_iface_value
|
properties[agent_iface_key] = agent_iface_value
|
||||||
|
|
||||||
if config == 'lxc':
|
if config == 'lxc':
|
||||||
|
@ -489,13 +487,13 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _get_vm_status(self, properties, node, vmid, vmtype, name):
|
def _get_vm_status(self, properties, node, vmid, vmtype, name):
|
||||||
ret = self._get_json("%s/api2/json/nodes/%s/%s/%s/status/current" % (self.proxmox_url, node, vmtype, vmid))
|
ret = self._get_json(f"{self.proxmox_url}/api2/json/nodes/{node}/{vmtype}/{vmid}/status/current")
|
||||||
properties[self._fact('status')] = ret['status']
|
properties[self._fact('status')] = ret['status']
|
||||||
if vmtype == 'qemu':
|
if vmtype == 'qemu':
|
||||||
properties[self._fact('qmpstatus')] = ret['qmpstatus']
|
properties[self._fact('qmpstatus')] = ret['qmpstatus']
|
||||||
|
|
||||||
def _get_vm_snapshots(self, properties, node, vmid, vmtype, name):
|
def _get_vm_snapshots(self, properties, node, vmid, vmtype, name):
|
||||||
ret = self._get_json("%s/api2/json/nodes/%s/%s/%s/snapshot" % (self.proxmox_url, node, vmtype, vmid))
|
ret = self._get_json(f"{self.proxmox_url}/api2/json/nodes/{node}/{vmtype}/{vmid}/snapshot")
|
||||||
snapshots = [snapshot['name'] for snapshot in ret if snapshot['name'] != 'current']
|
snapshots = [snapshot['name'] for snapshot in ret if snapshot['name'] != 'current']
|
||||||
properties[self._fact('snapshots')] = snapshots
|
properties[self._fact('snapshots')] = snapshots
|
||||||
|
|
||||||
|
@ -509,11 +507,11 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
|
|
||||||
def _fact(self, name):
|
def _fact(self, name):
|
||||||
'''Generate a fact's full name from the common prefix and a name.'''
|
'''Generate a fact's full name from the common prefix and a name.'''
|
||||||
return self.to_safe('%s%s' % (self.facts_prefix, name.lower()))
|
return self.to_safe(f'{self.facts_prefix}{name.lower()}')
|
||||||
|
|
||||||
def _group(self, name):
|
def _group(self, name):
|
||||||
'''Generate a group's full name from the common prefix and a name.'''
|
'''Generate a group's full name from the common prefix and a name.'''
|
||||||
return self.to_safe('%s%s' % (self.group_prefix, name.lower()))
|
return self.to_safe(f'{self.group_prefix}{name.lower()}')
|
||||||
|
|
||||||
def _can_add_host(self, name, properties):
|
def _can_add_host(self, name, properties):
|
||||||
'''Ensure that a host satisfies all defined hosts filters. If strict mode is
|
'''Ensure that a host satisfies all defined hosts filters. If strict mode is
|
||||||
|
@ -525,7 +523,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
if not self._compose(host_filter, properties):
|
if not self._compose(host_filter, properties):
|
||||||
return False
|
return False
|
||||||
except Exception as e: # pylint: disable=broad-except
|
except Exception as e: # pylint: disable=broad-except
|
||||||
message = "Could not evaluate host filter %s for host %s - %s" % (host_filter, name, to_native(e))
|
message = f"Could not evaluate host filter {host_filter} for host {name} - {to_native(e)}"
|
||||||
if self.strict:
|
if self.strict:
|
||||||
raise AnsibleError(message)
|
raise AnsibleError(message)
|
||||||
display.warning(message)
|
display.warning(message)
|
||||||
|
@ -566,8 +564,8 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
|
|
||||||
# add the host to the inventory
|
# add the host to the inventory
|
||||||
self._add_host(name, properties)
|
self._add_host(name, properties)
|
||||||
node_type_group = self._group('%s_%s' % (node, ittype))
|
node_type_group = self._group(f'{node}_{ittype}')
|
||||||
self.inventory.add_child(self._group('all_' + ittype), name)
|
self.inventory.add_child(self._group(f"all_{ittype}"), name)
|
||||||
self.inventory.add_child(node_type_group, name)
|
self.inventory.add_child(node_type_group, name)
|
||||||
|
|
||||||
item_status = item['status']
|
item_status = item['status']
|
||||||
|
@ -575,7 +573,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
if want_facts and ittype == 'qemu' and self.get_option('qemu_extended_statuses'):
|
if want_facts and ittype == 'qemu' and self.get_option('qemu_extended_statuses'):
|
||||||
# get more details about the status of the qemu VM
|
# get more details about the status of the qemu VM
|
||||||
item_status = properties.get(self._fact('qmpstatus'), item_status)
|
item_status = properties.get(self._fact('qmpstatus'), item_status)
|
||||||
self.inventory.add_child(self._group('all_%s' % (item_status, )), name)
|
self.inventory.add_child(self._group(f'all_{item_status}'), name)
|
||||||
|
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
@ -586,7 +584,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
poolid = pool.get('poolid')
|
poolid = pool.get('poolid')
|
||||||
if not poolid:
|
if not poolid:
|
||||||
continue
|
continue
|
||||||
pool_group = self._group('pool_' + poolid)
|
pool_group = self._group(f"pool_{poolid}")
|
||||||
self.inventory.add_group(pool_group)
|
self.inventory.add_group(pool_group)
|
||||||
|
|
||||||
for member in self._get_members_per_pool(poolid):
|
for member in self._get_members_per_pool(poolid):
|
||||||
|
@ -603,7 +601,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
default_groups.extend(['prelaunch', 'paused'])
|
default_groups.extend(['prelaunch', 'paused'])
|
||||||
|
|
||||||
for group in default_groups:
|
for group in default_groups:
|
||||||
self.inventory.add_group(self._group('all_%s' % (group)))
|
self.inventory.add_group(self._group(f'all_{group}'))
|
||||||
nodes_group = self._group('nodes')
|
nodes_group = self._group('nodes')
|
||||||
if not self.exclude_nodes:
|
if not self.exclude_nodes:
|
||||||
self.inventory.add_group(nodes_group)
|
self.inventory.add_group(nodes_group)
|
||||||
|
@ -636,7 +634,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
|
|
||||||
# add LXC/Qemu groups for the node
|
# add LXC/Qemu groups for the node
|
||||||
for ittype in ('lxc', 'qemu'):
|
for ittype in ('lxc', 'qemu'):
|
||||||
node_type_group = self._group('%s_%s' % (node['node'], ittype))
|
node_type_group = self._group(f"{node['node']}_{ittype}")
|
||||||
self.inventory.add_group(node_type_group)
|
self.inventory.add_group(node_type_group)
|
||||||
|
|
||||||
# get LXC containers and Qemu VMs for this node
|
# get LXC containers and Qemu VMs for this node
|
||||||
|
@ -665,7 +663,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
v = self.get_option(o)
|
v = self.get_option(o)
|
||||||
if self.templar.is_template(v):
|
if self.templar.is_template(v):
|
||||||
v = self.templar.template(v, disable_lookups=False)
|
v = self.templar.template(v, disable_lookups=False)
|
||||||
setattr(self, 'proxmox_%s' % o, v)
|
setattr(self, f'proxmox_{o}', v)
|
||||||
|
|
||||||
# some more cleanup and validation
|
# some more cleanup and validation
|
||||||
self.proxmox_url = self.proxmox_url.rstrip('/')
|
self.proxmox_url = self.proxmox_url.rstrip('/')
|
||||||
|
|
|
@ -140,7 +140,7 @@ def _fetch_information(token, url):
|
||||||
headers={'X-Auth-Token': token,
|
headers={'X-Auth-Token': token,
|
||||||
'Content-type': 'application/json'})
|
'Content-type': 'application/json'})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise AnsibleError("Error while fetching %s: %s" % (url, to_native(e)))
|
raise AnsibleError(f"Error while fetching {url}: {to_native(e)}")
|
||||||
try:
|
try:
|
||||||
raw_json = json.loads(to_text(response.read()))
|
raw_json = json.loads(to_text(response.read()))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
@ -161,7 +161,7 @@ def _fetch_information(token, url):
|
||||||
|
|
||||||
|
|
||||||
def _build_server_url(api_endpoint):
|
def _build_server_url(api_endpoint):
|
||||||
return "/".join([api_endpoint, "servers"])
|
return f"{api_endpoint}/servers"
|
||||||
|
|
||||||
|
|
||||||
def extract_public_ipv4(server_info):
|
def extract_public_ipv4(server_info):
|
||||||
|
|
|
@ -139,7 +139,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
}
|
}
|
||||||
resp = open_url(
|
resp = open_url(
|
||||||
self.api_host + '/identity/v1/oauth2/token',
|
f"{self.api_host}/identity/v1/oauth2/token",
|
||||||
headers=headers,
|
headers=headers,
|
||||||
data=payload,
|
data=payload,
|
||||||
method="POST"
|
method="POST"
|
||||||
|
@ -155,16 +155,16 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
self._authenticate()
|
self._authenticate()
|
||||||
for stack_slug in self.stack_slugs:
|
for stack_slug in self.stack_slugs:
|
||||||
try:
|
try:
|
||||||
workloads = self._stackpath_query_get_list(self.api_host + '/workload/v1/stacks/' + stack_slug + '/workloads')
|
workloads = self._stackpath_query_get_list(f"{self.api_host}/workload/v1/stacks/{stack_slug}/workloads")
|
||||||
except Exception:
|
except Exception:
|
||||||
raise AnsibleError("Failed to get workloads from the StackPath API: %s" % traceback.format_exc())
|
raise AnsibleError(f"Failed to get workloads from the StackPath API: {traceback.format_exc()}")
|
||||||
for workload in workloads:
|
for workload in workloads:
|
||||||
try:
|
try:
|
||||||
workload_instances = self._stackpath_query_get_list(
|
workload_instances = self._stackpath_query_get_list(
|
||||||
self.api_host + '/workload/v1/stacks/' + stack_slug + '/workloads/' + workload["id"] + '/instances'
|
f"{self.api_host}/workload/v1/stacks/{stack_slug}/workloads/{workload['id']}/instances"
|
||||||
)
|
)
|
||||||
except Exception:
|
except Exception:
|
||||||
raise AnsibleError("Failed to get workload instances from the StackPath API: %s" % traceback.format_exc())
|
raise AnsibleError(f"Failed to get workload instances from the StackPath API: {traceback.format_exc()}")
|
||||||
for instance in workload_instances:
|
for instance in workload_instances:
|
||||||
if instance["phase"] == "RUNNING":
|
if instance["phase"] == "RUNNING":
|
||||||
instance["stackSlug"] = stack_slug
|
instance["stackSlug"] = stack_slug
|
||||||
|
@ -184,7 +184,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
def _populate(self, instances):
|
def _populate(self, instances):
|
||||||
for instance in instances:
|
for instance in instances:
|
||||||
for group_key in self.group_keys:
|
for group_key in self.group_keys:
|
||||||
group = group_key + "_" + instance[group_key]
|
group = f"{group_key}_{instance[group_key]}"
|
||||||
group = group.lower().replace(" ", "_").replace("-", "_")
|
group = group.lower().replace(" ", "_").replace("-", "_")
|
||||||
self.inventory.add_group(group)
|
self.inventory.add_group(group)
|
||||||
self.inventory.add_host(instance[self.hostname_key],
|
self.inventory.add_host(instance[self.hostname_key],
|
||||||
|
@ -194,14 +194,14 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
self._authenticate()
|
self._authenticate()
|
||||||
headers = {
|
headers = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"Authorization": "Bearer " + self.auth_token,
|
"Authorization": f"Bearer {self.auth_token}",
|
||||||
}
|
}
|
||||||
next_page = True
|
next_page = True
|
||||||
result = []
|
result = []
|
||||||
cursor = '-1'
|
cursor = '-1'
|
||||||
while next_page:
|
while next_page:
|
||||||
resp = open_url(
|
resp = open_url(
|
||||||
url + '?page_request.first=10&page_request.after=%s' % cursor,
|
f"{url}?page_request.first=10&page_request.after={cursor}",
|
||||||
headers=headers,
|
headers=headers,
|
||||||
method="GET"
|
method="GET"
|
||||||
)
|
)
|
||||||
|
@ -251,10 +251,10 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
self.stack_slugs = self.get_option('stack_slugs')
|
self.stack_slugs = self.get_option('stack_slugs')
|
||||||
if not self.stack_slugs:
|
if not self.stack_slugs:
|
||||||
try:
|
try:
|
||||||
stacks = self._stackpath_query_get_list(self.api_host + '/stack/v1/stacks')
|
stacks = self._stackpath_query_get_list(f"{self.api_host}/stack/v1/stacks")
|
||||||
self._get_stack_slugs(stacks)
|
self._get_stack_slugs(stacks)
|
||||||
except Exception:
|
except Exception:
|
||||||
raise AnsibleError("Failed to get stack IDs from the Stackpath API: %s" % traceback.format_exc())
|
raise AnsibleError(f"Failed to get stack IDs from the Stackpath API: {traceback.format_exc()}")
|
||||||
|
|
||||||
cache_key = self.get_cache_key(path)
|
cache_key = self.get_cache_key(path)
|
||||||
# false when refresh_cache or --flush-cache is used
|
# false when refresh_cache or --flush-cache is used
|
||||||
|
@ -283,4 +283,4 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
if cache_needs_update or (not cache and self.get_option('cache')):
|
if cache_needs_update or (not cache and self.get_option('cache')):
|
||||||
self._cache[cache_key] = results
|
self._cache[cache_key] = results
|
||||||
except Exception:
|
except Exception:
|
||||||
raise AnsibleError("Failed to populate data: %s" % traceback.format_exc())
|
raise AnsibleError(f"Failed to populate data: {traceback.format_exc()}")
|
||||||
|
|
|
@ -203,7 +203,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# found vars, accumulate in hostvars for clean inventory set
|
# found vars, accumulate in hostvars for clean inventory set
|
||||||
pref_k = make_unsafe('vbox_' + k.strip().replace(' ', '_'))
|
pref_k = make_unsafe(f"vbox_{k.strip().replace(' ', '_')}")
|
||||||
leading_spaces = len(k) - len(k.lstrip(' '))
|
leading_spaces = len(k) - len(k.lstrip(' '))
|
||||||
if 0 < leading_spaces <= 2:
|
if 0 < leading_spaces <= 2:
|
||||||
if prevkey not in hostvars[current_host] or not isinstance(hostvars[current_host][prevkey], dict):
|
if prevkey not in hostvars[current_host] or not isinstance(hostvars[current_host][prevkey], dict):
|
||||||
|
|
|
@ -138,7 +138,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
|
|
||||||
sslopt = None if validate_certs else {'cert_reqs': ssl.CERT_NONE}
|
sslopt = None if validate_certs else {'cert_reqs': ssl.CERT_NONE}
|
||||||
self.conn = create_connection(
|
self.conn = create_connection(
|
||||||
'{0}://{1}/api/'.format(proto, xoa_api_host), sslopt=sslopt)
|
f'{proto}://{xoa_api_host}/api/', sslopt=sslopt)
|
||||||
|
|
||||||
CALL_TIMEOUT = 100
|
CALL_TIMEOUT = 100
|
||||||
"""Number of 1/10ths of a second to wait before method call times out."""
|
"""Number of 1/10ths of a second to wait before method call times out."""
|
||||||
|
@ -162,8 +162,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
sleep(0.1)
|
sleep(0.1)
|
||||||
waited += 1
|
waited += 1
|
||||||
|
|
||||||
raise AnsibleError(
|
raise AnsibleError(f'Method call {method} timed out after {self.CALL_TIMEOUT / 10} seconds.')
|
||||||
'Method call {method} timed out after {timeout} seconds.'.format(method=method, timeout=self.CALL_TIMEOUT / 10))
|
|
||||||
|
|
||||||
def login(self, user, password):
|
def login(self, user, password):
|
||||||
result = self.call('session.signIn', {
|
result = self.call('session.signIn', {
|
||||||
|
@ -171,15 +170,13 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
})
|
})
|
||||||
|
|
||||||
if 'error' in result:
|
if 'error' in result:
|
||||||
raise AnsibleError(
|
raise AnsibleError(f"Could not connect: {result['error']}")
|
||||||
'Could not connect: {0}'.format(result['error']))
|
|
||||||
|
|
||||||
def get_object(self, name):
|
def get_object(self, name):
|
||||||
answer = self.call('xo.getAllObjects', {'filter': {'type': name}})
|
answer = self.call('xo.getAllObjects', {'filter': {'type': name}})
|
||||||
|
|
||||||
if 'error' in answer:
|
if 'error' in answer:
|
||||||
raise AnsibleError(
|
raise AnsibleError(f"Could not request: {answer['error']}")
|
||||||
'Could not request: {0}'.format(answer['error']))
|
|
||||||
|
|
||||||
return answer['result']
|
return answer['result']
|
||||||
|
|
||||||
|
@ -252,8 +249,7 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
def _add_hosts(self, hosts, pools):
|
def _add_hosts(self, hosts, pools):
|
||||||
for host in hosts.values():
|
for host in hosts.values():
|
||||||
entry_name = host['uuid']
|
entry_name = host['uuid']
|
||||||
group_name = 'xo_host_{0}'.format(
|
group_name = f"xo_host_{clean_group_name(host['name_label'])}"
|
||||||
clean_group_name(host['name_label']))
|
|
||||||
pool_name = self._pool_group_name_for_uuid(pools, host['$poolId'])
|
pool_name = self._pool_group_name_for_uuid(pools, host['$poolId'])
|
||||||
|
|
||||||
self.inventory.add_group(group_name)
|
self.inventory.add_group(group_name)
|
||||||
|
@ -276,15 +272,13 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
entry_name, 'product_brand', host['productBrand'])
|
entry_name, 'product_brand', host['productBrand'])
|
||||||
|
|
||||||
for pool in pools.values():
|
for pool in pools.values():
|
||||||
group_name = 'xo_pool_{0}'.format(
|
group_name = f"xo_pool_{clean_group_name(pool['name_label'])}"
|
||||||
clean_group_name(pool['name_label']))
|
|
||||||
|
|
||||||
self.inventory.add_group(group_name)
|
self.inventory.add_group(group_name)
|
||||||
|
|
||||||
def _add_pools(self, pools):
|
def _add_pools(self, pools):
|
||||||
for pool in pools.values():
|
for pool in pools.values():
|
||||||
group_name = 'xo_pool_{0}'.format(
|
group_name = f"xo_pool_{clean_group_name(pool['name_label'])}"
|
||||||
clean_group_name(pool['name_label']))
|
|
||||||
|
|
||||||
self.inventory.add_group(group_name)
|
self.inventory.add_group(group_name)
|
||||||
|
|
||||||
|
@ -292,16 +286,13 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
def _pool_group_name_for_uuid(self, pools, pool_uuid):
|
def _pool_group_name_for_uuid(self, pools, pool_uuid):
|
||||||
for pool in pools:
|
for pool in pools:
|
||||||
if pool == pool_uuid:
|
if pool == pool_uuid:
|
||||||
return 'xo_pool_{0}'.format(
|
return f"xo_pool_{clean_group_name(pools[pool_uuid]['name_label'])}"
|
||||||
clean_group_name(pools[pool_uuid]['name_label']))
|
|
||||||
|
|
||||||
# TODO: Refactor
|
# TODO: Refactor
|
||||||
def _host_group_name_for_uuid(self, hosts, host_uuid):
|
def _host_group_name_for_uuid(self, hosts, host_uuid):
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
if host == host_uuid:
|
if host == host_uuid:
|
||||||
return 'xo_host_{0}'.format(
|
return f"xo_host_{clean_group_name(hosts[host_uuid]['name_label'])}"
|
||||||
clean_group_name(hosts[host_uuid]['name_label']
|
|
||||||
))
|
|
||||||
|
|
||||||
def _populate(self, objects):
|
def _populate(self, objects):
|
||||||
# Prepare general groups
|
# Prepare general groups
|
||||||
|
|
Loading…
Reference in New Issue