-
Notifications
You must be signed in to change notification settings - Fork 9
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
Implementing application level configuration parsing + deployment seq… #413
Implementing application level configuration parsing + deployment seq… #413
Conversation
Foresight Summary
View More Details✅ CI workflow has finished in 35 seconds and finished at 8th Mar, 2023.
*You can configure Foresight comments in your organization settings page. |
scripts/plugins/deploy_plugins.py
Outdated
# Check if application level bitops.config exists | ||
application_bitops_configuration_path = f"{bitops_operations_dir}/bitops.config.yaml" | ||
application_configuration = None | ||
if os.path.exists(application_bitops_configuration_path): | ||
with open(application_bitops_configuration_path, "r", encoding="utf8") as stream: | ||
application_config_yaml = yaml.load(stream, Loader=yaml.FullLoader) | ||
application_configuration = DefaultMunch.fromDict(application_config_yaml, None) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will work.
It will work only for deployments
section though.
If we're allowing users to include their bitops.config.yaml
on a root ops repo level, I'd assume full config should really work.
Is there a place where bitops.config.yaml
is parsed at earlier time? We could try to load the user's config it there.
We'll benefit from it when users want to also set the logging level, secrets masking or similar on BitOps runtime.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This loads the user level configuration.
AND THEN it populates the potential deployment sequence.
This was made with the above further enhancement in mind in that, we not have a loaded user application repo level configuration.
I did not go further then that, however the work is in a place where further enhancements to user specified values wouldn't be challenging
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to create a secondary ticket for that feature, what are your thoughts Eugen
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm talking about this part where the Docker
-packaged bitops.config.yaml
is loaded at early stage.
https://github.com/bitovi/bitops/blob/main/scripts/plugins/settings.py#L14-L35
If we try to load user-defined bitops.config.yaml
config from opsrepo right after that point, - it'll work for the majority of bitops.config settings, not just deployments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bitops configuration loads in the settings.py
bitops/scripts/plugins/settings.py
Line 34 in a8e834b
bitops_build_configuration = DefaultMunch.fromDict(BITOPS_config_yaml, None) |
It's not possible to have it in the settings.py
I'll look into doing the application bitops configuration load earlier (to gain access to the user specified variables).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@armab looking at the code, I'm not sure we could raise the application level loading any higher.
Additionally (unless I missed something) all potentially used variables that would be modifiable from the application level configuration would be done after the current block.
So in short, what you're asking for already takes place in a position that we could further enhance BitOps configuration before the "deployment" begins.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ENV variables to override the bitops.config.yaml
from settings are these:
bitops/scripts/plugins/settings.py
Lines 58 to 123 in a8e834b
BITOPS_fast_fail_mode = ( | |
BITOPS_ENV_fast_fail_mode | |
if BITOPS_ENV_fast_fail_mode is not None | |
else bitops_build_configuration.bitops.fail_fast | |
if bitops_build_configuration.bitops.fail_fast is not None | |
else True | |
) | |
BITOPS_run_mode = ( | |
BITOPS_ENV_run_mode | |
if BITOPS_ENV_run_mode is not None | |
else bitops_build_configuration.bitops.run_mode | |
if bitops_build_configuration.bitops.run_mode is not None | |
else "default" | |
) | |
BITOPS_logging_level = ( | |
BITOPS_ENV_logging_level | |
if BITOPS_ENV_logging_level is not None | |
else bitops_build_configuration.bitops.logging.level | |
if bitops_build_configuration.bitops.logging.level is not None | |
else "DEBUG" | |
) | |
BITOPS_logging_color = ( | |
bitops_build_configuration.bitops.logging.color.enabled | |
if bitops_build_configuration.bitops.logging.color.enabled is not None | |
else False | |
) | |
BITOPS_logging_filename = ( | |
bitops_build_configuration.bitops.logging.filename | |
if bitops_build_configuration.bitops.logging.filename is not None | |
else None | |
) | |
BITOPS_logging_path = ( | |
bitops_build_configuration.bitops.logging.path | |
if bitops_build_configuration.bitops.logging.path is not None | |
else "/var/log/bitops" | |
) | |
BITOPS_plugin_dir = ( | |
BITOPS_ENV_plugin_dir | |
if BITOPS_ENV_plugin_dir is not None | |
else bitops_build_configuration.bitops.plugins.plugin_dir | |
if bitops_build_configuration.bitops.plugins.plugin_dir is not None | |
else "/opt/bitops/scripts/plugins/" | |
) | |
BITOPS_INSTALLED_PLUGINS_DIR = "/opt/bitops/scripts/installed_plugins/" | |
BITOPS_default_folder = ( | |
BITOPS_ENV_default_folder | |
if BITOPS_ENV_default_folder is not None | |
else bitops_build_configuration.bitops.default_folder | |
if bitops_build_configuration.bitops.default_folder is not None | |
else "_default" | |
) | |
BITOPS_timeout = ( | |
BITOPS_ENV_timeout | |
if BITOPS_ENV_timeout is not None | |
else bitops_build_configuration.bitops.timeout | |
if bitops_build_configuration.bitops.timeout is not None | |
else 600 |
This way the precedence would be the following:
Docker-bundled bitops.config.yaml
-> User-specified OpsRepo bitops.config.yaml
(new) -> ENV variables
Where ENV variables have priority.
It's not possible to make this kind of expected full config vs ENV variable precedence before moving the user-provided configuration at a earlier level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also looked into the code, and it should be doable to read the user-provided ops-repo bitops.config.yaml
at that level.
It's fine if we do it before /tmp
creation, as we're just reading the config and that's all (no writes involved).
15439ca
to
1490c7a
Compare
1490c7a
to
4f10bbd
Compare
scripts/plugins/settings.py
Outdated
def parse_config(dictionary, dotted_key_list, validate=False): | ||
""" | ||
This function takes a dictionary, a list of keys in dotted notation, | ||
and an optional boolean argument "validate". It uses the operator.attrgetter() | ||
method to access the value in the dictionary associated with the dotted key list. | ||
""" | ||
try: | ||
item = operator.attrgetter(dotted_key_list)(dictionary) | ||
if item is None and validate: | ||
return False | ||
if item is not None and validate: | ||
return True | ||
return item | ||
except AttributeError: | ||
# Likely cause: Nested value doesn't exist | ||
if validate: | ||
return False | ||
return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I see validate
is just a None
check.
Do we really need it?
For example:
parse_config(bitops_build_configuration, "bitops.fail_fast")
if parse_config(bitops_build_configuration, "bitops.fail_fast", validate=True)
is the same as
parse_config(bitops_build_configuration, "bitops.fail_fast")
if parse_config(bitops_build_configuration, "bitops.fail_fast") is not None
right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point 👍
…ue from the chain of vars
…thub.com/bitovi/bitops into 410-application-repo-deployment-sequence
43b777b
to
f41d4f3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the changes!
…uence
Description
Users should be able to specify an alternative deployment sequence within their application repo.
Fixes # (issue)
fixes #410
closes #367
closes #259
Type of change
How Has This Been Tested?
Logs
Logs are posted in the linked ticket.
Checklist: