mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-04-28 17:36:49 +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.
|
||||
|
||||
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
|
||||
======
|
||||
|
||||
|
||||
@@ -1392,3 +1392,42 @@ releases:
|
||||
name: keycloak_authentication
|
||||
namespace: identity.keycloak
|
||||
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
|
||||
name: general
|
||||
version: 3.3.0
|
||||
version: 3.3.2
|
||||
readme: README.md
|
||||
authors:
|
||||
- Ansible (https://github.com/ansible)
|
||||
|
||||
@@ -59,4 +59,7 @@ class ModuleHelperBase(object):
|
||||
self.__init_module__()
|
||||
self.__run__()
|
||||
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
|
||||
__metaclass__ = type
|
||||
|
||||
import copy
|
||||
|
||||
|
||||
class VarMeta(object):
|
||||
NOTHING = object()
|
||||
@@ -30,11 +32,11 @@ class VarMeta(object):
|
||||
if fact is not None:
|
||||
self.fact = fact
|
||||
if initial_value is not self.NOTHING:
|
||||
self.initial_value = initial_value
|
||||
self.initial_value = copy.deepcopy(initial_value)
|
||||
|
||||
def set_value(self, value):
|
||||
if not self.init:
|
||||
self.initial_value = value
|
||||
self.initial_value = copy.deepcopy(value)
|
||||
self.init = True
|
||||
self.value = value
|
||||
return self
|
||||
|
||||
@@ -399,13 +399,14 @@ class Archive(object):
|
||||
|
||||
def remove_targets(self):
|
||||
for path in self.successes:
|
||||
try:
|
||||
if os.path.isdir(path):
|
||||
shutil.rmtree(path)
|
||||
else:
|
||||
os.remove(path)
|
||||
except OSError:
|
||||
self.errors.append(_to_native(path))
|
||||
if os.path.exists(path):
|
||||
try:
|
||||
if os.path.isdir(path):
|
||||
shutil.rmtree(path)
|
||||
else:
|
||||
os.remove(path)
|
||||
except OSError:
|
||||
self.errors.append(_to_native(path))
|
||||
for path in self.paths:
|
||||
try:
|
||||
if os.path.isdir(path):
|
||||
|
||||
@@ -200,11 +200,11 @@ def create_or_update_executions(kc, config, realm='master'):
|
||||
try:
|
||||
changed = False
|
||||
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):
|
||||
if new_exec["index"] is not None:
|
||||
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
|
||||
# Get flowalias parent if given
|
||||
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
|
||||
if not is_struct_included(new_exec, existing_executions[exec_index], exclude_key) or exec_index != new_exec_index:
|
||||
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:
|
||||
kc.create_execution(new_exec, flowAlias=flow_alias_parent, realm=realm)
|
||||
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)
|
||||
changed = True
|
||||
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:
|
||||
# Update the existing execution
|
||||
updated_exec = {
|
||||
"id": existing_executions[exec_index]["id"]
|
||||
"id": id_to_update
|
||||
}
|
||||
# add the execution configuration
|
||||
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))
|
||||
if 'dependencies' in data:
|
||||
for dep, props in data['dependencies'].items():
|
||||
dep_version = dep + '@' + str(props['version'])
|
||||
|
||||
if 'missing' in props and props['missing']:
|
||||
missing.append(dep)
|
||||
@@ -224,7 +223,9 @@ class Npm(object):
|
||||
missing.append(dep)
|
||||
else:
|
||||
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:
|
||||
missing.append(self.name)
|
||||
# Named dependency not installed
|
||||
|
||||
@@ -254,16 +254,23 @@ def upgrade(module, pacman_path):
|
||||
# e.g., "ansible 2.7.1-1 -> 2.7.2-1"
|
||||
regex = re.compile(r'([\w+\-.@]+) (\S+-\S+) -> (\S+-\S+)')
|
||||
for p in data:
|
||||
m = regex.search(p)
|
||||
packages.append(m.group(1))
|
||||
if module._diff:
|
||||
diff['before'] += "%s-%s\n" % (m.group(1), m.group(2))
|
||||
diff['after'] += "%s-%s\n" % (m.group(1), m.group(3))
|
||||
if '[ignored]' not in p:
|
||||
m = regex.search(p)
|
||||
packages.append(m.group(1))
|
||||
if module._diff:
|
||||
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:
|
||||
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)
|
||||
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:
|
||||
module.fail_json(msg="Could not upgrade")
|
||||
else:
|
||||
|
||||
@@ -107,6 +107,8 @@ snaps_removed:
|
||||
|
||||
import re
|
||||
|
||||
from ansible.module_utils.common.text.converters import to_native
|
||||
|
||||
from ansible_collections.community.general.plugins.module_utils.module_helper import (
|
||||
CmdStateModuleHelper, ArgFormat, ModuleHelperException
|
||||
)
|
||||
@@ -123,7 +125,7 @@ __state_map = dict(
|
||||
|
||||
|
||||
def _state_map(value):
|
||||
return __state_map[value]
|
||||
return [__state_map[value]]
|
||||
|
||||
|
||||
class Snap(CmdStateModuleHelper):
|
||||
@@ -131,10 +133,10 @@ class Snap(CmdStateModuleHelper):
|
||||
module = dict(
|
||||
argument_spec={
|
||||
'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']),
|
||||
'classic': dict(type='bool', required=False, default=False),
|
||||
'channel': dict(type='str', required=False, default='stable'),
|
||||
'classic': dict(type='bool', default=False),
|
||||
'channel': dict(type='str', default='stable'),
|
||||
},
|
||||
supports_check_mode=True,
|
||||
)
|
||||
@@ -163,20 +165,20 @@ class Snap(CmdStateModuleHelper):
|
||||
results[i].append(output[i])
|
||||
|
||||
return [
|
||||
'; '.join(results[0]),
|
||||
'; '.join([to_native(x) for x in results[0]]),
|
||||
self._first_non_zero(results[1]),
|
||||
'\n'.join(results[2]),
|
||||
'\n'.join(results[3]),
|
||||
]
|
||||
|
||||
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):
|
||||
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):
|
||||
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:
|
||||
return None
|
||||
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.vars.meta('classic').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:
|
||||
return
|
||||
self.changed = True
|
||||
self.vars.snaps_installed = actionable_snaps
|
||||
if self.module.check_mode:
|
||||
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_multiple_snaps = len(actionable_snaps) > 1
|
||||
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:
|
||||
commands = [params + actionable_snaps]
|
||||
commands = [params + [{'actionable_snaps': actionable_snaps}]]
|
||||
self.vars.cmd, rc, out, err = self._run_multiple_commands(commands)
|
||||
if rc == 0:
|
||||
return
|
||||
@@ -227,7 +229,7 @@ class Snap(CmdStateModuleHelper):
|
||||
|
||||
def state_absent(self):
|
||||
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:
|
||||
return
|
||||
self.changed = True
|
||||
@@ -235,7 +237,7 @@ class Snap(CmdStateModuleHelper):
|
||||
if self.module.check_mode:
|
||||
return
|
||||
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)
|
||||
if rc == 0:
|
||||
return
|
||||
@@ -253,7 +255,7 @@ class Snap(CmdStateModuleHelper):
|
||||
if self.module.check_mode:
|
||||
return
|
||||
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)
|
||||
if rc == 0:
|
||||
return
|
||||
@@ -271,7 +273,7 @@ class Snap(CmdStateModuleHelper):
|
||||
if self.module.check_mode:
|
||||
return
|
||||
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)
|
||||
if rc == 0:
|
||||
return
|
||||
|
||||
@@ -471,9 +471,9 @@ def main():
|
||||
if size_opt == 'l':
|
||||
module.fail_json(changed=False, msg="Thin volume sizing with percentage not supported.")
|
||||
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:
|
||||
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:
|
||||
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)
|
||||
|
||||
@@ -148,7 +148,39 @@
|
||||
- name: verify that excluded sub file is still present
|
||||
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:
|
||||
path: "{{ output_dir }}/tmpdir"
|
||||
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').change is False
|
||||
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('b', diff=True, output=False)
|
||||
vd['c'] = 789
|
||||
assert vd.has_changed('c') is False
|
||||
vd['a'] = 'new_a'
|
||||
assert vd.has_changed('a') is True
|
||||
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.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())
|
||||
|
||||
|
||||
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):
|
||||
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_copy_auth_flow.mock_calls), 0)
|
||||
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)
|
||||
|
||||
# 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_copy_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)
|
||||
|
||||
# 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_copy_auth_flow.mock_calls), 0)
|
||||
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)
|
||||
|
||||
# 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),
|
||||
])
|
||||
|
||||
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):
|
||||
set_module_args({
|
||||
'name': 'coffee-script',
|
||||
|
||||
Reference in New Issue
Block a user