lukasjarosch / skipper

Inventory based templated configuration library inspired by the kapitan project
https://lukasjarosch.github.io/skipper/
MIT License
11 stars 3 forks source link

Cannot replace variables with values of type map from another class (sometimes) #78

Closed andaryjo closed 6 months ago

andaryjo commented 6 months ago

This sounds complicated, because it is. Let me explain.

Imagine you have to classes A and B:

---
a:
  location: westeurope
---
b:
  spokes:
    - location: ${a:location}

And finally a target which uses both of these classes:

---
target:
  skipper:
    use:
      - a
      - b
  spokes: ${b:spokes}

Compilation of this setup would sometimes pass and sometimes fail with this error:

unexpected node type map[string]interface {} at index 2

@alxndr13 and myself spent together around 10 hours debugging this and so far this is what we got:

We are planning to continue investigating what exactly the problem is here since we don't fully understand it yet. But maybe you have already an idea, @lukasjarosch.

lukasjarosch commented 6 months ago

Thank you for reporting this and huge respect for already spending so much time debugging this ❤️. I was able to reproduce the bug with your example.

You were, right about the fact that the variable replacement is random. And that is also the reason this happens. The underlying issue is that variable replacement is rather naively implemented by simply brute-forcing and replacing variables as long as variables can be found. Hence, the two cases arise.

Case 1 ✅

Case 2 💥

Ultimately the issue arises from variables which point to variables are not properly resolved and replaced in order. This would've prevented that situation from happening.

I've implemented a fix here: https://github.com/lukasjarosch/skipper/pull/79 Can you verify if that fix works for you?