diff --git a/muranoclient/common/utils.py b/muranoclient/common/utils.py index 9ba9d7f2..de2ea155 100644 --- a/muranoclient/common/utils.py +++ b/muranoclient/common/utils.py @@ -353,18 +353,38 @@ class Package(FileWrapperMixin): except Exception: return [] + @property + def resolvers(self): + if not hasattr(self, '_resolvers'): + self.classes + return self._resolvers + @property def classes(self): if not hasattr(self, '_classes'): self._classes = {} + self._resolvers = {} for class_name, class_file in six.iteritems( self.manifest.get('Classes', {})): filename = "Classes/%s" % class_file if filename not in self.contents.namelist(): continue - klass = yaml.load(self.contents.open(filename), - DummyYaqlYamlLoader) - self._classes[class_name] = klass + klass_list = yaml.load_all(self.contents.open(filename), + DummyYaqlYamlLoader) + if not klass_list: + raise ValueError('No classes defined in file') + resolver = None + for klass in klass_list: + ns = klass.get('Namespaces') + if ns: + resolver = NamespaceResolver(ns) + name = klass.get('Name') + if name and resolver: + name = resolver.resolve_name(name) + if name == class_name: + self._classes[class_name] = klass + self._resolvers[class_name] = resolver + break return self._classes @property @@ -669,3 +689,32 @@ def traverse_and_replace(obj, _maybe_replace(obj, key, value) else: _maybe_replace(obj, key, value) + + +class NamespaceResolver(object): + """Copied from main murano repo + + original at murano/dsl/namespace_resolver.py + """ + + def __init__(self, namespaces): + self._namespaces = namespaces + self._namespaces[''] = '' + + def resolve_name(self, name, relative=None): + if name is None: + raise ValueError() + if name and name.startswith(':'): + return name[1:] + if ':' in name: + parts = name.split(':') + if len(parts) != 2 or not parts[1]: + raise NameError('Incorrectly formatted name ' + name) + if parts[0] not in self._namespaces: + raise KeyError('Unknown namespace prefix ' + parts[0]) + return '.'.join((self._namespaces[parts[0]], parts[1])) + if not relative and '=' in self._namespaces and '.' not in name: + return '.'.join((self._namespaces['='], name)) + if relative and '.' not in name: + return '.'.join((relative, name)) + return name diff --git a/muranoclient/v1/artifact_packages.py b/muranoclient/v1/artifact_packages.py index 7b082ab2..286819e7 100644 --- a/muranoclient/v1/artifact_packages.py +++ b/muranoclient/v1/artifact_packages.py @@ -52,7 +52,8 @@ class ArtifactRepo(object): for k, v in six.iteritems(kwargs): package_draft[k] = v - inherits = self._get_local_inheritance(package.classes) + inherits = self._get_local_inheritance(package.classes, + package.resolvers) package_draft['inherits'] = inherits @@ -90,16 +91,16 @@ class ArtifactRepo(object): return self.client.artifacts.get(app_id) @staticmethod - def _get_local_inheritance(classes): + def _get_local_inheritance(classes, resolvers): result = {} for class_name, klass in six.iteritems(classes): if 'Extends' not in klass: continue ns = klass.get('Namespaces') if ns: - resolver = NamespaceResolver(ns) + resolver = utils.NamespaceResolver(ns) else: - resolver = None + resolver = resolvers.get(class_name) if isinstance(klass['Extends'], list): bases = klass['Extends'] @@ -337,32 +338,3 @@ class PackageWrapper(object): {'pkg_name': self.name, 'attrs': ", ".join(missing_keys)}) return {key: getattr(self, key) for key in keys} - - -class NamespaceResolver(object): - """Copied from main murano repo - - original at murano/dsl/namespace_resolver.py - """ - - def __init__(self, namespaces): - self._namespaces = namespaces - self._namespaces[''] = '' - - def resolve_name(self, name, relative=None): - if name is None: - raise ValueError() - if name and name.startswith(':'): - return name[1:] - if ':' in name: - parts = name.split(':') - if len(parts) != 2 or not parts[1]: - raise NameError('Incorrectly formatted name ' + name) - if parts[0] not in self._namespaces: - raise KeyError('Unknown namespace prefix ' + parts[0]) - return '.'.join((self._namespaces[parts[0]], parts[1])) - if not relative and '=' in self._namespaces and '.' not in name: - return '.'.join((self._namespaces['='], name)) - if relative and '.' not in name: - return '.'.join((relative, name)) - return name diff --git a/releasenotes/notes/multi-class-yamls-support-914b3d155324214f.yaml b/releasenotes/notes/multi-class-yamls-support-914b3d155324214f.yaml new file mode 100644 index 00000000..1d26c2fb --- /dev/null +++ b/releasenotes/notes/multi-class-yamls-support-914b3d155324214f.yaml @@ -0,0 +1,4 @@ +--- +fixes: + - Fixed a bug when a package containing multi-class yamls could not be added + to glare-based catalog.