I had aked a question in this Charming Docs post but later realized that I should’ve asked the question here. So I’m re-asking here.
How does a charm author reconcile
config.yaml's deliberate restrictiveness with an application’s hierarchical configuration? For example, AlertManager has a non-flat configuration file (example) and translating some of the options to
config.yaml would be non-trivial.
For the simpler parts, it would obviously just be a matter of flattening the options in the
config.yaml file. For example, the following AlertManager configuration options:
global: smtp_smarthost: 'localhost:25' smtp_from: 'firstname.lastname@example.org' smtp_auth_username: 'alertmanager' smtp_auth_password: 'password'
Would be defined in the charm’s
options: global_smtp_smarthost: type: string global_smtp_from: type: string global_smtp_auth_username: type: string global_stmp_auth_password: type: string
But how would one deal with repeating options such as AlertManager’s receivers? For example, I tried to map the following to what was possible with
receivers: - name: 'team-X-mails' email_configs: - to: 'team-Xemail@example.com' - name: 'team-X-pager' email_configs: - to: 'team-Xfirstname.lastname@example.org' pagerduty_configs: - service_key: <team-X-key> ...
The “best” approach I could get with
options: receivers1_name: type: string receivers1_config_type: type: string receivers1_config_options: type: string # Would really have to be a minified JSON string or a base64 encoded YAML string receivers2_name: type: string receivers2_config_type: type: string receivers2_config_options: type: string # Would really have to be a minified JSON string or a base64 encoded YAML string ...
Obviously the above approach is not ideal for a number of reasons:
- The number of receivers defined would be limited to however many
receiversX_*is defined in
- Dropping down to a JSON string or a base64-encoded YAML string defeats the purpose of
config.yaml's restrictiveness which is to simplify AlertManager configuration
- As per the documentation referred to above: “If you’re considering using base64 encoding to slip structured data through the deliberately restrictive configuration language, you’re probably ‘Doing It Wrong.’”
- Note in the AlertManager config above how the
team-X-pagerreceiver has a config for both email and pagerduty. How does one represent that in
My initial analysis to the above problem is that it’s a symptom of me trying to create an “Unnecessary Abstraction Over An Abstraction™.” AlertManager’s configuration is already an abstraction over a complex problem domain and it is, for now, the simplest way to configure alerting. To try and abstract that with options in
config.yaml seems unnecessary and a side effect of this would be that the charm user would have to learn the configuration options of the charm and try and map that to AlertManager’s own configuration options. This means a lot of jumping back and forth between the charm’s documentation and AlertManager’s documentation. Again, that defeats the intended purpose of
conig.yaml and charming in general which is to simplify the job of deploying and operating AlertManager or any other application.
Of course, I haven’t stopped my analysis there. To move forward with my charming work, I tried to prototype a number of approaches. One of the approaches that I found promising was making use of juju’s
--resource option. This GitHub Pull Request already explains this thought process well enough.
I am also wary of the possibility that I might just be missing some hidden powers behind
config.yaml's parser so I’d be more than happy to be corrected of my (mis)understanding of the above restrictiveness.
I would love to know what the rest of the community thinks about this. Thank you so much for reading this far.