That can be very tricky though, if not impossible in some cases. I can’t come up with a good example from the top of my head, but integrations may look like they require similar data, but in some details they actually need some extra “seasoning” to clearly communicate what configuration options are possible. Let’s call it conditional configuration or relational configuration.
An example from a totally different application (Remmina, a tool for remote access using different protocols):
- For every host you configure a host and a port
- If it’s RDP you can provide the username, password, domain, bit-depth etc.
- If it’s SSH you can provide the username, password, but instead of that maybe which key to use, and domain and bit-depth don’t apply altogether
- Then there’s VNC, NX, whatever, all with different requirements
To make one thing clear: such a configuration can be easily done in yaml, provided the user doesn’t use options for a configuration variant where they don’t apply. But the user could add those options nonetheless, possibly causing the things to not work as they should. If the user reads the documentation though, this won’t be a problem. But if not, it’s a potential source for frustration.
And here the benefit of the UI-driven configuration comes into play. It ideally just allows you to configure parameters that are valid for what you are trying to do. Other parameters that globally are valid, but invalid within the feature scope, would just be hidden.
So now to the point I originally wanted to get to: it’s hard, if not impossible, to create an abstracted representation for the configuration-possibilities (referred to as schema) that can be used to validate input, and at the same time do the reverse operation of generating a UI for it. So the WHAT you from your statement lines up with the schema, the HOW is the logic to generate a UI from that schema. And because the HOW is a problem, it just has to be done by the integration maintainer.
To further visualize the problem imagine a non-existent integration for which you always need an ip, a port for variant a and b, username for b and c, and username + password just for c.
So now let’s pretend we could traverse this tree to generate a UI for it:
# BTW, this is what we have right now
integration:
ip: value
port: value
username: value
password: value
This wouldn’t work because all parameters would always be visible. Let’s try this:
integration:
ip: value
a:
port: value
b:
port: value
username: value
c:
username: value
password: value
This would work, but port and username are redundant. If there were changes and not every occurrence of port and username where adjusted, this could break the integration. So my final attempt:
integration:
ip: value
a:
port_a: value
b:
port_b: value
username_b: value
c:
username_c: value
password_c: value
Now this is nice without any redundancy. But by doing this we loose the ability to exactly derive the validation-method from the parameter name. So some sort of mapping-mechanism that tell’s us that port_a and port_b both have to be integers would be needed. And if a new variant c get’s introduced it could cause a problem if the validator-mapping for the new parameter isn’t correct.
So to sum this up: attempts to solve such problems always come with drawbacks that have to be worked around in some way. So the most stable solution is the first example, because here it’s hard to break anything, regardless of any change, added variants, whatever. But it also happens to be the solution that’s can’t be visualized automatically at all. Or at least not in a way that disallows the user to enter data that he’s not supposed to supply.