1"""
2Directly manage the Salt fileserver plugins
3"""
4
5import salt.fileserver
6
7
8def envs(backend=None, sources=False):
9    """
10    Return the available fileserver environments. If no backend is provided,
11    then the environments for all configured backends will be returned.
12
13    backend
14        Narrow fileserver backends to a subset of the enabled ones.
15
16        .. versionchanged:: 2015.5.0
17            If all passed backends start with a minus sign (``-``), then these
18            backends will be excluded from the enabled backends. However, if
19            there is a mix of backends with and without a minus sign (ex:
20            ``backend=-roots,git``) then the ones starting with a minus
21            sign will be disregarded.
22
23            Additionally, fileserver backends can now be passed as a
24            comma-separated list. In earlier versions, they needed to be passed
25            as a python list (ex: ``backend="['roots', 'git']"``)
26
27    CLI Example:
28
29    .. code-block:: bash
30
31        salt-run fileserver.envs
32        salt-run fileserver.envs backend=roots,git
33        salt-run fileserver.envs git
34    """
35    fileserver = salt.fileserver.Fileserver(__opts__)
36    return sorted(fileserver.envs(back=backend, sources=sources))
37
38
39def clear_file_list_cache(saltenv=None, backend=None):
40    """
41    .. versionadded:: 2016.11.0
42
43    The Salt fileserver caches the files/directories/symlinks for each
44    fileserver backend and environment as they are requested. This is done to
45    help the fileserver scale better. Without this caching, when
46    hundreds/thousands of minions simultaneously ask the master what files are
47    available, this would cause the master's CPU load to spike as it obtains
48    the same information separately for each minion.
49
50    saltenv
51        By default, this runner will clear the file list caches for all
52        environments. This argument allows for a list of environments to be
53        passed, to clear more selectively. This list can be passed either as a
54        comma-separated string, or a Python list.
55
56    backend
57        Similar to the ``saltenv`` parameter, this argument will restrict the
58        cache clearing to specific fileserver backends (the default behavior is
59        to clear from all enabled fileserver backends). This list can be passed
60        either as a comma-separated string, or a Python list.
61
62    .. note:
63        The maximum age for the cached file lists (i.e. the age at which the
64        cache will be disregarded and rebuilt) is defined by the
65        :conf_master:`fileserver_list_cache_time` configuration parameter.
66
67    Since the ability to clear these caches is often required by users writing
68    custom runners which add/remove files, this runner can easily be called
69    from within a custom runner using any of the following examples:
70
71    .. code-block:: python
72
73        # Clear all file list caches
74        __salt__['fileserver.clear_file_list_cache']()
75        # Clear just the 'base' saltenv file list caches
76        __salt__['fileserver.clear_file_list_cache'](saltenv='base')
77        # Clear just the 'base' saltenv file list caches from just the 'roots'
78        # fileserver backend
79        __salt__['fileserver.clear_file_list_cache'](saltenv='base', backend='roots')
80        # Clear all file list caches from the 'roots' fileserver backend
81        __salt__['fileserver.clear_file_list_cache'](backend='roots')
82
83    .. note::
84        In runners, the ``__salt__`` dictionary will likely be renamed to
85        ``__runner__`` in a future Salt release to distinguish runner functions
86        from remote execution functions. See `this GitHub issue`_ for
87        discussion/updates on this.
88
89    .. _`this GitHub issue`: https://github.com/saltstack/salt/issues/34958
90
91    If using Salt's Python API (not a runner), the following examples are
92    equivalent to the ones above:
93
94    .. code-block:: python
95
96        import salt.config
97        import salt.runner
98
99        opts = salt.config.master_config('/etc/salt/master')
100        opts['fun'] = 'fileserver.clear_file_list_cache'
101
102        # Clear all file list_caches
103        opts['arg'] = []  # No arguments
104        runner = salt.runner.Runner(opts)
105        cleared = runner.run()
106
107        # Clear just the 'base' saltenv file list caches
108        opts['arg'] = ['base', None]
109        runner = salt.runner.Runner(opts)
110        cleared = runner.run()
111
112        # Clear just the 'base' saltenv file list caches from just the 'roots'
113        # fileserver backend
114        opts['arg'] = ['base', 'roots']
115        runner = salt.runner.Runner(opts)
116        cleared = runner.run()
117
118        # Clear all file list caches from the 'roots' fileserver backend
119        opts['arg'] = [None, 'roots']
120        runner = salt.runner.Runner(opts)
121        cleared = runner.run()
122
123
124    This function will return a dictionary showing a list of environments which
125    were cleared for each backend. An empty return dictionary means that no
126    changes were made.
127
128    CLI Examples:
129
130    .. code-block:: bash
131
132        # Clear all file list caches
133        salt-run fileserver.clear_file_list_cache
134        # Clear just the 'base' saltenv file list caches
135        salt-run fileserver.clear_file_list_cache saltenv=base
136        # Clear just the 'base' saltenv file list caches from just the 'roots'
137        # fileserver backend
138        salt-run fileserver.clear_file_list_cache saltenv=base backend=roots
139        # Clear all file list caches from the 'roots' fileserver backend
140        salt-run fileserver.clear_file_list_cache backend=roots
141    """
142    fileserver = salt.fileserver.Fileserver(__opts__)
143    load = {"saltenv": saltenv, "fsbackend": backend}
144    return fileserver.clear_file_list_cache(load=load)
145
146
147def file_list(saltenv="base", backend=None):
148    """
149    Return a list of files from the salt fileserver
150
151    saltenv : base
152        The salt fileserver environment to be listed
153
154    backend
155        Narrow fileserver backends to a subset of the enabled ones. If all
156        passed backends start with a minus sign (``-``), then these backends
157        will be excluded from the enabled backends. However, if there is a mix
158        of backends with and without a minus sign (ex:
159        ``backend=-roots,git``) then the ones starting with a minus sign will
160        be disregarded.
161
162        .. versionadded:: 2015.5.0
163
164    .. note:
165        Keep in mind that executing this function spawns a new process,
166        separate from the master. This means that if the fileserver
167        configuration has been changed in some way since the master has been
168        restarted (e.g. if :conf_master:`fileserver_backend`,
169        :conf_master:`gitfs_remotes`, :conf_master:`hgfs_remotes`, etc. have
170        been updated), then the results of this runner will not accurately
171        reflect what files are available to minions.
172
173        When in doubt, use :py:func:`cp.list_master
174        <salt.modules.cp.list_master>` to see what files the minion can see,
175        and always remember to restart the salt-master daemon when updating
176        the fileserver configuration.
177
178    CLI Examples:
179
180    .. code-block:: bash
181
182        salt-run fileserver.file_list
183        salt-run fileserver.file_list saltenv=prod
184        salt-run fileserver.file_list saltenv=dev backend=git
185        salt-run fileserver.file_list base hg,roots
186        salt-run fileserver.file_list -git
187    """
188    fileserver = salt.fileserver.Fileserver(__opts__)
189    load = {"saltenv": saltenv, "fsbackend": backend}
190    return fileserver.file_list(load=load)
191
192
193def symlink_list(saltenv="base", backend=None):
194    """
195    Return a list of symlinked files and dirs
196
197    saltenv : base
198        The salt fileserver environment to be listed
199
200    backend
201        Narrow fileserver backends to a subset of the enabled ones. If all
202        passed backends start with a minus sign (``-``), then these backends
203        will be excluded from the enabled backends. However, if there is a mix
204        of backends with and without a minus sign (ex:
205        ``backend=-roots,git``) then the ones starting with a minus sign will
206        be disregarded.
207
208        .. versionadded:: 2015.5.0
209
210    .. note:
211        Keep in mind that executing this function spawns a new process,
212        separate from the master. This means that if the fileserver
213        configuration has been changed in some way since the master has been
214        restarted (e.g. if :conf_master:`fileserver_backend`,
215        :conf_master:`gitfs_remotes`, :conf_master:`hgfs_remotes`, etc. have
216        been updated), then the results of this runner will not accurately
217        reflect what symlinks are available to minions.
218
219        When in doubt, use :py:func:`cp.list_master_symlinks
220        <salt.modules.cp.list_master_symlinks>` to see what symlinks the minion
221        can see, and always remember to restart the salt-master daemon when
222        updating the fileserver configuration.
223
224    CLI Example:
225
226    .. code-block:: bash
227
228        salt-run fileserver.symlink_list
229        salt-run fileserver.symlink_list saltenv=prod
230        salt-run fileserver.symlink_list saltenv=dev backend=git
231        salt-run fileserver.symlink_list base hg,roots
232        salt-run fileserver.symlink_list -git
233    """
234    fileserver = salt.fileserver.Fileserver(__opts__)
235    load = {"saltenv": saltenv, "fsbackend": backend}
236    return fileserver.symlink_list(load=load)
237
238
239def dir_list(saltenv="base", backend=None):
240    """
241    Return a list of directories in the given environment
242
243    saltenv : base
244        The salt fileserver environment to be listed
245
246    backend
247        Narrow fileserver backends to a subset of the enabled ones. If all
248        passed backends start with a minus sign (``-``), then these backends
249        will be excluded from the enabled backends. However, if there is a mix
250        of backends with and without a minus sign (ex:
251        ``backend=-roots,git``) then the ones starting with a minus sign will
252        be disregarded.
253
254        .. versionadded:: 2015.5.0
255
256    .. note:
257        Keep in mind that executing this function spawns a new process,
258        separate from the master. This means that if the fileserver
259        configuration has been changed in some way since the master has been
260        restarted (e.g. if :conf_master:`fileserver_backend`,
261        :conf_master:`gitfs_remotes`, :conf_master:`hgfs_remotes`, etc. have
262        been updated), then the results of this runner will not accurately
263        reflect what dirs are available to minions.
264
265        When in doubt, use :py:func:`cp.list_master_dirs
266        <salt.modules.cp.list_master_dirs>` to see what dirs the minion can see,
267        and always remember to restart the salt-master daemon when updating
268        the fileserver configuration.
269
270    CLI Example:
271
272    .. code-block:: bash
273
274        salt-run fileserver.dir_list
275        salt-run fileserver.dir_list saltenv=prod
276        salt-run fileserver.dir_list saltenv=dev backend=git
277        salt-run fileserver.dir_list base hg,roots
278        salt-run fileserver.dir_list -git
279    """
280    fileserver = salt.fileserver.Fileserver(__opts__)
281    load = {"saltenv": saltenv, "fsbackend": backend}
282    return fileserver.dir_list(load=load)
283
284
285def empty_dir_list(saltenv="base", backend=None):
286    """
287    .. versionadded:: 2015.5.0
288
289    Return a list of empty directories in the given environment
290
291    saltenv : base
292        The salt fileserver environment to be listed
293
294    backend
295        Narrow fileserver backends to a subset of the enabled ones. If all
296        passed backends start with a minus sign (``-``), then these backends
297        will be excluded from the enabled backends. However, if there is a mix
298        of backends with and without a minus sign (ex:
299        ``backend=-roots,git``) then the ones starting with a minus sign will
300        be disregarded.
301
302        .. note::
303
304            Some backends (such as :mod:`git <salt.fileserver.gitfs>` and
305            :mod:`hg <salt.fileserver.hgfs>`) do not support empty directories.
306            So, passing ``backend=git`` or ``backend=hg`` will result in an
307            empty list being returned.
308
309    CLI Example:
310
311    .. code-block:: bash
312
313        salt-run fileserver.empty_dir_list
314        salt-run fileserver.empty_dir_list saltenv=prod
315        salt-run fileserver.empty_dir_list backend=roots
316    """
317    fileserver = salt.fileserver.Fileserver(__opts__)
318    load = {"saltenv": saltenv, "fsbackend": backend}
319    return fileserver.file_list_emptydirs(load=load)
320
321
322def update(backend=None, **kwargs):
323    """
324    Update the fileserver cache. If no backend is provided, then the cache for
325    all configured backends will be updated.
326
327    backend
328        Narrow fileserver backends to a subset of the enabled ones.
329
330        .. versionchanged:: 2015.5.0
331            If all passed backends start with a minus sign (``-``), then these
332            backends will be excluded from the enabled backends. However, if
333            there is a mix of backends with and without a minus sign (ex:
334            ``backend=-roots,git``) then the ones starting with a minus
335            sign will be disregarded.
336
337            Additionally, fileserver backends can now be passed as a
338            comma-separated list. In earlier versions, they needed to be passed
339            as a python list (ex: ``backend="['roots', 'git']"``)
340
341    kwargs
342        Pass additional arguments to backend. See example below
343
344    CLI Example:
345
346    .. code-block:: bash
347
348        salt-run fileserver.update
349        salt-run fileserver.update backend=roots,git
350        salt-run fileserver.update backend=git remotes=myrepo,yourrepo
351    """
352    fileserver = salt.fileserver.Fileserver(__opts__)
353    fileserver.update(back=backend, **kwargs)
354    return True
355
356
357def clear_cache(backend=None):
358    """
359    .. versionadded:: 2015.5.0
360
361    Clear the fileserver cache from VCS fileserver backends (:mod:`git
362    <salt.fileserver.gitfs>`, :mod:`hg <salt.fileserver.hgfs>`, :mod:`svn
363    <salt.fileserver.svnfs>`). Executing this runner with no arguments will
364    clear the cache for all enabled VCS fileserver backends, but this
365    can be narrowed using the ``backend`` argument.
366
367    backend
368        Only clear the update lock for the specified backend(s). If all passed
369        backends start with a minus sign (``-``), then these backends will be
370        excluded from the enabled backends. However, if there is a mix of
371        backends with and without a minus sign (ex: ``backend=-roots,git``)
372        then the ones starting with a minus sign will be disregarded.
373
374    CLI Example:
375
376    .. code-block:: bash
377
378        salt-run fileserver.clear_cache
379        salt-run fileserver.clear_cache backend=git,hg
380        salt-run fileserver.clear_cache hg
381        salt-run fileserver.clear_cache -roots
382    """
383    fileserver = salt.fileserver.Fileserver(__opts__)
384    cleared, errors = fileserver.clear_cache(back=backend)
385    ret = {}
386    if cleared:
387        ret["cleared"] = cleared
388    if errors:
389        ret["errors"] = errors
390    if not ret:
391        return "No cache was cleared"
392    return ret
393
394
395def clear_lock(backend=None, remote=None):
396    """
397    .. versionadded:: 2015.5.0
398
399    Clear the fileserver update lock from VCS fileserver backends (:mod:`git
400    <salt.fileserver.gitfs>`, :mod:`hg <salt.fileserver.hgfs>`, :mod:`svn
401    <salt.fileserver.svnfs>`). This should only need to be done if a fileserver
402    update was interrupted and a remote is not updating (generating a warning
403    in the Master's log file). Executing this runner with no arguments will
404    remove all update locks from all enabled VCS fileserver backends, but this
405    can be narrowed by using the following arguments:
406
407    backend
408        Only clear the update lock for the specified backend(s).
409
410    remote
411        If specified, then any remotes which contain the passed string will
412        have their lock cleared. For example, a ``remote`` value of **github**
413        will remove the lock from all github.com remotes.
414
415    CLI Example:
416
417    .. code-block:: bash
418
419        salt-run fileserver.clear_lock
420        salt-run fileserver.clear_lock backend=git,hg
421        salt-run fileserver.clear_lock backend=git remote=github
422        salt-run fileserver.clear_lock remote=bitbucket
423    """
424    fileserver = salt.fileserver.Fileserver(__opts__)
425    cleared, errors = fileserver.clear_lock(back=backend, remote=remote)
426    ret = {}
427    if cleared:
428        ret["cleared"] = cleared
429    if errors:
430        ret["errors"] = errors
431    if not ret:
432        return "No locks were removed"
433    return ret
434
435
436def lock(backend=None, remote=None):
437    """
438    .. versionadded:: 2015.5.0
439
440    Set a fileserver update lock for VCS fileserver backends (:mod:`git
441    <salt.fileserver.gitfs>`, :mod:`hg <salt.fileserver.hgfs>`, :mod:`svn
442    <salt.fileserver.svnfs>`).
443
444    .. note::
445
446        This will only operate on enabled backends (those configured in
447        :conf_master:`fileserver_backend`).
448
449    backend
450        Only set the update lock for the specified backend(s).
451
452    remote
453        If not None, then any remotes which contain the passed string will have
454        their lock cleared. For example, a ``remote`` value of ``*github.com*``
455        will remove the lock from all github.com remotes.
456
457    CLI Example:
458
459    .. code-block:: bash
460
461        salt-run fileserver.lock
462        salt-run fileserver.lock backend=git,hg
463        salt-run fileserver.lock backend=git remote='*github.com*'
464        salt-run fileserver.lock remote=bitbucket
465    """
466    fileserver = salt.fileserver.Fileserver(__opts__)
467    locked, errors = fileserver.lock(back=backend, remote=remote)
468    ret = {}
469    if locked:
470        ret["locked"] = locked
471    if errors:
472        ret["errors"] = errors
473    if not ret:
474        return "No locks were set"
475    return ret
476