Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inheritance Issue #621

Closed
no-such-anthony opened this issue Dec 20, 2020 · 6 comments · Fixed by #623
Closed

Inheritance Issue #621

no-such-anthony opened this issue Dec 20, 2020 · 6 comments · Fixed by #623

Comments

@no-such-anthony
Copy link

There appears to be an inheritance issue as found by Netigo @ https://nornir.discourse.group/t/inheritance-problem/645

If you recreate the inventory files at https://github.com/nornir-automation/nornir/blob/develop/docs/tutorial/inventory.ipynb

Then try

leaf01_bma = nr.inventory.hosts["leaf01.bma"]
print(leaf01_bma["domain"])  

The data is supposed to come from the group global, but instead comes from defaults.yaml, ie acme.local. It should be global.local as mentioned in the documentation.

I've attempted a possible patch but not sure how correct it is within the Nornir framework.

In nornir/core/inventory.py

Modify the group loop in _resolve_data

for g in self.groups:
    for k, v in g.data.items():
        if k not in processed:
            processed.append(k)
            result[k] = v

    for pg in g.groups:
        for k, v in pg.data.items():
            if k not in processed:
                processed.append(k)
                result[k] = v

Modify the group loop in __getitem__

    for g in self.groups:
        try:
            r = g.data[item]
            return r
        except KeyError:
            pass

        for pg in g.groups:
            try:
                r = pg.data[item]
                return r
            except KeyError:
                pass
@dbarrosop
Copy link
Contributor

thanks for reporting, I opened #623 which should address this bug

@no-such-anthony
Copy link
Author

Thanks! Re #623 - Looks great. I think it may still need a change of g.items() to g.data.items() in _resolve_data? And maybe a .values() test for this scenario?

@NetIgo
Copy link

NetIgo commented Dec 22, 2020

Thank you.
Looks good.

@no-such-anthony
Copy link
Author

no-such-anthony commented Dec 23, 2020

Something that returns an ordered list of all the groups might help in _resolve_data and __getitem__? Example

    def __ordered_groups(self, groups):
        og = []
        for g in groups:
            og.append(g)
            if len(g.groups) > 0:
                og.extend(self.__ordered_groups(g.groups))
        return og

for g in self.__ordered_groups(self.groups):

@no-such-anthony
Copy link
Author

Another function that needs checking on, __getattribute__ . If the username was in group global like the original example, it would be missed.

Possible fix for __getattribute__ , using something that returns a complete group list like above,

           for g in self.__ordered_groups(self.groups):
                r = object.__getattribute__(g, name)

@dbarrosop
Copy link
Contributor

Thanks, I will try to find time to look into your comments. Just a tip, these comments would be easier to track on the PR alongside the code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants