def get_object_classes(class_names=None): """ Resolve class names from config into actual classes. Also, always return dependencies before dependent classes """ if class_names is None: conf = config.get_config() classes = conf.class_paths.keys() else: classes = class_names class_list = [] for class_name in classes: klass = getattr(api, class_name) class_list.extend( Bootstrapper.get_object_classes(class_names=klass.depends_on)) class_list.append(klass) if class_names is None: res = [] for klass in class_list: if klass not in res: res.append(klass) return res else: return class_list
def __init__(self, repo=None): self.config = config.get_config() if repo is None: repo = git.Repo(self.config.scripts_root, self.config.bootstrap_branch) self.repo = repo
def init_empty_repo(cls): conf = config.get_config() logger.debug(f"Creating empty git repository in {conf.scripts_root}") os.makedirs(conf.scripts_root) repo = git.Repo.init_empty_repo(conf.scripts_root, conf.bootstrap_branch) return cls(repo=repo)
def get_path_in_repo(self, path): """ Path can be in one of these forms: Absolute path (/opt/netmri_bootstrap/scripts/foo.py) Path relative to current directory (./netmri_bootstrap/scripts/foo.py) Path relative to repo root (scripts/foo.py) This method converts them all into path relative to repo root. """ absolute_path = os.path.abspath(path) absolute_repo_root = os.path.abspath(self.path) if os.path.commonpath([absolute_path, absolute_repo_root]) \ != absolute_repo_root: if os.path.isabs(path): raise ValueError(f"{path} is outside of repository {self.path}") else: # Simplify constructions like a//b/../c (becomes a/c) normalized_path = os.path.normpath(path) for object_subpath in config.get_config().class_paths.values(): if normalized_path.startswith(object_subpath): logger.debug(f"Assuming {path} is inside the repo") return normalized_path raise ValueError(f"Relative path {path} is invalid") else: relative_path = os.path.relpath(absolute_path, start=absolute_repo_root) logger.debug(f"Translated {path} to {relative_path}") return relative_path
def save_to_disk(self): conf = config.get_config() fn = os.path.join(conf.scripts_root, self.generate_path()) os.makedirs(os.path.dirname(fn), exist_ok=True) logger.info( f"{self.api_broker} \"{self.name}\" (id {self.id}) -> {self.path}") with open(fn, 'w') as f: f.write(self.build_metadata_block()) f.write(self._content) return fn
def _get_subclass_by_path(klass, path): subclass_name = None for cls, cls_path in config.get_config().class_paths.items(): if path.startswith(cls_path): subclass_name = cls break the_module = importlib.import_module(klass.__module__) if subclass_name is None or subclass_name not in dir(the_module): raise ValueError(f"Cannot find subclass for path {path}") return getattr(the_module, subclass_name)
def save_to_disk(self): conf = config.get_config() os.makedirs(os.path.join(conf.scripts_root, self.scripts_dir()), exist_ok=True) fn = os.path.join(conf.scripts_root, self.generate_path()) logger.info( f"{self.api_broker} \"{self.name}\" (id {self.id}) -> {self.path}") with open(fn, 'w') as f: # No need to write metadata block, it's already exported f.write(self._content) return fn
def save_to_disk(self): conf = config.get_config() os.makedirs(os.path.join(conf.scripts_root, self.scripts_dir()), exist_ok=True) fn = os.path.join(conf.scripts_root, self.generate_path()) logger.info( f"{self.api_broker} \"{self.name}\" (id {self.id}) -> {self.path}") content = etree.tostring(self._content, pretty_print=True, xml_declaration=True, encoding="UTF-8") with open(fn, 'wb') as f: f.write(content) return fn
def test_get_config(self): conf = config.get_config() self.assertEqual(conf.host, "localhost") self.assertEqual(conf.username, "admin") self.assertEqual(conf.password, "unittest") self.assertEqual(conf.proto, "https") self.assertEqual(conf.ssl_verify, True) self.assertEqual(conf.scripts_root, "/tmp/netmri/") self.assertEqual(conf.bootstrap_branch, "master") self.assertEqual(conf.skip_readonly_objects, True) expected_class_paths = { 'Script': 'scripts', 'Policy': 'policy', 'PolicyRule': 'policy/rules' } self.assertEqual(conf.class_paths, expected_class_paths)
def scripts_dir(klass): path = config.get_config().class_paths.get(klass.__name__, None) if path is None: raise ValueError( f"Cannot determine repo path for {klass.__name__}") return path