File/environment-based secrets#35
Conversation
| | Size | Downloads | Discord | | ||
| | ------------- | ------------- | ------------- | | ||
| | [](https://hub.docker.com/r/timothyjmiller/cloudflare-ddns "cloudflare-ddns docker image size") | [](https://hub.docker.com/r/timothyjmiller/cloudflare-ddns "Total DockerHub pulls") | [](https://discord.gg/UgGmwMvNxm "Official Discord Server") | ||
| | Size | Downloads | Discord | |
There was a problem hiding this comment.
Apologies, this is vim trying to help with MD auto-format on save. Happy to revert this if you want.
There was a problem hiding this comment.
No problem, please fix it when you make your revisions.
|
Thank you for putting this together. I have some feedback for some changes I'd like to see in this pr. I do not want to see changes to the current Using the That way, the user can write a single docker-compose file and manage all their DNS by way of environment variables. |
|
Was this meant to be closed? I've not had time to look at your suggestions yet but I would still like to work on this |
|
Absolutely not. I am looking forward to your forthcoming commit. I'll restate this again, because we have multiple PRs trying to add file/environment based secrets, and so far they have came short of the community expectations. A PR to support file/environment based secrets cannot break backwards compatibility with passing in a config.json file, which is the preferred method for Docker-compose & the legacy Python script method. If we have an environment variable set, then we should short circuit and not read in the config.json file. Is there anything else I can help explain to help you? |
|
Hey @timothymiller - sorry for the delay here, finally getting time to sit down and properly read through your comments. 100% with you on not breaking any backwards compatibility. The PR as it stands now doesn't do that because it only extends the {
"cloudflare": [
{
"authentication": {
"api_token": "my_hard_coded_value",
"api_key": {
"api_key": { "file": "/my/secret/file" },
"account_email": { "env": "MY_ENV_VAR" }
}
},
...
},
{
"authentication": {
"api_token": { "file": "/my/other/secret/file" },
"api_key": {
"api_key": "my_other_hardcoded_value",
"account_email": { "env": "MY_OTHER_ENV_VAR" }
}
},
...
}
]
}However, all of that does go against your preference of "I do not want to see changes to the current When you say having vars named Have I understood your preference correctly above? (Or given you cause to reconsider extending the format? 😉) |
|
Thanks for your work so far. This PR needs to be synced with the latest master branch to be approved. |
|
I think this being over complicated, and overthought. File Support Environment Variables Example: import os
from collections import Collection, Mapping
from string import Template
# Read in all environment variables that have the correct prefix
ENV_VARS = {key: value for (key, value) in os.environ.items() if key.startswith('CF_DDNS_')}
# Stole this from StackOverflow for demo purposes
def recursive_map(data, func):
apply = lambda x: recursive_map(x)
if isinstance(data, Mapping):
return type(data)({k: apply(v) for k, v in data.items()})
elif isinstance(data, Collection):
return type(data)(apply(v) for v in data)
else:
return func(data)
# Substitutes env variables in a template string with their values
def resolve_env(val):
return Template(val).safe_substitute(**ENV_VARS)
# Resolve env vars in all values
config = recursive_map(config, resolve_env)This way, you can just do something like: |
I like your suggestion. I opened a call to action in the README for anyone interested in opening a PR to add this functionality. |
|
This discussion is being carried on in this thread #117 |
Fixes #31
First draft of a way to provide some config values from a file or environment variable rather than hardcoding them in
config.jsonthat is fully backwards compatible. It works by replacing the constant values with nested objects as follows:I went with replacing the values rather than adding new keys like
api_token_filebecause a) it lead to cleaner code and b) it avoids the problem of "what if a user enters both?".Right now this is implemented for the different auth configs and the zone ID - I think those make the most sense but happy to take feedback. I've added some brief docs in the readme but I could also add example docker-compose files or similar.