cdist configuration management
Latest manual: https://www.cdi.st/manual/latest/
Home page: https://www.cdi.st
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
179 lines
6.9 KiB
179 lines
6.9 KiB
# -*- coding: utf-8 -*- |
|
# |
|
# 2019-2020 Darko Poljak (darko.poljak at gmail.com) |
|
# |
|
# This file is part of cdist. |
|
# |
|
# cdist is free software: you can redistribute it and/or modify |
|
# it under the terms of the GNU General Public License as published by |
|
# the Free Software Foundation, either version 3 of the License, or |
|
# (at your option) any later version. |
|
# |
|
# cdist is distributed in the hope that it will be useful, |
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
# GNU General Public License for more details. |
|
# |
|
# You should have received a copy of the GNU General Public License |
|
# along with cdist. If not, see <http://www.gnu.org/licenses/>. |
|
# |
|
# |
|
|
|
import cdist |
|
import cdist.configuration |
|
import cdist.core |
|
import cdist.exec.util as util |
|
import os |
|
import glob |
|
import fnmatch |
|
|
|
|
|
class Info: |
|
def __init__(self, conf_dirs, args): |
|
self.conf_dirs = conf_dirs |
|
self.all = args.all |
|
self.display_global_explorers = args.global_explorers |
|
self.display_types = args.types |
|
if not self.display_global_explorers and not self.display_types: |
|
self.all = True |
|
self.fixed_string = args.fixed_string |
|
self._setup_glob_pattern(args.pattern) |
|
self.full = args.full |
|
|
|
def _setup_glob_pattern(self, pattern): |
|
if pattern is None: |
|
self.glob_pattern = '*' |
|
elif ('?' in pattern or '*' in pattern or '[' in pattern or |
|
self.fixed_string): |
|
self.glob_pattern = pattern |
|
else: |
|
self.glob_pattern = '*' + pattern + '*' |
|
|
|
@classmethod |
|
def commandline(cls, args): |
|
conf_dirs = util.resolve_conf_dirs_from_config_and_args(args) |
|
c = cls(conf_dirs, args) |
|
c.run() |
|
|
|
def _get_global_explorers(self, conf_path): |
|
rv = [] |
|
global_explorer_path = os.path.join(conf_path, "explorer", |
|
self.glob_pattern) |
|
if self.fixed_string: |
|
if os.path.exists(global_explorer_path): |
|
rv.append(global_explorer_path) |
|
else: |
|
for explorer in glob.glob(global_explorer_path): |
|
rv.append(explorer) |
|
return rv |
|
|
|
def _should_display_type(self, dir_entry): |
|
if not dir_entry.is_dir(): |
|
return False |
|
if self.glob_pattern is None: |
|
return True |
|
if self.fixed_string: |
|
return dir_entry.name == self.glob_pattern |
|
else: |
|
return fnmatch.fnmatch(dir_entry.name, self.glob_pattern) |
|
|
|
def _get_types(self, conf_path): |
|
rv = [] |
|
types_path = os.path.join(conf_path, "type") |
|
if not os.path.exists(types_path): |
|
return rv |
|
with os.scandir(types_path) as it: |
|
for entry in it: |
|
if self._should_display_type(entry): |
|
rv.append(entry.path) |
|
return rv |
|
|
|
def _display_details(self, title, details, default_values=None, |
|
deprecated=None): |
|
if not details: |
|
return |
|
if isinstance(details, bool): |
|
print("\t{}: {}".format(title, 'yes' if details else 'no')) |
|
elif isinstance(details, str): |
|
print("\t{}: {}".format(title, details)) |
|
elif isinstance(details, list): |
|
dv = dict(default_values) if default_values else {} |
|
dp = dict(deprecated) if deprecated else {} |
|
|
|
print("\t{}:".format(title)) |
|
for x in sorted(details): |
|
print("\t\t{}".format(x), end='') |
|
has_default = x in dv |
|
is_deprecated = x in dp |
|
need_comma = False |
|
if has_default or is_deprecated: |
|
print(" (", end='') |
|
if has_default: |
|
print("default: {}".format(dv[x]), end='') |
|
need_comma = True |
|
if is_deprecated: |
|
print("{}deprecated".format(', ' if need_comma else ''), |
|
end='') |
|
if has_default or is_deprecated: |
|
print(")", end='') |
|
print() |
|
|
|
def _display_type_parameters(self, cdist_type): |
|
self._display_details("required parameters", |
|
cdist_type.required_parameters, |
|
default_values=cdist_type.parameter_defaults, |
|
deprecated=cdist_type.deprecated_parameters) |
|
self._display_details("required multiple parameters", |
|
cdist_type.required_multiple_parameters, |
|
default_values=cdist_type.parameter_defaults, |
|
deprecated=cdist_type.deprecated_parameters) |
|
self._display_details("optional parameters", |
|
cdist_type.optional_parameters, |
|
default_values=cdist_type.parameter_defaults, |
|
deprecated=cdist_type.deprecated_parameters) |
|
self._display_details("optional multiple parameters", |
|
cdist_type.optional_multiple_parameters, |
|
default_values=cdist_type.parameter_defaults, |
|
deprecated=cdist_type.deprecated_parameters) |
|
self._display_details("boolean parameters", |
|
cdist_type.boolean_parameters, |
|
default_values=cdist_type.parameter_defaults, |
|
deprecated=cdist_type.deprecated_parameters) |
|
|
|
def _display_type_characteristics(self, cdist_type): |
|
characteristics = [] |
|
if cdist_type.is_install: |
|
characteristics.append('install') |
|
else: |
|
characteristics.append('config') |
|
if cdist_type.is_singleton: |
|
characteristics.append('singleton') |
|
if cdist_type.is_nonparallel: |
|
characteristics.append('nonparallel') |
|
else: |
|
characteristics.append('parallel') |
|
if cdist_type.deprecated is not None: |
|
characteristics.append('deprecated') |
|
print("\t{}".format(', '.join(characteristics))) |
|
|
|
def _display_type_details(self, type_path): |
|
dirname, basename = os.path.split(type_path) |
|
cdist_type = cdist.core.CdistType(dirname, basename) |
|
|
|
self._display_type_characteristics(cdist_type) |
|
self._display_type_parameters(cdist_type) |
|
|
|
def run(self): |
|
rv = [] |
|
for cp in self.conf_dirs: |
|
conf_path = os.path.expanduser(cp) |
|
if self.all or self.display_global_explorers: |
|
rv.extend((x, 'E', ) for x in self._get_global_explorers( |
|
conf_path)) |
|
if self.all or self.display_types: |
|
rv.extend((x, 'T', ) for x in self._get_types(conf_path)) |
|
rv = sorted(rv, key=lambda x: x[0]) |
|
for x, t in rv: |
|
print(x) |
|
if self.full and t == 'T': |
|
self._display_type_details(x)
|
|
|