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

feat: Support multiple configuration files #389

Merged
merged 13 commits into from
Jan 7, 2023

Conversation

henningjanssen
Copy link
Contributor

@henningjanssen henningjanssen commented Dec 19, 2022

Summary

This PR allows configuration to split across multiple files using the common config.d/-path style. The approach reads all *.yml and *.yaml files and merges them in memory into a single file before parsing. This seemed easier und required fewer changes than parsing each file individually and merging the objects afterwards.

Fixes #326

As I did not work with golang before, feel free to remark on obvious errors and bad patterns.

I envisaged to write tests, but did not figure out yet, how invasive tests are intended to be structured for this project. I hope the chosen way is in you interest.

Checklist

  • Tested and/or added tests to validate that the changes work as intended, if applicable.
  • Added the documentation in README.md, if applicable.

@henningjanssen henningjanssen changed the title Allow configuration to be distributed WIP: Allow configuration to be distributed Dec 19, 2022
@henningjanssen henningjanssen marked this pull request as draft December 19, 2022 01:17
@henningjanssen henningjanssen marked this pull request as ready for review December 19, 2022 01:26
@henningjanssen henningjanssen changed the title WIP: Allow configuration to be distributed Allow configuration to be distributed Dec 19, 2022
config/config.go Outdated Show resolved Hide resolved
@TwiN TwiN changed the title Allow configuration to be distributed feat: Support multiple configuration files Jan 6, 2023
main.go Outdated Show resolved Hide resolved
config/config.go Outdated Show resolved Hide resolved
config/config.go Outdated Show resolved Hide resolved
config/config.go Outdated Show resolved Hide resolved
config/config.go Outdated Show resolved Hide resolved
config/config.go Outdated Show resolved Hide resolved
config/config.go Outdated Show resolved Hide resolved
config/config.go Outdated Show resolved Hide resolved
config/config.go Outdated Show resolved Hide resolved
Comment on lines +45 to +64
func TestLoadConfigurationFile(t *testing.T) {
_, err := LoadConfiguration("../test-conf/config.yaml")
if nil != err {
t.Error("Should not have returned an error, because the configuration file exists at the provided path")
}
}

func TestLoadDistributedConfiguration(t *testing.T) {
_, err := LoadConfiguration("../test-conf/conf.d/")
if nil != err {
t.Error("Should not have returned an error, because configuration files exist at the provided path for distributed files")
}
}

func TestLoadCombinedConfiguration(t *testing.T) {
_, err := LoadConfiguration("../test-conf/empty-conf.d/")
if nil == err {
t.Error("Should have returned an error, because the configuration directory does not contain any configuration files")
}
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to self: rewrite that in a single Test (use test table method) and dynamically generate the config directories and files instead of using the test-conf folder. Just make sure to defer clean up

henningjanssen and others added 5 commits January 7, 2023 05:05
Co-authored-by: TwiN <twin@linux.com>
Co-authored-by: TwiN <twin@linux.com>
Co-authored-by: TwiN <twin@linux.com>
Co-authored-by: TwiN <twin@linux.com>
Co-authored-by: TwiN <twin@linux.com>
config/config.go Outdated Show resolved Hide resolved
@codecov-commenter
Copy link

Codecov Report

Base: 81.99% // Head: 82.36% // Increases project coverage by +0.37% 🎉

Coverage data is based on head (be86949) compared to base (19e90cd).
Patch coverage: 70.76% of modified lines in pull request are covered.

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #389      +/-   ##
==========================================
+ Coverage   81.99%   82.36%   +0.37%     
==========================================
  Files          55       55              
  Lines        4148     4163      +15     
==========================================
+ Hits         3401     3429      +28     
+ Misses        589      579      -10     
+ Partials      158      155       -3     
Impacted Files Coverage Δ
config/config.go 78.44% <70.76%> (+5.17%) ⬆️
controller/handler/endpoint_status.go 39.28% <0.00%> (-3.29%) ⬇️
controller/handler/handler.go 78.12% <0.00%> (+0.70%) ⬆️
config/maintenance/maintenance.go 100.00% <0.00%> (+3.79%) ⬆️

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

@TwiN TwiN merged commit 8e14302 into TwiN:master Jan 7, 2023
@TwiN
Copy link
Owner

TwiN commented Jan 7, 2023

@henningjanssen Thank you for your contribution!

@TwiN
Copy link
Owner

TwiN commented Jan 7, 2023

By the way, I did some testing locally and it turns out your implementation doesn't work 😓
I've prevented it from making it to latest and I'll see if I can fix it, but long story short, two files with endpoints: doesn't actually merge the endpoints, the second endpoints: just overwrite the first one.

TwiN added a commit that referenced this pull request Jan 7, 2023
TwiN added a commit that referenced this pull request Jan 7, 2023
Revert "feat: Support multiple configuration files (#389)"

This reverts commit 8e14302.
@TwiN
Copy link
Owner

TwiN commented Jan 7, 2023

@henningjanssen I'm really sorry; I had to revert it because I wasn't able to fix it before signing off for the day (it's nearly 4AM for me) and I don't want to leave the master branch in an inaccurate state. I'll have a look at it later.

@henningjanssen
Copy link
Contributor Author

Yeah, because there is no "correct" way of handling duplicate nested keys, especially if they have different types. But this should also be an issue with duplicating keys inside the same yaml-file as this implementation sees no difference between a single and multiple files due to concatenation of byte streams before parsing.

The advantage of this approach is to have f.e. alert-config (containing access tokens) separated from endpoints so that the latter can be checked into version control while the former is deployed on the host directly.

While probably breaking the YAML protocol, splitting endpoints into multiple files is possible by omitting the top-level key. The load order can be influenced by filename (10-xxx.yml, 70-yyy.yml). A possibility to make this usage of this hack more obvious could be to additionally support usage of a file extension like .pyml (partial yml).

@TwiN
Copy link
Owner

TwiN commented Jan 7, 2023

Oh it's definitely possible, don't worry :P

Personally, I think there would be no advantage implementing this feature if we can't define endpoints in multiple files -- that's what people want the most, because the endpoint configuration is the longest configuration.

It's going to require some testing, but long story short, I'll make it deep merge the yaml files, append keys that have a slice as value rather than overwrite other slices, and prevent duplicate keys with primitive as value.

I'll re-add your changes with the fix in #396

@TwiN
Copy link
Owner

TwiN commented Jan 8, 2023

Surprisingly, outside of yq (which had too many dependencies for my liking), I haven't found any decent libraries to deep merge YAML files, so I made one: https://github.com/TwiN/deepmerge

Granted it could be because I haven't searched for that long, but 🤷‍♂️

@TwiN
Copy link
Owner

TwiN commented Jan 8, 2023

Superseded by #396

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 this pull request may close these issues.

split config files
3 participants