1"""
2NAPALM Users
3============
4
5Manages the configuration of the users on network devices.
6
7:codeauthor: Mircea Ulinic <ping@mirceaulinic.net>
8:maturity:   new
9:depends:    napalm
10:platform:   unix
11
12Dependencies
13------------
14- :mod:`NAPALM proxy minion <salt.proxy.napalm>`
15
16.. seealso::
17    :mod:`Users management state <salt.states.netusers>`
18
19.. versionadded:: 2016.11.0
20"""
21
22
23import logging
24
25# import NAPALM utils
26import salt.utils.napalm
27from salt.utils.napalm import proxy_napalm_wrap
28
29log = logging.getLogger(__file__)
30
31
32# ----------------------------------------------------------------------------------------------------------------------
33# module properties
34# ----------------------------------------------------------------------------------------------------------------------
35
36__virtualname__ = "users"
37__proxyenabled__ = ["napalm"]
38__virtual_aliases__ = ("napalm_users",)
39# uses NAPALM-based proxy to interact with network devices
40
41# ----------------------------------------------------------------------------------------------------------------------
42# property functions
43# ----------------------------------------------------------------------------------------------------------------------
44
45
46def __virtual__():
47    """
48    NAPALM library must be installed for this module to work and run in a (proxy) minion.
49    """
50    return salt.utils.napalm.virtual(__opts__, __virtualname__, __file__)
51
52
53# ----------------------------------------------------------------------------------------------------------------------
54# helper functions -- will not be exported
55# ----------------------------------------------------------------------------------------------------------------------
56
57# ----------------------------------------------------------------------------------------------------------------------
58# callable functions
59# ----------------------------------------------------------------------------------------------------------------------
60
61
62@proxy_napalm_wrap
63def config(**kwargs):  # pylint: disable=unused-argument
64
65    """
66    Returns the configuration of the users on the device
67
68    CLI Example:
69
70    .. code-block:: bash
71
72        salt '*' users.config
73
74    Output example:
75
76    .. code-block:: python
77
78        {
79            'mircea': {
80                'level': 15,
81                'password': '$1$0P70xKPa$4jt5/10cBTckk6I/w/',
82                'sshkeys': [
83                    'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC4pFn+shPwTb2yELO4L7NtQrKOJXNeCl1je\
84                    l9STXVaGnRAnuc2PXl35vnWmcUq6YbUEcgUTRzzXfmelJKuVJTJIlMXii7h2xkbQp0YZIEs4P\
85                    8ipwnRBAxFfk/ZcDsN3mjep4/yjN56ejk345jhk345jk345jk341p3A/9LIL7l6YewLBCwJj6\
86                    D+fWSJ0/YW+7oH17Fk2HH+tw0L5PcWLHkwA4t60iXn16qDbIk/ze6jv2hDGdCdz7oYQeCE55C\
87                    CHOHMJWYfN3jcL4s0qv8/u6Ka1FVkV7iMmro7ChThoV/5snI4Ljf2wKqgHH7TfNaCfpU0WvHA\
88                    nTs8zhOrGScSrtb mircea@master-roshi'
89                ]
90            }
91        }
92    """
93
94    return salt.utils.napalm.call(
95        napalm_device, "get_users", **{}  # pylint: disable=undefined-variable
96    )
97
98
99@proxy_napalm_wrap
100def set_users(
101    users, test=False, commit=True, **kwargs
102):  # pylint: disable=unused-argument
103
104    """
105    Configures users on network devices.
106
107    :param users: Dictionary formatted as the output of the function config()
108
109    :param test: Dry run? If set as True, will apply the config, discard and
110        return the changes. Default: False
111
112    :param commit: Commit? (default: True) Sometimes it is not needed to commit
113        the config immediately after loading the changes. E.g.: a state loads a
114        couple of parts (add / remove / update) and would not be optimal to
115        commit after each operation.  Also, from the CLI when the user needs to
116        apply the similar changes before committing, can specify commit=False
117        and will not discard the config.
118
119    :raise MergeConfigException: If there is an error on the configuration sent.
120    :return a dictionary having the following keys:
121
122    - result (bool): if the config was applied successfully. It is `False` only
123      in case of failure. In case there are no changes to be applied and
124      successfully performs all operations it is still `True` and so will be
125      the `already_configured` flag (example below)
126    - comment (str): a message for the user
127    - already_configured (bool): flag to check if there were no changes applied
128    - diff (str): returns the config changes applied
129
130    CLI Example:
131
132    .. code-block:: bash
133
134        salt '*' users.set_users "{'mircea': {}}"
135    """
136
137    # pylint: disable=undefined-variable
138    return __salt__["net.load_template"](
139        "set_users",
140        users=users,
141        test=test,
142        commit=commit,
143        inherit_napalm_device=napalm_device,
144    )
145    # pylint: enable=undefined-variable
146
147
148@proxy_napalm_wrap
149def delete_users(
150    users, test=False, commit=True, **kwargs
151):  # pylint: disable=unused-argument
152
153    """
154    Removes users from the configuration of network devices.
155
156    :param users: Dictionary formatted as the output of the function config()
157    :param test: Dry run? If set as True, will apply the config, discard and return the changes. Default: False
158    :param commit: Commit? (default: True) Sometimes it is not needed to commit the config immediately
159        after loading the changes. E.g.: a state loads a couple of parts (add / remove / update)
160        and would not be optimal to commit after each operation.
161        Also, from the CLI when the user needs to apply the similar changes before committing,
162        can specify commit=False and will not discard the config.
163    :raise MergeConfigException: If there is an error on the configuration sent.
164    :return a dictionary having the following keys:
165        - result (bool): if the config was applied successfully. It is `False`
166          only in case of failure. In case there are no changes to be applied
167          and successfully performs all operations it is still `True` and so
168          will be the `already_configured` flag (example below)
169        - comment (str): a message for the user
170        - already_configured (bool): flag to check if there were no changes applied
171        - diff (str): returns the config changes applied
172
173    CLI Example:
174
175    .. code-block:: bash
176
177        salt '*' users.delete_users "{'mircea': {}}"
178    """
179
180    # pylint: disable=undefined-variable
181    return __salt__["net.load_template"](
182        "delete_users",
183        users=users,
184        test=test,
185        commit=commit,
186        inherit_napalm_device=napalm_device,
187    )
188    # pylint: enable=undefined-variable
189