mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-05-01 10:53:20 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5fd87a1811 | ||
|
|
e463f94ce9 | ||
|
|
4205a94f0c | ||
|
|
bcfcdd1052 | ||
|
|
2638413475 | ||
|
|
9ea55a81b3 | ||
|
|
32c1e39df1 | ||
|
|
7bb23e9649 | ||
|
|
eeedd97eec | ||
|
|
4e1ba6af46 | ||
|
|
aa1ae85b55 | ||
|
|
4d2873afd2 | ||
|
|
43c1d9f66c | ||
|
|
201f49acd9 | ||
|
|
6f0d46d0a2 | ||
|
|
92529d5605 | ||
|
|
f635ed6c2e | ||
|
|
0e0fce54ab | ||
|
|
caae74abd8 |
@@ -171,8 +171,8 @@ stages:
|
||||
parameters:
|
||||
testFormat: devel/{0}
|
||||
targets:
|
||||
- name: Alpine 3.17
|
||||
test: alpine/3.17
|
||||
- name: Alpine 3.18
|
||||
test: alpine/3.18
|
||||
# - name: Fedora 38
|
||||
# test: fedora/38
|
||||
- name: Ubuntu 22.04
|
||||
@@ -195,8 +195,6 @@ stages:
|
||||
test: rhel/8.8
|
||||
- name: FreeBSD 13.2
|
||||
test: freebsd/13.2
|
||||
- name: FreeBSD 12.4
|
||||
test: freebsd/12.4
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
@@ -217,6 +215,8 @@ stages:
|
||||
test: rhel/7.9
|
||||
- name: FreeBSD 13.1
|
||||
test: freebsd/13.1
|
||||
- name: FreeBSD 12.4
|
||||
test: freebsd/12.4
|
||||
groups:
|
||||
- 1
|
||||
- 2
|
||||
|
||||
4
.github/BOTMETA.yml
vendored
4
.github/BOTMETA.yml
vendored
@@ -670,9 +670,9 @@ files:
|
||||
$modules/jenkins_script.py:
|
||||
maintainers: hogarthj
|
||||
$modules/jira.py:
|
||||
ignore: DWSR
|
||||
ignore: DWSR tarka
|
||||
labels: jira
|
||||
maintainers: Slezhuk tarka pertoft
|
||||
maintainers: Slezhuk pertoft
|
||||
$modules/kdeconfig.py:
|
||||
maintainers: smeso
|
||||
$modules/kernel_blacklist.py:
|
||||
|
||||
@@ -6,6 +6,32 @@ Community General Release Notes
|
||||
|
||||
This changelog describes changes after version 5.0.0.
|
||||
|
||||
v6.6.4
|
||||
======
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
Regular bugfix release.
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- redfish_utils - use ``Controllers`` key in redfish data to obtain Storage controllers properties (https://github.com/ansible-collections/community.general/pull/7081).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- bitwarden lookup plugin - the plugin made assumptions about the structure of a Bitwarden JSON object which may have been broken by an update in the Bitwarden API. Remove assumptions, and allow queries for general fields such as ``notes`` (https://github.com/ansible-collections/community.general/pull/7061).
|
||||
- cmd_runner module utils - when a parameter in ``argument_spec`` has no type, meaning it is implicitly a ``str``, ``CmdRunner`` would fail trying to find the ``type`` key in that dictionary (https://github.com/ansible-collections/community.general/pull/6968).
|
||||
- ejabberd_user - module was failing to detect whether user was already created and/or password was changed (https://github.com/ansible-collections/community.general/pull/7033).
|
||||
- ejabberd_user - provide meaningful error message when the ``ejabberdctl`` command is not found (https://github.com/ansible-collections/community.general/pull/7028, https://github.com/ansible-collections/community.general/issues/6949).
|
||||
- oci_utils module utils - avoid direct type comparisons (https://github.com/ansible-collections/community.general/pull/7085).
|
||||
- proxmox module utils - fix proxmoxer library version check (https://github.com/ansible-collections/community.general/issues/6974, https://github.com/ansible-collections/community.general/issues/6975, https://github.com/ansible-collections/community.general/pull/6980).
|
||||
- proxmox_kvm - when ``name`` option is provided without ``vmid`` and VM with that name already exists then no new VM will be created (https://github.com/ansible-collections/community.general/issues/6911, https://github.com/ansible-collections/community.general/pull/6981).
|
||||
- proxmox_user_info - avoid direct type comparisons (https://github.com/ansible-collections/community.general/pull/7085).
|
||||
- rundeck - fix ``TypeError`` on 404 API response (https://github.com/ansible-collections/community.general/pull/6983).
|
||||
|
||||
v6.6.3
|
||||
======
|
||||
|
||||
|
||||
@@ -1491,3 +1491,42 @@ releases:
|
||||
- 6923-cobbler-inventory_unicode.yml
|
||||
- 6935-machinectl-become.yml
|
||||
release_date: '2023-07-16'
|
||||
6.6.4:
|
||||
changes:
|
||||
bugfixes:
|
||||
- bitwarden lookup plugin - the plugin made assumptions about the structure
|
||||
of a Bitwarden JSON object which may have been broken by an update in the
|
||||
Bitwarden API. Remove assumptions, and allow queries for general fields such
|
||||
as ``notes`` (https://github.com/ansible-collections/community.general/pull/7061).
|
||||
- cmd_runner module utils - when a parameter in ``argument_spec`` has no type,
|
||||
meaning it is implicitly a ``str``, ``CmdRunner`` would fail trying to find
|
||||
the ``type`` key in that dictionary (https://github.com/ansible-collections/community.general/pull/6968).
|
||||
- ejabberd_user - module was failing to detect whether user was already created
|
||||
and/or password was changed (https://github.com/ansible-collections/community.general/pull/7033).
|
||||
- ejabberd_user - provide meaningful error message when the ``ejabberdctl``
|
||||
command is not found (https://github.com/ansible-collections/community.general/pull/7028,
|
||||
https://github.com/ansible-collections/community.general/issues/6949).
|
||||
- oci_utils module utils - avoid direct type comparisons (https://github.com/ansible-collections/community.general/pull/7085).
|
||||
- proxmox module utils - fix proxmoxer library version check (https://github.com/ansible-collections/community.general/issues/6974,
|
||||
https://github.com/ansible-collections/community.general/issues/6975, https://github.com/ansible-collections/community.general/pull/6980).
|
||||
- proxmox_kvm - when ``name`` option is provided without ``vmid`` and VM with
|
||||
that name already exists then no new VM will be created (https://github.com/ansible-collections/community.general/issues/6911,
|
||||
https://github.com/ansible-collections/community.general/pull/6981).
|
||||
- proxmox_user_info - avoid direct type comparisons (https://github.com/ansible-collections/community.general/pull/7085).
|
||||
- rundeck - fix ``TypeError`` on 404 API response (https://github.com/ansible-collections/community.general/pull/6983).
|
||||
minor_changes:
|
||||
- redfish_utils - use ``Controllers`` key in redfish data to obtain Storage
|
||||
controllers properties (https://github.com/ansible-collections/community.general/pull/7081).
|
||||
release_summary: Regular bugfix release.
|
||||
fragments:
|
||||
- 6.6.4.yml
|
||||
- 6949-ejabberdctl-error.yml
|
||||
- 6968-cmdrunner-implicit-type.yml
|
||||
- 6980-proxmox-fix-token-auth.yml
|
||||
- 6981-proxmox-fix-vm-creation-when-only-name-provided.yml
|
||||
- 6983-rundeck-fix-typerrror-on-404-api-response.yml
|
||||
- 7033-ejabberd-user-bugs.yml
|
||||
- 7061-fix-bitwarden-get_field.yml
|
||||
- 7081-redfish-utils-fix-for-storagecontrollers-deprecated-key.yaml
|
||||
- 7085-sanity.yml
|
||||
release_date: '2023-08-13'
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
namespace: community
|
||||
name: general
|
||||
version: 6.6.3
|
||||
version: 6.6.4
|
||||
readme: README.md
|
||||
authors:
|
||||
- Ansible (https://github.com/ansible)
|
||||
|
||||
@@ -49,8 +49,10 @@ DOCUMENTATION = '''
|
||||
'''
|
||||
|
||||
EXAMPLES = r"""
|
||||
# Static inventory file
|
||||
# Plugin requires root privileges for chroot, -E preserves your env (and location of ~/.ansible):
|
||||
# sudo -E ansible-playbook ...
|
||||
#
|
||||
# Static inventory file
|
||||
# [chroots]
|
||||
# /path/to/debootstrap
|
||||
# /path/to/feboostrap
|
||||
|
||||
@@ -132,20 +132,29 @@ class Bitwarden(object):
|
||||
If field is None, return the whole record for each match.
|
||||
"""
|
||||
matches = self._get_matches(search_value, search_field, collection_id)
|
||||
|
||||
if field in ['autofillOnPageLoad', 'password', 'passwordRevisionDate', 'totp', 'uris', 'username']:
|
||||
return [match['login'][field] for match in matches]
|
||||
elif not field:
|
||||
if not field:
|
||||
return matches
|
||||
else:
|
||||
custom_field_matches = []
|
||||
for match in matches:
|
||||
field_matches = []
|
||||
for match in matches:
|
||||
# if there are no custom fields, then `match` has no key 'fields'
|
||||
if 'fields' in match:
|
||||
custom_field_found = False
|
||||
for custom_field in match['fields']:
|
||||
if custom_field['name'] == field:
|
||||
custom_field_matches.append(custom_field['value'])
|
||||
if matches and not custom_field_matches:
|
||||
raise AnsibleError("Custom field {field} does not exist in {search_value}".format(field=field, search_value=search_value))
|
||||
return custom_field_matches
|
||||
if field == custom_field['name']:
|
||||
field_matches.append(custom_field['value'])
|
||||
custom_field_found = True
|
||||
break
|
||||
if custom_field_found:
|
||||
continue
|
||||
if 'login' in match and field in match['login']:
|
||||
field_matches.append(match['login'][field])
|
||||
continue
|
||||
if field in match:
|
||||
field_matches.append(match[field])
|
||||
continue
|
||||
if matches and not field_matches:
|
||||
raise AnsibleError("field {field} does not exist in {search_value}".format(field=field, search_value=search_value))
|
||||
return field_matches
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
|
||||
@@ -203,7 +203,7 @@ class CmdRunner(object):
|
||||
|
||||
for mod_param_name, spec in iteritems(module.argument_spec):
|
||||
if mod_param_name not in self.arg_formats:
|
||||
self.arg_formats[mod_param_name] = _Format.as_default_type(spec['type'], mod_param_name)
|
||||
self.arg_formats[mod_param_name] = _Format.as_default_type(spec.get('type', 'str'), mod_param_name)
|
||||
|
||||
def __call__(self, args_order=None, output_process=None, ignore_value_none=True, check_mode_skip=False, check_mode_return=None, **kwargs):
|
||||
if output_process is None:
|
||||
|
||||
@@ -570,7 +570,7 @@ def are_lists_equal(s, t):
|
||||
s = to_dict(s)
|
||||
t = to_dict(t)
|
||||
|
||||
if type(s[0]) == dict:
|
||||
if isinstance(s[0], dict):
|
||||
# Handle list of dicts. Dictionary returned by the API may have additional keys. For example, a get call on
|
||||
# service gateway has an attribute `services` which is a list of `ServiceIdResponseDetails`. This has a key
|
||||
# `service_name` which is not provided in the list of `services` by a user while making an update call; only
|
||||
@@ -604,9 +604,9 @@ def get_attr_to_update(get_fn, kwargs_get, module, update_attributes):
|
||||
user_provided_attr_value = module.params.get(attr, None)
|
||||
|
||||
unequal_list_attr = (
|
||||
type(resources_attr_value) == list or type(user_provided_attr_value) == list
|
||||
isinstance(resources_attr_value, list) or isinstance(user_provided_attr_value, list)
|
||||
) and not are_lists_equal(user_provided_attr_value, resources_attr_value)
|
||||
unequal_attr = type(resources_attr_value) != list and to_dict(
|
||||
unequal_attr = not isinstance(resources_attr_value, list) and to_dict(
|
||||
resources_attr_value
|
||||
) != to_dict(user_provided_attr_value)
|
||||
if unequal_list_attr or unequal_attr:
|
||||
@@ -936,9 +936,9 @@ def tuplize(d):
|
||||
list_of_tuples = []
|
||||
key_list = sorted(list(d.keys()))
|
||||
for key in key_list:
|
||||
if type(d[key]) == list:
|
||||
if isinstance(d[key], list):
|
||||
# Convert a value which is itself a list of dict to a list of tuples.
|
||||
if d[key] and type(d[key][0]) == dict:
|
||||
if d[key] and isinstance(d[key][0], dict):
|
||||
sub_tuples = []
|
||||
for sub_dict in d[key]:
|
||||
sub_tuples.append(tuplize(sub_dict))
|
||||
@@ -948,7 +948,7 @@ def tuplize(d):
|
||||
list_of_tuples.append((sub_tuples is None, key, sub_tuples))
|
||||
else:
|
||||
list_of_tuples.append((d[key] is None, key, d[key]))
|
||||
elif type(d[key]) == dict:
|
||||
elif isinstance(d[key], dict):
|
||||
tupled_value = tuplize(d[key])
|
||||
list_of_tuples.append((tupled_value is None, key, tupled_value))
|
||||
else:
|
||||
@@ -969,13 +969,13 @@ def sort_dictionary(d):
|
||||
"""
|
||||
sorted_d = {}
|
||||
for key in d:
|
||||
if type(d[key]) == list:
|
||||
if d[key] and type(d[key][0]) == dict:
|
||||
if isinstance(d[key], list):
|
||||
if d[key] and isinstance(d[key][0], dict):
|
||||
sorted_value = sort_list_of_dictionary(d[key])
|
||||
sorted_d[key] = sorted_value
|
||||
else:
|
||||
sorted_d[key] = sorted(d[key])
|
||||
elif type(d[key]) == dict:
|
||||
elif isinstance(d[key], dict):
|
||||
sorted_d[key] = sort_dictionary(d[key])
|
||||
else:
|
||||
sorted_d[key] = d[key]
|
||||
@@ -1044,7 +1044,7 @@ def check_if_user_value_matches_resources_attr(
|
||||
|
||||
if (
|
||||
user_provided_value_for_attr
|
||||
and type(user_provided_value_for_attr[0]) == dict
|
||||
and isinstance(user_provided_value_for_attr[0], dict)
|
||||
):
|
||||
# Process a list of dict
|
||||
sorted_user_provided_value_for_attr = sort_list_of_dictionary(
|
||||
@@ -1547,7 +1547,7 @@ def delete_and_wait(
|
||||
except ServiceError as ex:
|
||||
# DNS API throws a 400 InvalidParameter when a zone id is provided for zone_name_or_id and if the zone
|
||||
# resource is not available, instead of the expected 404. So working around this for now.
|
||||
if type(client) == oci.dns.DnsClient:
|
||||
if isinstance(client, oci.dns.DnsClient):
|
||||
if ex.status == 400 and ex.code == "InvalidParameter":
|
||||
_debug(
|
||||
"Resource {0} with {1} already deleted. So returning changed=False".format(
|
||||
|
||||
@@ -18,6 +18,7 @@ import traceback
|
||||
PROXMOXER_IMP_ERR = None
|
||||
try:
|
||||
from proxmoxer import ProxmoxAPI
|
||||
from proxmoxer import __version__ as proxmoxer_version
|
||||
HAS_PROXMOXER = True
|
||||
except ImportError:
|
||||
HAS_PROXMOXER = False
|
||||
@@ -79,6 +80,7 @@ class ProxmoxAnsible(object):
|
||||
module.fail_json(msg=missing_required_lib('proxmoxer'), exception=PROXMOXER_IMP_ERR)
|
||||
|
||||
self.module = module
|
||||
self.proxmoxer_version = proxmoxer_version
|
||||
self.proxmox_api = self._connect()
|
||||
# Test token validity
|
||||
try:
|
||||
@@ -98,7 +100,7 @@ class ProxmoxAnsible(object):
|
||||
if api_password:
|
||||
auth_args['password'] = api_password
|
||||
else:
|
||||
if self.version() < LooseVersion('1.1.0'):
|
||||
if self.proxmoxer_version < LooseVersion('1.1.0'):
|
||||
self.module.fail_json('Using "token_name" and "token_value" require proxmoxer>=1.1.0')
|
||||
auth_args['token_name'] = api_token_id
|
||||
auth_args['token_value'] = api_token_secret
|
||||
|
||||
@@ -652,7 +652,8 @@ class RedfishUtils(object):
|
||||
properties = ['CacheSummary', 'FirmwareVersion', 'Identifiers',
|
||||
'Location', 'Manufacturer', 'Model', 'Name', 'Id',
|
||||
'PartNumber', 'SerialNumber', 'SpeedGbps', 'Status']
|
||||
key = "StorageControllers"
|
||||
key = "Controllers"
|
||||
deprecated_key = "StorageControllers"
|
||||
|
||||
# Find Storage service
|
||||
response = self.get_request(self.root_uri + systems_uri)
|
||||
@@ -680,7 +681,30 @@ class RedfishUtils(object):
|
||||
data = response['data']
|
||||
|
||||
if key in data:
|
||||
controller_list = data[key]
|
||||
controllers_uri = data[key][u'@odata.id']
|
||||
|
||||
response = self.get_request(self.root_uri + controllers_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
result['ret'] = True
|
||||
data = response['data']
|
||||
|
||||
if data[u'Members']:
|
||||
for controller_member in data[u'Members']:
|
||||
controller_member_uri = controller_member[u'@odata.id']
|
||||
response = self.get_request(self.root_uri + controller_member_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
result['ret'] = True
|
||||
data = response['data']
|
||||
|
||||
controller_result = {}
|
||||
for property in properties:
|
||||
if property in data:
|
||||
controller_result[property] = data[property]
|
||||
controller_results.append(controller_result)
|
||||
elif deprecated_key in data:
|
||||
controller_list = data[deprecated_key]
|
||||
for controller in controller_list:
|
||||
controller_result = {}
|
||||
for property in properties:
|
||||
@@ -735,7 +759,25 @@ class RedfishUtils(object):
|
||||
return response
|
||||
data = response['data']
|
||||
controller_name = 'Controller 1'
|
||||
if 'StorageControllers' in data:
|
||||
if 'Controllers' in data:
|
||||
controllers_uri = data['Controllers'][u'@odata.id']
|
||||
|
||||
response = self.get_request(self.root_uri + controllers_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
result['ret'] = True
|
||||
cdata = response['data']
|
||||
|
||||
if cdata[u'Members']:
|
||||
controller_member_uri = cdata[u'Members'][0][u'@odata.id']
|
||||
|
||||
response = self.get_request(self.root_uri + controller_member_uri)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
result['ret'] = True
|
||||
cdata = response['data']
|
||||
controller_name = cdata['Name']
|
||||
elif 'StorageControllers' in data:
|
||||
sc = data['StorageControllers']
|
||||
if sc:
|
||||
if 'Name' in sc[0]:
|
||||
@@ -839,15 +881,7 @@ class RedfishUtils(object):
|
||||
return response
|
||||
data = response['data']
|
||||
controller_name = 'Controller %s' % str(idx)
|
||||
if 'StorageControllers' in data:
|
||||
sc = data['StorageControllers']
|
||||
if sc:
|
||||
if 'Name' in sc[0]:
|
||||
controller_name = sc[0]['Name']
|
||||
else:
|
||||
sc_id = sc[0].get('Id', '1')
|
||||
controller_name = 'Controller %s' % sc_id
|
||||
elif 'Controllers' in data:
|
||||
if 'Controllers' in data:
|
||||
response = self.get_request(self.root_uri + data['Controllers'][u'@odata.id'])
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
@@ -865,6 +899,14 @@ class RedfishUtils(object):
|
||||
else:
|
||||
controller_id = member_data.get('Id', '1')
|
||||
controller_name = 'Controller %s' % controller_id
|
||||
elif 'StorageControllers' in data:
|
||||
sc = data['StorageControllers']
|
||||
if sc:
|
||||
if 'Name' in sc[0]:
|
||||
controller_name = sc[0]['Name']
|
||||
else:
|
||||
sc_id = sc[0].get('Id', '1')
|
||||
controller_name = 'Controller %s' % sc_id
|
||||
volume_results = []
|
||||
volume_list = []
|
||||
if 'Volumes' in data:
|
||||
|
||||
@@ -72,7 +72,9 @@ def api_request(module, endpoint, data=None, method="GET"):
|
||||
if info["status"] == 403:
|
||||
module.fail_json(msg="Token authorization failed",
|
||||
execution_info=json.loads(info["body"]))
|
||||
if info["status"] == 409:
|
||||
elif info["status"] == 404:
|
||||
return None, info
|
||||
elif info["status"] == 409:
|
||||
module.fail_json(msg="Job executions limit reached",
|
||||
execution_info=json.loads(info["body"]))
|
||||
elif info["status"] >= 500:
|
||||
|
||||
@@ -102,7 +102,7 @@ class EjabberdUser(object):
|
||||
changed. It will return True if the user does not match the supplied
|
||||
credentials and False if it does not
|
||||
"""
|
||||
return self.run_command('check_password', [self.user, self.host, self.pwd])
|
||||
return bool(self.run_command('check_password', [self.user, self.host, self.pwd])[0])
|
||||
|
||||
@property
|
||||
def exists(self):
|
||||
@@ -110,7 +110,7 @@ class EjabberdUser(object):
|
||||
host specified. If the user exists True is returned, otherwise False
|
||||
is returned
|
||||
"""
|
||||
return self.run_command('check_account', [self.user, self.host])
|
||||
return not bool(self.run_command('check_account', [self.user, self.host])[0])
|
||||
|
||||
def log(self, entry):
|
||||
""" This method will log information to the local syslog facility """
|
||||
@@ -122,7 +122,7 @@ class EjabberdUser(object):
|
||||
""" This method will run the any command specified and return the
|
||||
returns using the Ansible common module
|
||||
"""
|
||||
cmd = [self.module.get_bin_path('ejabberdctl'), cmd] + options
|
||||
cmd = [self.module.get_bin_path('ejabberdctl', required=True), cmd] + options
|
||||
self.log('command: %s' % " ".join(cmd))
|
||||
return self.module.run_command(cmd)
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ options:
|
||||
group:
|
||||
type: str
|
||||
description:
|
||||
- Name of the Jenkins group on the OS.
|
||||
- GID or name of the Jenkins group on the OS.
|
||||
default: jenkins
|
||||
jenkins_home:
|
||||
type: path
|
||||
@@ -47,7 +47,7 @@ options:
|
||||
owner:
|
||||
type: str
|
||||
description:
|
||||
- Name of the Jenkins user on the OS.
|
||||
- UID or name of the Jenkins user on the OS.
|
||||
default: jenkins
|
||||
state:
|
||||
type: str
|
||||
@@ -195,6 +195,29 @@ EXAMPLES = '''
|
||||
url_password: p4ssw0rd
|
||||
url: http://localhost:8888
|
||||
|
||||
#
|
||||
# Example of how to authenticate with serverless deployment
|
||||
#
|
||||
- name: Update plugins on ECS Fargate Jenkins instance
|
||||
community.general.jenkins_plugin:
|
||||
# plugin name and version
|
||||
name: ws-cleanup
|
||||
version: '0.45'
|
||||
# Jenkins home path mounted on ec2-helper VM (example)
|
||||
jenkins_home: "/mnt/{{ jenkins_instance }}"
|
||||
# matching the UID/GID to one in official Jenkins image
|
||||
owner: 1000
|
||||
group: 1000
|
||||
# Jenkins instance URL and admin credentials
|
||||
url: "https://{{ jenkins_instance }}.com/"
|
||||
url_username: admin
|
||||
url_password: p4ssw0rd
|
||||
# make module work from EC2 which has local access
|
||||
# to EFS mount as well as Jenkins URL
|
||||
delegate_to: ec2-helper
|
||||
vars:
|
||||
jenkins_instance: foobar
|
||||
|
||||
#
|
||||
# Example of a Play which handles Jenkins restarts during the state changes
|
||||
#
|
||||
|
||||
@@ -281,8 +281,9 @@ options:
|
||||
type: int
|
||||
name:
|
||||
description:
|
||||
- Specifies the VM name. Only used on the configuration web interface.
|
||||
- Required only for C(state=present).
|
||||
- Specifies the VM name. Name could be non-unique across the cluster.
|
||||
- Required only for I(state=present).
|
||||
- With I(state=present) if I(vmid) not provided and VM with name exists in the cluster then no changes will be made.
|
||||
type: str
|
||||
nameservers:
|
||||
description:
|
||||
@@ -1210,10 +1211,14 @@ def main():
|
||||
# the cloned vm name or retrieve the next free VM id from ProxmoxAPI.
|
||||
if not vmid:
|
||||
if state == 'present' and not update and not clone and not delete and not revert:
|
||||
try:
|
||||
vmid = proxmox.get_nextvmid()
|
||||
except Exception:
|
||||
module.fail_json(msg="Can't get the next vmid for VM {0} automatically. Ensure your cluster state is good".format(name))
|
||||
existing_vmid = proxmox.get_vmid(name, ignore_missing=True)
|
||||
if existing_vmid:
|
||||
vmid = existing_vmid
|
||||
else:
|
||||
try:
|
||||
vmid = proxmox.get_nextvmid()
|
||||
except Exception:
|
||||
module.fail_json(msg="Can't get the next vmid for VM {0} automatically. Ensure your cluster state is good".format(name))
|
||||
else:
|
||||
clone_target = clone or name
|
||||
vmid = proxmox.get_vmid(clone_target, ignore_missing=True)
|
||||
|
||||
@@ -193,14 +193,14 @@ class ProxmoxUser:
|
||||
self.user[k] = v
|
||||
elif k in ['groups', 'tokens'] and (v == '' or v is None):
|
||||
self.user[k] = []
|
||||
elif k == 'groups' and type(v) == str:
|
||||
elif k == 'groups' and isinstance(v, str):
|
||||
self.user['groups'] = v.split(',')
|
||||
elif k == 'tokens' and type(v) == list:
|
||||
elif k == 'tokens' and isinstance(v, list):
|
||||
for token in v:
|
||||
if 'privsep' in token:
|
||||
token['privsep'] = proxmox_to_ansible_bool(token['privsep'])
|
||||
self.user['tokens'] = v
|
||||
elif k == 'tokens' and type(v) == dict:
|
||||
elif k == 'tokens' and isinstance(v, dict):
|
||||
self.user['tokens'] = list()
|
||||
for tokenid, tokenvalues in v.items():
|
||||
t = tokenvalues
|
||||
|
||||
@@ -26,6 +26,7 @@ def main():
|
||||
arg_values=dict(type="dict", default={}),
|
||||
check_mode_skip=dict(type="bool", default=False),
|
||||
aa=dict(type="raw"),
|
||||
tt=dict(),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
@@ -121,3 +121,20 @@ cmd_echo_tests:
|
||||
- test_result.rc == None
|
||||
- test_result.out == None
|
||||
- test_result.err == None
|
||||
|
||||
- name: set aa and tt value
|
||||
arg_formats:
|
||||
aa:
|
||||
func: as_opt_eq_val
|
||||
args: [--answer]
|
||||
tt:
|
||||
func: as_opt_val
|
||||
args: [--tt-arg]
|
||||
arg_order: 'aa tt'
|
||||
arg_values:
|
||||
tt: potatoes
|
||||
aa: 11
|
||||
assertions:
|
||||
- test_result.rc == 0
|
||||
- test_result.out == "-- --answer=11 --tt-arg potatoes\n"
|
||||
- test_result.err == ""
|
||||
|
||||
11
tests/integration/targets/ejabberd_user/aliases
Normal file
11
tests/integration/targets/ejabberd_user/aliases
Normal file
@@ -0,0 +1,11 @@
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
azp/posix/3
|
||||
skip/osx
|
||||
skip/macos
|
||||
skip/freebsd
|
||||
skip/alpine
|
||||
skip/rhel
|
||||
destructive
|
||||
@@ -0,0 +1,9 @@
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
---
|
||||
- name: Remove ejabberd
|
||||
ansible.builtin.package:
|
||||
name: ejabberd
|
||||
state: absent
|
||||
7
tests/integration/targets/ejabberd_user/meta/main.yml
Normal file
7
tests/integration/targets/ejabberd_user/meta/main.yml
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
dependencies:
|
||||
- setup_pkg_mgr
|
||||
106
tests/integration/targets/ejabberd_user/tasks/main.yml
Normal file
106
tests/integration/targets/ejabberd_user/tasks/main.yml
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
####################################################################
|
||||
# WARNING: These are designed specifically for Ansible tests #
|
||||
# and should not be used as examples of how to write Ansible roles #
|
||||
####################################################################
|
||||
|
||||
# Copyright (c) Ansible Project
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Bail out if not supported
|
||||
ansible.builtin.meta: end_play
|
||||
when: ansible_distribution in ('Alpine', 'openSUSE Leap', 'CentOS', 'Fedora')
|
||||
|
||||
|
||||
- name: Remove ejabberd
|
||||
ansible.builtin.package:
|
||||
name: ejabberd
|
||||
state: absent
|
||||
|
||||
- name: Create user without ejabberdctl installed
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
password: pa$$w0rd
|
||||
state: present
|
||||
register: user_no_ejabberdctl
|
||||
ignore_errors: true
|
||||
|
||||
- name: Install ejabberd
|
||||
ansible.builtin.package:
|
||||
name: ejabberd
|
||||
state: present
|
||||
notify: Remove ejabberd
|
||||
|
||||
- ansible.builtin.service:
|
||||
name: ejabberd
|
||||
state: started
|
||||
|
||||
- name: Create user alice (check)
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
password: pa$$w0rd
|
||||
state: present
|
||||
check_mode: true
|
||||
register: user_alice_check
|
||||
|
||||
- name: Create user alice
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
password: pa$$w0rd
|
||||
state: present
|
||||
register: user_alice
|
||||
|
||||
- name: Create user alice (idempotency)
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
password: pa$$w0rd
|
||||
state: present
|
||||
register: user_alice_idempot
|
||||
|
||||
- name: Create user alice (change password)
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
password: different_pa$$w0rd
|
||||
state: present
|
||||
register: user_alice_chgpw
|
||||
|
||||
- name: Remove user alice (check)
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
state: absent
|
||||
register: remove_alice_check
|
||||
check_mode: true
|
||||
|
||||
- name: Remove user alice
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
state: absent
|
||||
register: remove_alice
|
||||
|
||||
- name: Remove user alice (idempotency)
|
||||
community.general.ejabberd_user:
|
||||
host: localhost
|
||||
username: alice
|
||||
state: absent
|
||||
register: remove_alice_idempot
|
||||
|
||||
- name: Assertions
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- user_no_ejabberdctl is failed
|
||||
- "'Failed to find required executable' in user_no_ejabberdctl.msg"
|
||||
- user_alice_check is changed
|
||||
- user_alice is changed
|
||||
- user_alice_idempot is not changed
|
||||
- user_alice_chgpw is changed
|
||||
- remove_alice_check is changed
|
||||
- remove_alice is changed
|
||||
- remove_alice_idempot is not changed
|
||||
@@ -9,3 +9,4 @@ skip/osx
|
||||
skip/macos
|
||||
skip/freebsd
|
||||
needs/root
|
||||
skip/rhel # FIXME: keytool seems to be broken on newer RHELs
|
||||
|
||||
@@ -9,3 +9,4 @@ skip/osx
|
||||
skip/macos
|
||||
skip/freebsd
|
||||
needs/root
|
||||
skip/rhel # FIXME: keytool seems to be broken on newer RHELs
|
||||
|
||||
@@ -3,17 +3,29 @@
|
||||
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
- name: Remove python requests
|
||||
ansible.builtin.pip:
|
||||
name:
|
||||
- requests
|
||||
state: absent
|
||||
|
||||
- name: Stop docker service
|
||||
become: true
|
||||
ansible.builtin.service:
|
||||
name: docker
|
||||
state: stopped
|
||||
|
||||
- name: Remove Docker packages
|
||||
package:
|
||||
ansible.builtin.package:
|
||||
name: "{{ docker_packages }}"
|
||||
state: absent
|
||||
|
||||
- name: "D-Fedora : Remove repository"
|
||||
file:
|
||||
ansible.builtin.file:
|
||||
path: /etc/yum.repos.d/docker-ce.repo
|
||||
state: absent
|
||||
|
||||
- name: "D-Fedora : Remove dnf-plugins-core"
|
||||
package:
|
||||
ansible.builtin.package:
|
||||
name: dnf-plugins-core
|
||||
state: absent
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
ansible.builtin.service:
|
||||
name: docker
|
||||
state: started
|
||||
notify: Stop docker service
|
||||
|
||||
- name: Cheat on the docker socket permissions
|
||||
become: true
|
||||
@@ -53,3 +54,4 @@
|
||||
name:
|
||||
- requests
|
||||
state: present
|
||||
notify: Remove python requests
|
||||
|
||||
@@ -3,6 +3,7 @@ plugins/modules/consul.py validate-modules:undocumented-parameter
|
||||
plugins/modules/consul_session.py validate-modules:parameter-state-invalid-choice
|
||||
plugins/modules/gconftool2.py validate-modules:parameter-state-invalid-choice # state=get - removed in 8.0.0
|
||||
plugins/modules/homectl.py import-3.11 # Uses deprecated stdlib library 'crypt'
|
||||
plugins/modules/homectl.py import-3.12 # Uses deprecated stdlib library 'crypt'
|
||||
plugins/modules/iptables_state.py validate-modules:undocumented-parameter # params _back and _timeout used by action plugin
|
||||
plugins/modules/lxc_container.py validate-modules:use-run-command-not-popen
|
||||
plugins/modules/manageiq_policies.py validate-modules:parameter-state-invalid-choice # state=list - removed in 8.0.0
|
||||
@@ -19,4 +20,5 @@ plugins/modules/rax_files.py validate-modules:parameter-state-invalid-choice
|
||||
plugins/modules/rax.py use-argspec-type-path # module deprecated - removed in 9.0.0
|
||||
plugins/modules/rhevm.py validate-modules:parameter-state-invalid-choice
|
||||
plugins/modules/udm_user.py import-3.11 # Uses deprecated stdlib library 'crypt'
|
||||
plugins/modules/udm_user.py import-3.12 # Uses deprecated stdlib library 'crypt'
|
||||
plugins/modules/xfconf.py validate-modules:return-syntax-error
|
||||
|
||||
@@ -17,7 +17,7 @@ class DictDataLoader(DataLoader):
|
||||
|
||||
def __init__(self, file_mapping=None):
|
||||
file_mapping = {} if file_mapping is None else file_mapping
|
||||
assert type(file_mapping) == dict
|
||||
assert isinstance(file_mapping, dict)
|
||||
|
||||
super(DictDataLoader, self).__init__()
|
||||
|
||||
|
||||
@@ -8,6 +8,13 @@ __metaclass__ = type
|
||||
|
||||
import json
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
proxmoxer = pytest.importorskip('proxmoxer')
|
||||
mandatory_py_version = pytest.mark.skipif(
|
||||
sys.version_info < (2, 7),
|
||||
reason='The proxmoxer dependency requires python2.7 or higher'
|
||||
)
|
||||
|
||||
from ansible_collections.community.general.tests.unit.compat.mock import MagicMock, patch
|
||||
from ansible_collections.community.general.plugins.modules import proxmox_snap
|
||||
|
||||
@@ -12,6 +12,13 @@ __metaclass__ = type
|
||||
|
||||
import pytest
|
||||
import json
|
||||
import sys
|
||||
|
||||
proxmoxer = pytest.importorskip('proxmoxer')
|
||||
mandatory_py_version = pytest.mark.skipif(
|
||||
sys.version_info < (2, 7),
|
||||
reason='The proxmoxer dependency requires python2.7 or higher'
|
||||
)
|
||||
|
||||
from ansible_collections.community.general.plugins.modules import proxmox_tasks_info
|
||||
import ansible_collections.community.general.plugins.module_utils.proxmox as proxmox_utils
|
||||
|
||||
@@ -43,4 +43,8 @@ dataclasses ; python_version == '3.6'
|
||||
elastic-apm ; python_version >= '3.6'
|
||||
|
||||
# requirements for scaleway modules
|
||||
passlib[argon2]
|
||||
passlib[argon2]
|
||||
|
||||
# requirements for the proxmox modules
|
||||
proxmoxer < 2.0.0 ; python_version >= '2.7' and python_version <= '3.6'
|
||||
proxmoxer ; python_version > '3.6'
|
||||
|
||||
Reference in New Issue
Block a user