summaryrefslogtreecommitdiffstats
path: root/ansible_collections/community/general/plugins/module_utils/mh/mixins/vars.py
blob: 91f4e4a189d5a2d2b82420e081d562b02daf9868 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# -*- coding: utf-8 -*-
# (c) 2020, Alexei Znamensky <russoz@gmail.com>
# Copyright (c) 2020, Ansible Project
# Simplified BSD License (see LICENSES/BSD-2-Clause.txt or https://opensource.org/licenses/BSD-2-Clause)
# SPDX-License-Identifier: BSD-2-Clause

from __future__ import absolute_import, division, print_function
__metaclass__ = type

import copy


class VarMeta(object):
    """
    DEPRECATION WARNING

    This class is deprecated and will be removed in community.general 10.0.0
    Modules should use the VarDict from plugins/module_utils/vardict.py instead.
    """

    NOTHING = object()

    def __init__(self, diff=False, output=True, change=None, fact=False):
        self.init = False
        self.initial_value = None
        self.value = None

        self.diff = diff
        self.change = diff if change is None else change
        self.output = output
        self.fact = fact

    def set(self, diff=None, output=None, change=None, fact=None, initial_value=NOTHING):
        if diff is not None:
            self.diff = diff
        if output is not None:
            self.output = output
        if change is not None:
            self.change = change
        if fact is not None:
            self.fact = fact
        if initial_value is not self.NOTHING:
            self.initial_value = copy.deepcopy(initial_value)

    def set_value(self, value):
        if not self.init:
            self.initial_value = copy.deepcopy(value)
            self.init = True
        self.value = value
        return self

    @property
    def has_changed(self):
        return self.change and (self.initial_value != self.value)

    @property
    def diff_result(self):
        return None if not (self.diff and self.has_changed) else {
            'before': self.initial_value,
            'after': self.value,
        }

    def __str__(self):
        return "<VarMeta: value={0}, initial={1}, diff={2}, output={3}, change={4}>".format(
            self.value, self.initial_value, self.diff, self.output, self.change
        )


class VarDict(object):
    """
    DEPRECATION WARNING

    This class is deprecated and will be removed in community.general 10.0.0
    Modules should use the VarDict from plugins/module_utils/vardict.py instead.
    """
    def __init__(self):
        self._data = dict()
        self._meta = dict()

    def __getitem__(self, item):
        return self._data[item]

    def __setitem__(self, key, value):
        self.set(key, value)

    def __getattr__(self, item):
        try:
            return self._data[item]
        except KeyError:
            return getattr(self._data, item)

    def __setattr__(self, key, value):
        if key in ('_data', '_meta'):
            super(VarDict, self).__setattr__(key, value)
        else:
            self.set(key, value)

    def meta(self, name):
        return self._meta[name]

    def set_meta(self, name, **kwargs):
        self.meta(name).set(**kwargs)

    def set(self, name, value, **kwargs):
        if name in ('_data', '_meta'):
            raise ValueError("Names _data and _meta are reserved for use by ModuleHelper")
        self._data[name] = value
        if name in self._meta:
            meta = self.meta(name)
        else:
            meta = VarMeta(**kwargs)
        meta.set_value(value)
        self._meta[name] = meta

    def output(self):
        return dict((k, v) for k, v in self._data.items() if self.meta(k).output)

    def diff(self):
        diff_results = [(k, self.meta(k).diff_result) for k in self._data]
        diff_results = [dr for dr in diff_results if dr[1] is not None]
        if diff_results:
            before = dict((dr[0], dr[1]['before']) for dr in diff_results)
            after = dict((dr[0], dr[1]['after']) for dr in diff_results)
            return {'before': before, 'after': after}
        return None

    def facts(self):
        facts_result = dict((k, v) for k, v in self._data.items() if self._meta[k].fact)
        return facts_result if facts_result else None

    def change_vars(self):
        return [v for v in self._data if self.meta(v).change]

    def has_changed(self, v):
        return self._meta[v].has_changed


class VarsMixin(object):
    """
    DEPRECATION WARNING

    This class is deprecated and will be removed in community.general 10.0.0
    Modules should use the VarDict from plugins/module_utils/vardict.py instead.
    """
    def __init__(self, module=None):
        self.vars = VarDict()
        super(VarsMixin, self).__init__(module)

    def update_vars(self, meta=None, **kwargs):
        if meta is None:
            meta = {}
        for k, v in kwargs.items():
            self.vars.set(k, v, **meta)