mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-29 18:06:53 +00:00
Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3197ef2e38 | ||
|
|
5f971e677a | ||
|
|
1b5d91153b | ||
|
|
2ce9ea8c54 | ||
|
|
eec4861c36 | ||
|
|
82e7e931a8 | ||
|
|
4b59174063 | ||
|
|
58d8469759 | ||
|
|
6d5dbfd455 | ||
|
|
6357048068 | ||
|
|
a861149a0e | ||
|
|
9a9b0b04a5 | ||
|
|
0a4e9379e2 | ||
|
|
7d1abf5d6a | ||
|
|
7ef25be10c | ||
|
|
0d0194fdf8 |
@@ -6,6 +6,39 @@ Community General Release Notes
|
|||||||
|
|
||||||
This changelog describes changes after version 2.0.0.
|
This changelog describes changes after version 2.0.0.
|
||||||
|
|
||||||
|
v3.3.2
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Extraordinary bugfix release to fix some annoying bugs.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- archive - fixed task failure when using the ``remove`` option with a ``path`` containing nested files for ``format``s other than ``zip`` (https://github.com/ansible-collections/community.general/issues/2919).
|
||||||
|
- lvol - honor ``check_mode`` on thinpool (https://github.com/ansible-collections/community.general/issues/2934).
|
||||||
|
- module_helper module utils - fixed change-tracking for dictionaries and lists (https://github.com/ansible-collections/community.general/pull/2951).
|
||||||
|
- npm - correctly handle cases where a dependency does not have a ``version`` property because it is either missing or invalid (https://github.com/ansible-collections/community.general/issues/2917).
|
||||||
|
- pacman - fix changed status when ignorepkg has been defined (https://github.com/ansible-collections/community.general/issues/1758).
|
||||||
|
- snap - fixed the order of the ``--classic`` parameter in the command line invocation (https://github.com/ansible-collections/community.general/issues/2916).
|
||||||
|
|
||||||
|
v3.3.1
|
||||||
|
======
|
||||||
|
|
||||||
|
Release Summary
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Extraordinary bugfix release to fix a fatal bug in ``snap``.
|
||||||
|
|
||||||
|
Bugfixes
|
||||||
|
--------
|
||||||
|
|
||||||
|
- keycloak_authentication - fix bug when two identical executions are in the same authentication flow (https://github.com/ansible-collections/community.general/pull/2904).
|
||||||
|
- module_helper module utils - avoid failing when non-zero ``rc`` is present on regular exit (https://github.com/ansible-collections/community.general/pull/2912).
|
||||||
|
- snap - fix various bugs which prevented the module from working at all, and which resulted in ``state=absent`` fail on absent snaps (https://github.com/ansible-collections/community.general/issues/2835, https://github.com/ansible-collections/community.general/issues/2906, https://github.com/ansible-collections/community.general/pull/2912).
|
||||||
|
|
||||||
v3.3.0
|
v3.3.0
|
||||||
======
|
======
|
||||||
|
|
||||||
|
|||||||
@@ -1392,3 +1392,42 @@ releases:
|
|||||||
name: keycloak_authentication
|
name: keycloak_authentication
|
||||||
namespace: identity.keycloak
|
namespace: identity.keycloak
|
||||||
release_date: '2021-06-29'
|
release_date: '2021-06-29'
|
||||||
|
3.3.1:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- keycloak_authentication - fix bug when two identical executions are in the
|
||||||
|
same authentication flow (https://github.com/ansible-collections/community.general/pull/2904).
|
||||||
|
- module_helper module utils - avoid failing when non-zero ``rc`` is present
|
||||||
|
on regular exit (https://github.com/ansible-collections/community.general/pull/2912).
|
||||||
|
- snap - fix various bugs which prevented the module from working at all, and
|
||||||
|
which resulted in ``state=absent`` fail on absent snaps (https://github.com/ansible-collections/community.general/issues/2835,
|
||||||
|
https://github.com/ansible-collections/community.general/issues/2906, https://github.com/ansible-collections/community.general/pull/2912).
|
||||||
|
release_summary: Extraordinary bugfix release to fix a fatal bug in ``snap``.
|
||||||
|
fragments:
|
||||||
|
- 2904-fix-bug-when-2-identical-executions-in-same-auth-flow.yml
|
||||||
|
- 2912-snap-module-helper.yml
|
||||||
|
- 3.3.1.yml
|
||||||
|
release_date: '2021-07-01'
|
||||||
|
3.3.2:
|
||||||
|
changes:
|
||||||
|
bugfixes:
|
||||||
|
- archive - fixed task failure when using the ``remove`` option with a ``path``
|
||||||
|
containing nested files for ``format``s other than ``zip`` (https://github.com/ansible-collections/community.general/issues/2919).
|
||||||
|
- lvol - honor ``check_mode`` on thinpool (https://github.com/ansible-collections/community.general/issues/2934).
|
||||||
|
- module_helper module utils - fixed change-tracking for dictionaries and lists
|
||||||
|
(https://github.com/ansible-collections/community.general/pull/2951).
|
||||||
|
- npm - correctly handle cases where a dependency does not have a ``version``
|
||||||
|
property because it is either missing or invalid (https://github.com/ansible-collections/community.general/issues/2917).
|
||||||
|
- pacman - fix changed status when ignorepkg has been defined (https://github.com/ansible-collections/community.general/issues/1758).
|
||||||
|
- snap - fixed the order of the ``--classic`` parameter in the command line
|
||||||
|
invocation (https://github.com/ansible-collections/community.general/issues/2916).
|
||||||
|
release_summary: Extraordinary bugfix release to fix some annoying bugs.
|
||||||
|
fragments:
|
||||||
|
- 2918-snap-param-order.yml
|
||||||
|
- 2923-archive-remove-bugfix.yml
|
||||||
|
- 2924-npm-fix-package-json.yml
|
||||||
|
- 2935-lvol-support_check_mode_thinpool.yml
|
||||||
|
- 2936-pacman-fix_changed_status_when_ignorepkg_has_been_defined.yml
|
||||||
|
- 2951-mh-vars-deepcopy.yml
|
||||||
|
- 3.3.2.yml
|
||||||
|
release_date: '2021-07-08'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace: community
|
namespace: community
|
||||||
name: general
|
name: general
|
||||||
version: 3.3.0
|
version: 3.3.2
|
||||||
readme: README.md
|
readme: README.md
|
||||||
authors:
|
authors:
|
||||||
- Ansible (https://github.com/ansible)
|
- Ansible (https://github.com/ansible)
|
||||||
|
|||||||
@@ -59,4 +59,7 @@ class ModuleHelperBase(object):
|
|||||||
self.__init_module__()
|
self.__init_module__()
|
||||||
self.__run__()
|
self.__run__()
|
||||||
self.__quit_module__()
|
self.__quit_module__()
|
||||||
self.module.exit_json(changed=self.has_changed(), **self.output)
|
output = self.output
|
||||||
|
if 'failed' not in output:
|
||||||
|
output['failed'] = False
|
||||||
|
self.module.exit_json(changed=self.has_changed(), **output)
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
from __future__ import absolute_import, division, print_function
|
from __future__ import absolute_import, division, print_function
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
|
import copy
|
||||||
|
|
||||||
|
|
||||||
class VarMeta(object):
|
class VarMeta(object):
|
||||||
NOTHING = object()
|
NOTHING = object()
|
||||||
@@ -30,11 +32,11 @@ class VarMeta(object):
|
|||||||
if fact is not None:
|
if fact is not None:
|
||||||
self.fact = fact
|
self.fact = fact
|
||||||
if initial_value is not self.NOTHING:
|
if initial_value is not self.NOTHING:
|
||||||
self.initial_value = initial_value
|
self.initial_value = copy.deepcopy(initial_value)
|
||||||
|
|
||||||
def set_value(self, value):
|
def set_value(self, value):
|
||||||
if not self.init:
|
if not self.init:
|
||||||
self.initial_value = value
|
self.initial_value = copy.deepcopy(value)
|
||||||
self.init = True
|
self.init = True
|
||||||
self.value = value
|
self.value = value
|
||||||
return self
|
return self
|
||||||
|
|||||||
@@ -399,13 +399,14 @@ class Archive(object):
|
|||||||
|
|
||||||
def remove_targets(self):
|
def remove_targets(self):
|
||||||
for path in self.successes:
|
for path in self.successes:
|
||||||
try:
|
if os.path.exists(path):
|
||||||
if os.path.isdir(path):
|
try:
|
||||||
shutil.rmtree(path)
|
if os.path.isdir(path):
|
||||||
else:
|
shutil.rmtree(path)
|
||||||
os.remove(path)
|
else:
|
||||||
except OSError:
|
os.remove(path)
|
||||||
self.errors.append(_to_native(path))
|
except OSError:
|
||||||
|
self.errors.append(_to_native(path))
|
||||||
for path in self.paths:
|
for path in self.paths:
|
||||||
try:
|
try:
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path):
|
||||||
|
|||||||
@@ -200,11 +200,11 @@ def create_or_update_executions(kc, config, realm='master'):
|
|||||||
try:
|
try:
|
||||||
changed = False
|
changed = False
|
||||||
if "authenticationExecutions" in config:
|
if "authenticationExecutions" in config:
|
||||||
|
# Get existing executions on the Keycloak server for this alias
|
||||||
|
existing_executions = kc.get_executions_representation(config, realm=realm)
|
||||||
for new_exec_index, new_exec in enumerate(config["authenticationExecutions"], start=0):
|
for new_exec_index, new_exec in enumerate(config["authenticationExecutions"], start=0):
|
||||||
if new_exec["index"] is not None:
|
if new_exec["index"] is not None:
|
||||||
new_exec_index = new_exec["index"]
|
new_exec_index = new_exec["index"]
|
||||||
# Get existing executions on the Keycloak server for this alias
|
|
||||||
existing_executions = kc.get_executions_representation(config, realm=realm)
|
|
||||||
exec_found = False
|
exec_found = False
|
||||||
# Get flowalias parent if given
|
# Get flowalias parent if given
|
||||||
if new_exec["flowAlias"] is not None:
|
if new_exec["flowAlias"] is not None:
|
||||||
@@ -222,6 +222,9 @@ def create_or_update_executions(kc, config, realm='master'):
|
|||||||
# Compare the executions to see if it need changes
|
# Compare the executions to see if it need changes
|
||||||
if not is_struct_included(new_exec, existing_executions[exec_index], exclude_key) or exec_index != new_exec_index:
|
if not is_struct_included(new_exec, existing_executions[exec_index], exclude_key) or exec_index != new_exec_index:
|
||||||
changed = True
|
changed = True
|
||||||
|
id_to_update = existing_executions[exec_index]["id"]
|
||||||
|
# Remove exec from list in case 2 exec with same name
|
||||||
|
existing_executions[exec_index].clear()
|
||||||
elif new_exec["providerId"] is not None:
|
elif new_exec["providerId"] is not None:
|
||||||
kc.create_execution(new_exec, flowAlias=flow_alias_parent, realm=realm)
|
kc.create_execution(new_exec, flowAlias=flow_alias_parent, realm=realm)
|
||||||
changed = True
|
changed = True
|
||||||
@@ -229,13 +232,10 @@ def create_or_update_executions(kc, config, realm='master'):
|
|||||||
kc.create_subflow(new_exec["displayName"], flow_alias_parent, realm=realm)
|
kc.create_subflow(new_exec["displayName"], flow_alias_parent, realm=realm)
|
||||||
changed = True
|
changed = True
|
||||||
if changed:
|
if changed:
|
||||||
# Get existing executions on the Keycloak server for this alias
|
|
||||||
existing_executions = kc.get_executions_representation(config, realm=realm)
|
|
||||||
exec_index = find_exec_in_executions(new_exec, existing_executions)
|
|
||||||
if exec_index != -1:
|
if exec_index != -1:
|
||||||
# Update the existing execution
|
# Update the existing execution
|
||||||
updated_exec = {
|
updated_exec = {
|
||||||
"id": existing_executions[exec_index]["id"]
|
"id": id_to_update
|
||||||
}
|
}
|
||||||
# add the execution configuration
|
# add the execution configuration
|
||||||
if new_exec["authenticationConfig"] is not None:
|
if new_exec["authenticationConfig"] is not None:
|
||||||
|
|||||||
@@ -216,7 +216,6 @@ class Npm(object):
|
|||||||
self.module.fail_json(msg="Failed to parse NPM output with error %s" % to_native(e))
|
self.module.fail_json(msg="Failed to parse NPM output with error %s" % to_native(e))
|
||||||
if 'dependencies' in data:
|
if 'dependencies' in data:
|
||||||
for dep, props in data['dependencies'].items():
|
for dep, props in data['dependencies'].items():
|
||||||
dep_version = dep + '@' + str(props['version'])
|
|
||||||
|
|
||||||
if 'missing' in props and props['missing']:
|
if 'missing' in props and props['missing']:
|
||||||
missing.append(dep)
|
missing.append(dep)
|
||||||
@@ -224,7 +223,9 @@ class Npm(object):
|
|||||||
missing.append(dep)
|
missing.append(dep)
|
||||||
else:
|
else:
|
||||||
installed.append(dep)
|
installed.append(dep)
|
||||||
installed.append(dep_version)
|
if 'version' in props and props['version']:
|
||||||
|
dep_version = dep + '@' + str(props['version'])
|
||||||
|
installed.append(dep_version)
|
||||||
if self.name_version and self.name_version not in installed:
|
if self.name_version and self.name_version not in installed:
|
||||||
missing.append(self.name)
|
missing.append(self.name)
|
||||||
# Named dependency not installed
|
# Named dependency not installed
|
||||||
|
|||||||
@@ -254,16 +254,23 @@ def upgrade(module, pacman_path):
|
|||||||
# e.g., "ansible 2.7.1-1 -> 2.7.2-1"
|
# e.g., "ansible 2.7.1-1 -> 2.7.2-1"
|
||||||
regex = re.compile(r'([\w+\-.@]+) (\S+-\S+) -> (\S+-\S+)')
|
regex = re.compile(r'([\w+\-.@]+) (\S+-\S+) -> (\S+-\S+)')
|
||||||
for p in data:
|
for p in data:
|
||||||
m = regex.search(p)
|
if '[ignored]' not in p:
|
||||||
packages.append(m.group(1))
|
m = regex.search(p)
|
||||||
if module._diff:
|
packages.append(m.group(1))
|
||||||
diff['before'] += "%s-%s\n" % (m.group(1), m.group(2))
|
if module._diff:
|
||||||
diff['after'] += "%s-%s\n" % (m.group(1), m.group(3))
|
diff['before'] += "%s-%s\n" % (m.group(1), m.group(2))
|
||||||
|
diff['after'] += "%s-%s\n" % (m.group(1), m.group(3))
|
||||||
if module.check_mode:
|
if module.check_mode:
|
||||||
module.exit_json(changed=True, msg="%s package(s) would be upgraded" % (len(data)), packages=packages, diff=diff)
|
if packages:
|
||||||
|
module.exit_json(changed=True, msg="%s package(s) would be upgraded" % (len(data)), packages=packages, diff=diff)
|
||||||
|
else:
|
||||||
|
module.exit_json(changed=False, msg='Nothing to upgrade', packages=packages)
|
||||||
rc, stdout, stderr = module.run_command(cmdupgrade, check_rc=False)
|
rc, stdout, stderr = module.run_command(cmdupgrade, check_rc=False)
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
module.exit_json(changed=True, msg='System upgraded', packages=packages, diff=diff)
|
if packages:
|
||||||
|
module.exit_json(changed=True, msg='System upgraded', packages=packages, diff=diff)
|
||||||
|
else:
|
||||||
|
module.exit_json(changed=False, msg='Nothing to upgrade', packages=packages)
|
||||||
else:
|
else:
|
||||||
module.fail_json(msg="Could not upgrade")
|
module.fail_json(msg="Could not upgrade")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -107,6 +107,8 @@ snaps_removed:
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from ansible.module_utils.common.text.converters import to_native
|
||||||
|
|
||||||
from ansible_collections.community.general.plugins.module_utils.module_helper import (
|
from ansible_collections.community.general.plugins.module_utils.module_helper import (
|
||||||
CmdStateModuleHelper, ArgFormat, ModuleHelperException
|
CmdStateModuleHelper, ArgFormat, ModuleHelperException
|
||||||
)
|
)
|
||||||
@@ -123,7 +125,7 @@ __state_map = dict(
|
|||||||
|
|
||||||
|
|
||||||
def _state_map(value):
|
def _state_map(value):
|
||||||
return __state_map[value]
|
return [__state_map[value]]
|
||||||
|
|
||||||
|
|
||||||
class Snap(CmdStateModuleHelper):
|
class Snap(CmdStateModuleHelper):
|
||||||
@@ -131,10 +133,10 @@ class Snap(CmdStateModuleHelper):
|
|||||||
module = dict(
|
module = dict(
|
||||||
argument_spec={
|
argument_spec={
|
||||||
'name': dict(type='list', elements='str', required=True),
|
'name': dict(type='list', elements='str', required=True),
|
||||||
'state': dict(type='str', required=False, default='present',
|
'state': dict(type='str', default='present',
|
||||||
choices=['absent', 'present', 'enabled', 'disabled']),
|
choices=['absent', 'present', 'enabled', 'disabled']),
|
||||||
'classic': dict(type='bool', required=False, default=False),
|
'classic': dict(type='bool', default=False),
|
||||||
'channel': dict(type='str', required=False, default='stable'),
|
'channel': dict(type='str', default='stable'),
|
||||||
},
|
},
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
@@ -163,20 +165,20 @@ class Snap(CmdStateModuleHelper):
|
|||||||
results[i].append(output[i])
|
results[i].append(output[i])
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'; '.join(results[0]),
|
'; '.join([to_native(x) for x in results[0]]),
|
||||||
self._first_non_zero(results[1]),
|
self._first_non_zero(results[1]),
|
||||||
'\n'.join(results[2]),
|
'\n'.join(results[2]),
|
||||||
'\n'.join(results[3]),
|
'\n'.join(results[3]),
|
||||||
]
|
]
|
||||||
|
|
||||||
def snap_exists(self, snap_name):
|
def snap_exists(self, snap_name):
|
||||||
return 0 == self.run_command(params=[{'state': 'info'}, {'name': [snap_name]}])[0]
|
return 0 == self.run_command(params=[{'state': 'info'}, {'name': snap_name}])[0]
|
||||||
|
|
||||||
def is_snap_installed(self, snap_name):
|
def is_snap_installed(self, snap_name):
|
||||||
return 0 == self.run_command(params=[{'state': 'list'}, {'name': [snap_name]}])[0]
|
return 0 == self.run_command(params=[{'state': 'list'}, {'name': snap_name}])[0]
|
||||||
|
|
||||||
def is_snap_enabled(self, snap_name):
|
def is_snap_enabled(self, snap_name):
|
||||||
rc, out, err = self.run_command(params=[{'state': 'list'}, {'name': [snap_name]}])
|
rc, out, err = self.run_command(params=[{'state': 'list'}, {'name': snap_name}])
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
return None
|
return None
|
||||||
result = out.splitlines()[1]
|
result = out.splitlines()[1]
|
||||||
@@ -196,20 +198,20 @@ class Snap(CmdStateModuleHelper):
|
|||||||
self.validate_input_snaps() # if snap doesnt exist, it will explode when trying to install
|
self.validate_input_snaps() # if snap doesnt exist, it will explode when trying to install
|
||||||
self.vars.meta('classic').set(output=True)
|
self.vars.meta('classic').set(output=True)
|
||||||
self.vars.meta('channel').set(output=True)
|
self.vars.meta('channel').set(output=True)
|
||||||
actionable_snaps = [s for s in self.vars.name if self.is_snap_installed(s)]
|
actionable_snaps = [s for s in self.vars.name if not self.is_snap_installed(s)]
|
||||||
if not actionable_snaps:
|
if not actionable_snaps:
|
||||||
return
|
return
|
||||||
self.changed = True
|
self.changed = True
|
||||||
self.vars.snaps_installed = actionable_snaps
|
self.vars.snaps_installed = actionable_snaps
|
||||||
if self.module.check_mode:
|
if self.module.check_mode:
|
||||||
return
|
return
|
||||||
params = ['classic', 'channel', 'state'] # get base cmd parts
|
params = ['state', 'classic', 'channel'] # get base cmd parts
|
||||||
has_one_pkg_params = bool(self.vars.classic) or self.vars.channel != 'stable'
|
has_one_pkg_params = bool(self.vars.classic) or self.vars.channel != 'stable'
|
||||||
has_multiple_snaps = len(actionable_snaps) > 1
|
has_multiple_snaps = len(actionable_snaps) > 1
|
||||||
if has_one_pkg_params and has_multiple_snaps:
|
if has_one_pkg_params and has_multiple_snaps:
|
||||||
commands = [params + [s] for s in actionable_snaps]
|
commands = [params + [{'actionable_snaps': [s]}] for s in actionable_snaps]
|
||||||
else:
|
else:
|
||||||
commands = [params + actionable_snaps]
|
commands = [params + [{'actionable_snaps': actionable_snaps}]]
|
||||||
self.vars.cmd, rc, out, err = self._run_multiple_commands(commands)
|
self.vars.cmd, rc, out, err = self._run_multiple_commands(commands)
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
return
|
return
|
||||||
@@ -227,7 +229,7 @@ class Snap(CmdStateModuleHelper):
|
|||||||
|
|
||||||
def state_absent(self):
|
def state_absent(self):
|
||||||
self.validate_input_snaps() # if snap doesnt exist, it will be absent by definition
|
self.validate_input_snaps() # if snap doesnt exist, it will be absent by definition
|
||||||
actionable_snaps = [s for s in self.vars.name if not self.is_snap_installed(s)]
|
actionable_snaps = [s for s in self.vars.name if self.is_snap_installed(s)]
|
||||||
if not actionable_snaps:
|
if not actionable_snaps:
|
||||||
return
|
return
|
||||||
self.changed = True
|
self.changed = True
|
||||||
@@ -235,7 +237,7 @@ class Snap(CmdStateModuleHelper):
|
|||||||
if self.module.check_mode:
|
if self.module.check_mode:
|
||||||
return
|
return
|
||||||
params = ['classic', 'channel', 'state'] # get base cmd parts
|
params = ['classic', 'channel', 'state'] # get base cmd parts
|
||||||
commands = [params + actionable_snaps]
|
commands = [params + [{'actionable_snaps': actionable_snaps}]]
|
||||||
self.vars.cmd, rc, out, err = self._run_multiple_commands(commands)
|
self.vars.cmd, rc, out, err = self._run_multiple_commands(commands)
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
return
|
return
|
||||||
@@ -253,7 +255,7 @@ class Snap(CmdStateModuleHelper):
|
|||||||
if self.module.check_mode:
|
if self.module.check_mode:
|
||||||
return
|
return
|
||||||
params = ['classic', 'channel', 'state'] # get base cmd parts
|
params = ['classic', 'channel', 'state'] # get base cmd parts
|
||||||
commands = [params + actionable_snaps]
|
commands = [params + [{'actionable_snaps': actionable_snaps}]]
|
||||||
self.vars.cmd, rc, out, err = self._run_multiple_commands(commands)
|
self.vars.cmd, rc, out, err = self._run_multiple_commands(commands)
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
return
|
return
|
||||||
@@ -271,7 +273,7 @@ class Snap(CmdStateModuleHelper):
|
|||||||
if self.module.check_mode:
|
if self.module.check_mode:
|
||||||
return
|
return
|
||||||
params = ['classic', 'channel', 'state'] # get base cmd parts
|
params = ['classic', 'channel', 'state'] # get base cmd parts
|
||||||
commands = [params + actionable_snaps]
|
commands = [params + [{'actionable_snaps': actionable_snaps}]]
|
||||||
self.vars.cmd, rc, out, err = self._run_multiple_commands(commands)
|
self.vars.cmd, rc, out, err = self._run_multiple_commands(commands)
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -471,9 +471,9 @@ def main():
|
|||||||
if size_opt == 'l':
|
if size_opt == 'l':
|
||||||
module.fail_json(changed=False, msg="Thin volume sizing with percentage not supported.")
|
module.fail_json(changed=False, msg="Thin volume sizing with percentage not supported.")
|
||||||
size_opt = 'V'
|
size_opt = 'V'
|
||||||
cmd = "%s %s -n %s -%s %s%s %s -T %s/%s" % (lvcreate_cmd, yesopt, lv, size_opt, size, size_unit, opts, vg, thinpool)
|
cmd = "%s %s %s -n %s -%s %s%s %s -T %s/%s" % (lvcreate_cmd, test_opt, yesopt, lv, size_opt, size, size_unit, opts, vg, thinpool)
|
||||||
elif thinpool and not lv:
|
elif thinpool and not lv:
|
||||||
cmd = "%s %s -%s %s%s %s -T %s/%s" % (lvcreate_cmd, yesopt, size_opt, size, size_unit, opts, vg, thinpool)
|
cmd = "%s %s %s -%s %s%s %s -T %s/%s" % (lvcreate_cmd, test_opt, yesopt, size_opt, size, size_unit, opts, vg, thinpool)
|
||||||
else:
|
else:
|
||||||
cmd = "%s %s %s -n %s -%s %s%s %s %s %s" % (lvcreate_cmd, test_opt, yesopt, lv, size_opt, size, size_unit, opts, vg, pvs)
|
cmd = "%s %s %s -n %s -%s %s%s %s %s %s" % (lvcreate_cmd, test_opt, yesopt, lv, size_opt, size, size_unit, opts, vg, pvs)
|
||||||
rc, dummy, err = module.run_command(cmd)
|
rc, dummy, err = module.run_command(cmd)
|
||||||
|
|||||||
@@ -148,7 +148,39 @@
|
|||||||
- name: verify that excluded sub file is still present
|
- name: verify that excluded sub file is still present
|
||||||
file: path={{ output_dir }}/tmpdir/sub/subfile.txt state=file
|
file: path={{ output_dir }}/tmpdir/sub/subfile.txt state=file
|
||||||
|
|
||||||
- name: remove temporary directory
|
- name: prep our files in tmpdir again
|
||||||
|
copy: src={{ item }} dest={{ output_dir }}/tmpdir/{{ item }}
|
||||||
|
with_items:
|
||||||
|
- foo.txt
|
||||||
|
- bar.txt
|
||||||
|
- empty.txt
|
||||||
|
- sub
|
||||||
|
- sub/subfile.txt
|
||||||
|
|
||||||
|
- name: archive using gz and remove src directory
|
||||||
|
archive:
|
||||||
|
path:
|
||||||
|
- "{{ output_dir }}/tmpdir/"
|
||||||
|
dest: "{{ output_dir }}/archive_remove_05.gz"
|
||||||
|
format: gz
|
||||||
|
remove: yes
|
||||||
|
exclude_path: "{{ output_dir }}/tmpdir/sub/subfile.txt"
|
||||||
|
register: archive_remove_result_05
|
||||||
|
|
||||||
|
- name: verify that the files archived
|
||||||
|
file: path={{ output_dir }}/archive_remove_05.gz state=file
|
||||||
|
|
||||||
|
- name: Verify source files were removed
|
||||||
file:
|
file:
|
||||||
path: "{{ output_dir }}/tmpdir"
|
path: "{{ output_dir }}/tmpdir"
|
||||||
state: absent
|
state: absent
|
||||||
|
register: archive_source_file_removal_05
|
||||||
|
|
||||||
|
- name: Verify that task status is success
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- archive_remove_result_05 is success
|
||||||
|
- archive_source_file_removal_05 is not changed
|
||||||
|
|
||||||
|
- name: remove our gz
|
||||||
|
file: path="{{ output_dir }}/archive_remove_05.gz" state=absent
|
||||||
|
|||||||
6
tests/integration/targets/snap/aliases
Normal file
6
tests/integration/targets/snap/aliases
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
shippable/posix/group1
|
||||||
|
skip/aix
|
||||||
|
skip/freebsd
|
||||||
|
skip/osx
|
||||||
|
skip/macos
|
||||||
|
skip/docker
|
||||||
4
tests/integration/targets/snap/defaults/main.yml
Normal file
4
tests/integration/targets/snap/defaults/main.yml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
has_snap: false
|
||||||
|
|
||||||
|
snap_packages:
|
||||||
|
- snapd
|
||||||
5
tests/integration/targets/snap/handlers/main.yml
Normal file
5
tests/integration/targets/snap/handlers/main.yml
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
- name: Remove snapd
|
||||||
|
package:
|
||||||
|
name: "{{ snap_packages }}"
|
||||||
|
state: absent
|
||||||
3
tests/integration/targets/snap/meta/main.yml
Normal file
3
tests/integration/targets/snap/meta/main.yml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
dependencies:
|
||||||
|
- setup_pkg_mgr
|
||||||
|
- setup_epel
|
||||||
1
tests/integration/targets/snap/tasks/Debian.yml
Symbolic link
1
tests/integration/targets/snap/tasks/Debian.yml
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
default.yml
|
||||||
1
tests/integration/targets/snap/tasks/Fedora.yml
Symbolic link
1
tests/integration/targets/snap/tasks/Fedora.yml
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
default.yml
|
||||||
1
tests/integration/targets/snap/tasks/RedHat.yml
Symbolic link
1
tests/integration/targets/snap/tasks/RedHat.yml
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
default.yml
|
||||||
21
tests/integration/targets/snap/tasks/default.yml
Normal file
21
tests/integration/targets/snap/tasks/default.yml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
- name: Install snapd
|
||||||
|
package:
|
||||||
|
name: "{{ snap_packages }}"
|
||||||
|
state: present
|
||||||
|
notify: Remove snapd
|
||||||
|
|
||||||
|
- name: Make sure that snapd is running
|
||||||
|
service:
|
||||||
|
name: snapd
|
||||||
|
state: started
|
||||||
|
|
||||||
|
- name: Create link /snap
|
||||||
|
file:
|
||||||
|
src: /var/lib/snapd/snap
|
||||||
|
dest: /snap
|
||||||
|
state: link
|
||||||
|
|
||||||
|
- name: Inform that snap is installed
|
||||||
|
set_fact:
|
||||||
|
has_snap: true
|
||||||
145
tests/integration/targets/snap/tasks/main.yml
Normal file
145
tests/integration/targets/snap/tasks/main.yml
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
---
|
||||||
|
####################################################################
|
||||||
|
# WARNING: These are designed specifically for Ansible tests #
|
||||||
|
# and should not be used as examples of how to write Ansible roles #
|
||||||
|
####################################################################
|
||||||
|
|
||||||
|
- name: Include distribution specific tasks
|
||||||
|
include_tasks: "{{ lookup('first_found', params) }}"
|
||||||
|
vars:
|
||||||
|
params:
|
||||||
|
files:
|
||||||
|
- "{{ ansible_facts.distribution }}-{{ ansible_facts.distribution_major_version }}.yml"
|
||||||
|
- "{{ ansible_facts.os_family }}-{{ ansible_facts.distribution_major_version }}.yml"
|
||||||
|
- "{{ ansible_facts.distribution }}.yml"
|
||||||
|
- "{{ ansible_facts.os_family }}.yml"
|
||||||
|
- "nothing.yml"
|
||||||
|
paths:
|
||||||
|
- "{{ role_path }}/tasks"
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- name: Make sure package is not installed
|
||||||
|
community.general.snap:
|
||||||
|
name: hello-world
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Install package (check mode)
|
||||||
|
community.general.snap:
|
||||||
|
name: hello-world
|
||||||
|
state: present
|
||||||
|
register: install_check
|
||||||
|
check_mode: true
|
||||||
|
|
||||||
|
- name: Install package
|
||||||
|
community.general.snap:
|
||||||
|
name: hello-world
|
||||||
|
state: present
|
||||||
|
register: install
|
||||||
|
|
||||||
|
- name: Install package again (check mode)
|
||||||
|
community.general.snap:
|
||||||
|
name: hello-world
|
||||||
|
state: present
|
||||||
|
register: install_again_check
|
||||||
|
check_mode: true
|
||||||
|
|
||||||
|
- name: Install package again
|
||||||
|
community.general.snap:
|
||||||
|
name: hello-world
|
||||||
|
state: present
|
||||||
|
register: install_again
|
||||||
|
|
||||||
|
- name: Assert package has been installed just once
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- install is changed
|
||||||
|
- install_check is changed
|
||||||
|
- install_again is not changed
|
||||||
|
- install_again_check is not changed
|
||||||
|
|
||||||
|
- name: Check package has been installed correctly
|
||||||
|
command: hello-world
|
||||||
|
environment:
|
||||||
|
PATH: /var/lib/snapd/snap/bin/
|
||||||
|
|
||||||
|
- name: Remove package (check mode)
|
||||||
|
community.general.snap:
|
||||||
|
name: hello-world
|
||||||
|
state: absent
|
||||||
|
register: remove_check
|
||||||
|
check_mode: true
|
||||||
|
|
||||||
|
- name: Remove package
|
||||||
|
community.general.snap:
|
||||||
|
name: hello-world
|
||||||
|
state: absent
|
||||||
|
register: remove
|
||||||
|
|
||||||
|
- name: Remove package again (check mode)
|
||||||
|
community.general.snap:
|
||||||
|
name: hello-world
|
||||||
|
state: absent
|
||||||
|
register: remove_again_check
|
||||||
|
check_mode: true
|
||||||
|
|
||||||
|
- name: Remove package again
|
||||||
|
community.general.snap:
|
||||||
|
name: hello-world
|
||||||
|
state: absent
|
||||||
|
register: remove_again
|
||||||
|
|
||||||
|
- name: Assert package has been removed just once
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- remove is changed
|
||||||
|
- remove_check is changed
|
||||||
|
- remove_again is not changed
|
||||||
|
- remove_again_check is not changed
|
||||||
|
|
||||||
|
- name: Make sure package from classic snap is not installed
|
||||||
|
community.general.snap:
|
||||||
|
name: nvim
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Install package from classic snap
|
||||||
|
community.general.snap:
|
||||||
|
name: nvim
|
||||||
|
state: present
|
||||||
|
classic: true
|
||||||
|
register: classic_install
|
||||||
|
|
||||||
|
# testing classic idempotency
|
||||||
|
- name: Install package from classic snap again
|
||||||
|
community.general.snap:
|
||||||
|
name: nvim
|
||||||
|
state: present
|
||||||
|
classic: true
|
||||||
|
register: classic_install_again
|
||||||
|
|
||||||
|
- name: Assert package has been installed just once
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- classic_install is changed
|
||||||
|
- classic_install_again is not changed
|
||||||
|
|
||||||
|
# this is just testing if a package which has been installed
|
||||||
|
# with true classic can be removed without setting classic to true
|
||||||
|
- name: Remove package from classic snap without setting classic to true
|
||||||
|
community.general.snap:
|
||||||
|
name: nvim
|
||||||
|
state: absent
|
||||||
|
register: classic_remove_without_true_classic
|
||||||
|
|
||||||
|
- name: Remove package from classic snap with setting classic to true
|
||||||
|
community.general.snap:
|
||||||
|
name: nvim
|
||||||
|
state: absent
|
||||||
|
classic: true
|
||||||
|
register: classic_remove_with_true_classic
|
||||||
|
|
||||||
|
- name: Assert package has been removed without setting classic to true
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- classic_remove_without_true_classic is changed
|
||||||
|
- classic_remove_with_true_classic is not changed
|
||||||
|
when: has_snap
|
||||||
2
tests/integration/targets/snap/tasks/nothing.yml
Normal file
2
tests/integration/targets/snap/tasks/nothing.yml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
# Do nothing
|
||||||
@@ -151,17 +151,45 @@ def test_vardict():
|
|||||||
assert vd.meta('a').diff is False
|
assert vd.meta('a').diff is False
|
||||||
assert vd.meta('a').change is False
|
assert vd.meta('a').change is False
|
||||||
vd['b'] = 456
|
vd['b'] = 456
|
||||||
|
assert vd.meta('b').output is True
|
||||||
|
assert vd.meta('b').diff is False
|
||||||
|
assert vd.meta('b').change is False
|
||||||
vd.set_meta('a', diff=True, change=True)
|
vd.set_meta('a', diff=True, change=True)
|
||||||
vd.set_meta('b', diff=True, output=False)
|
vd.set_meta('b', diff=True, output=False)
|
||||||
vd['c'] = 789
|
vd['c'] = 789
|
||||||
|
assert vd.has_changed('c') is False
|
||||||
vd['a'] = 'new_a'
|
vd['a'] = 'new_a'
|
||||||
|
assert vd.has_changed('a') is True
|
||||||
vd['c'] = 'new_c'
|
vd['c'] = 'new_c'
|
||||||
|
assert vd.has_changed('c') is False
|
||||||
|
vd['b'] = 'new_b'
|
||||||
|
assert vd.has_changed('b') is False
|
||||||
assert vd.a == 'new_a'
|
assert vd.a == 'new_a'
|
||||||
assert vd.c == 'new_c'
|
assert vd.c == 'new_c'
|
||||||
assert vd.output() == {'a': 'new_a', 'c': 'new_c'}
|
assert vd.output() == {'a': 'new_a', 'c': 'new_c'}
|
||||||
assert vd.diff() == {'before': {'a': 123}, 'after': {'a': 'new_a'}}, "diff={0}".format(vd.diff())
|
assert vd.diff() == {'before': {'a': 123}, 'after': {'a': 'new_a'}}, "diff={0}".format(vd.diff())
|
||||||
|
|
||||||
|
|
||||||
|
def test_variable_meta_change():
|
||||||
|
vd = VarDict()
|
||||||
|
vd.set('a', 123, change=True)
|
||||||
|
vd.set('b', [4, 5, 6], change=True)
|
||||||
|
vd.set('c', {'m': 7, 'n': 8, 'o': 9}, change=True)
|
||||||
|
vd.set('d', {'a1': {'a11': 33, 'a12': 34}}, change=True)
|
||||||
|
|
||||||
|
vd.a = 1234
|
||||||
|
assert vd.has_changed('a') is True
|
||||||
|
vd.b.append(7)
|
||||||
|
assert vd.b == [4, 5, 6, 7]
|
||||||
|
assert vd.has_changed('b')
|
||||||
|
vd.c.update({'p': 10})
|
||||||
|
assert vd.c == {'m': 7, 'n': 8, 'o': 9, 'p': 10}
|
||||||
|
assert vd.has_changed('c')
|
||||||
|
vd.d['a1'].update({'a13': 35})
|
||||||
|
assert vd.d == {'a1': {'a11': 33, 'a12': 34, 'a13': 35}}
|
||||||
|
assert vd.has_changed('d')
|
||||||
|
|
||||||
|
|
||||||
class MockMH(object):
|
class MockMH(object):
|
||||||
changed = None
|
changed = None
|
||||||
|
|
||||||
|
|||||||
@@ -343,7 +343,7 @@ class TestKeycloakAuthentication(ModuleTestCase):
|
|||||||
self.assertEqual(len(mock_get_authentication_flow_by_alias.mock_calls), 1)
|
self.assertEqual(len(mock_get_authentication_flow_by_alias.mock_calls), 1)
|
||||||
self.assertEqual(len(mock_copy_auth_flow.mock_calls), 0)
|
self.assertEqual(len(mock_copy_auth_flow.mock_calls), 0)
|
||||||
self.assertEqual(len(mock_create_empty_auth_flow.mock_calls), 1)
|
self.assertEqual(len(mock_create_empty_auth_flow.mock_calls), 1)
|
||||||
self.assertEqual(len(mock_get_executions_representation.mock_calls), 3)
|
self.assertEqual(len(mock_get_executions_representation.mock_calls), 2)
|
||||||
self.assertEqual(len(mock_delete_authentication_flow_by_id.mock_calls), 0)
|
self.assertEqual(len(mock_delete_authentication_flow_by_id.mock_calls), 0)
|
||||||
|
|
||||||
# Verify that the module's changed status matches what is expected
|
# Verify that the module's changed status matches what is expected
|
||||||
@@ -434,7 +434,7 @@ class TestKeycloakAuthentication(ModuleTestCase):
|
|||||||
self.assertEqual(len(mock_get_authentication_flow_by_alias.mock_calls), 1)
|
self.assertEqual(len(mock_get_authentication_flow_by_alias.mock_calls), 1)
|
||||||
self.assertEqual(len(mock_copy_auth_flow.mock_calls), 0)
|
self.assertEqual(len(mock_copy_auth_flow.mock_calls), 0)
|
||||||
self.assertEqual(len(mock_create_empty_auth_flow.mock_calls), 0)
|
self.assertEqual(len(mock_create_empty_auth_flow.mock_calls), 0)
|
||||||
self.assertEqual(len(mock_get_executions_representation.mock_calls), 3)
|
self.assertEqual(len(mock_get_executions_representation.mock_calls), 2)
|
||||||
self.assertEqual(len(mock_delete_authentication_flow_by_id.mock_calls), 0)
|
self.assertEqual(len(mock_delete_authentication_flow_by_id.mock_calls), 0)
|
||||||
|
|
||||||
# Verify that the module's changed status matches what is expected
|
# Verify that the module's changed status matches what is expected
|
||||||
@@ -611,7 +611,7 @@ class TestKeycloakAuthentication(ModuleTestCase):
|
|||||||
self.assertEqual(len(mock_get_authentication_flow_by_alias.mock_calls), 1)
|
self.assertEqual(len(mock_get_authentication_flow_by_alias.mock_calls), 1)
|
||||||
self.assertEqual(len(mock_copy_auth_flow.mock_calls), 0)
|
self.assertEqual(len(mock_copy_auth_flow.mock_calls), 0)
|
||||||
self.assertEqual(len(mock_create_empty_auth_flow.mock_calls), 1)
|
self.assertEqual(len(mock_create_empty_auth_flow.mock_calls), 1)
|
||||||
self.assertEqual(len(mock_get_executions_representation.mock_calls), 3)
|
self.assertEqual(len(mock_get_executions_representation.mock_calls), 2)
|
||||||
self.assertEqual(len(mock_delete_authentication_flow_by_id.mock_calls), 1)
|
self.assertEqual(len(mock_delete_authentication_flow_by_id.mock_calls), 1)
|
||||||
|
|
||||||
# Verify that the module's changed status matches what is expected
|
# Verify that the module's changed status matches what is expected
|
||||||
|
|||||||
@@ -52,6 +52,25 @@ class NPMModuleTestCase(ModuleTestCase):
|
|||||||
call(['/testbin/npm', 'install', '--global', 'coffee-script'], check_rc=True, cwd=None),
|
call(['/testbin/npm', 'install', '--global', 'coffee-script'], check_rc=True, cwd=None),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
def test_present_missing(self):
|
||||||
|
set_module_args({
|
||||||
|
'name': 'coffee-script',
|
||||||
|
'global': 'true',
|
||||||
|
'state': 'present',
|
||||||
|
})
|
||||||
|
self.module_main_command.side_effect = [
|
||||||
|
(0, '{"dependencies": {"coffee-script": {"missing" : true}}}', ''),
|
||||||
|
(0, '{}', ''),
|
||||||
|
]
|
||||||
|
|
||||||
|
result = self.module_main(AnsibleExitJson)
|
||||||
|
|
||||||
|
self.assertTrue(result['changed'])
|
||||||
|
self.module_main_command.assert_has_calls([
|
||||||
|
call(['/testbin/npm', 'list', '--json', '--long', '--global'], check_rc=False, cwd=None),
|
||||||
|
call(['/testbin/npm', 'install', '--global', 'coffee-script'], check_rc=True, cwd=None),
|
||||||
|
])
|
||||||
|
|
||||||
def test_present_version(self):
|
def test_present_version(self):
|
||||||
set_module_args({
|
set_module_args({
|
||||||
'name': 'coffee-script',
|
'name': 'coffee-script',
|
||||||
|
|||||||
Reference in New Issue
Block a user