-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Disallow booleans in environment #2000
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
import json | ||
import logging | ||
import os | ||
from functools import wraps | ||
|
||
|
@@ -11,6 +12,9 @@ | |
from .errors import ConfigurationError | ||
|
||
|
||
log = logging.getLogger(__name__) | ||
|
||
|
||
DOCKER_CONFIG_HINTS = { | ||
'cpu_share': 'cpu_shares', | ||
'add_host': 'extra_hosts', | ||
|
@@ -44,6 +48,21 @@ def format_ports(instance): | |
return True | ||
|
||
|
||
@FormatChecker.cls_checks(format="environment") | ||
def format_boolean_in_environment(instance): | ||
""" | ||
Check if there is a boolean in the environment and display a warning. | ||
Always return True here so the validation won't raise an error. | ||
""" | ||
if isinstance(instance, bool): | ||
log.warn( | ||
"Warning: There is a boolean value, {0} in the 'environment' key.\n" | ||
"Environment variables can only be strings.\nPlease add quotes to any boolean values to make them string " | ||
"(eg, '{0}').\nThis warning will become an error in a future release. \r\n".format(instance) | ||
) | ||
return True | ||
|
||
|
||
def validate_service_names(func): | ||
@wraps(func) | ||
def func_wrapper(config): | ||
|
@@ -259,23 +278,25 @@ def _parse_oneof_validator(error): | |
|
||
def validate_against_fields_schema(config): | ||
schema_filename = "fields_schema.json" | ||
return _validate_against_schema(config, schema_filename) | ||
format_checkers = ["ports", "environment"] | ||
return _validate_against_schema(config, schema_filename, format_checkers) | ||
|
||
|
||
def validate_against_service_schema(config, service_name): | ||
schema_filename = "service_schema.json" | ||
return _validate_against_schema(config, schema_filename, service_name) | ||
format_checkers = ["ports"] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is only the ports used here, but both are used above? Would we get double warnings if we use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Exactly, it gave double warnings. Currently the code path doesn't get to validate the full service schema unless it's gone through the fields validation, so thought that was the best place for it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cool, maybe an inline comment for that so we remember why these lists are different? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thinking about this some more, I think there might be a better way to handle this. Instead of repeating the validation in the second schema, why not do something like this:
I think that way the format warning only logs once. I'd actually be in favor of dropping support for abstract base services, but that's a topic for another time. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like this is outside scope of this PR. Can we come back to that later in a separate PR as I think depending on how some of the future extend/import work is going to happen, this indeed will need to be re-factored but I'd like space for us to have a separate discussion around that. Heh, yeh abstract base services are a bit of a pain. |
||
return _validate_against_schema(config, schema_filename, format_checkers, service_name) | ||
|
||
|
||
def _validate_against_schema(config, schema_filename, service_name=None): | ||
def _validate_against_schema(config, schema_filename, format_checker=[], service_name=None): | ||
config_source_dir = os.path.dirname(os.path.abspath(__file__)) | ||
schema_file = os.path.join(config_source_dir, schema_filename) | ||
|
||
with open(schema_file, "r") as schema_fh: | ||
schema = json.load(schema_fh) | ||
|
||
resolver = RefResolver('file://' + config_source_dir + '/', schema) | ||
validation_output = Draft4Validator(schema, resolver=resolver, format_checker=FormatChecker(["ports"])) | ||
validation_output = Draft4Validator(schema, resolver=resolver, format_checker=FormatChecker(format_checker)) | ||
|
||
errors = [error for error in sorted(validation_output.iter_errors(config), key=str)] | ||
if errors: | ||
|
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.
should this use the
list_or_dict
schema? maybe there are differences between them?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 didn't use
list_or_dict
for this one as we define some extra constraints in thepatternProperties
for the allowed key names. I was being restrictive cos I was worried about character compatibility for different systems.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 think these constraints here are the same ones we'd want for
labels
, and most likely forextra_hosts
as well (where are the two places thatlist_or_dict
is used).What do you think about moving this to be the new definition of
list_or_dict
?If we do that, I think we'd want to change the format to something like
non_bool_scalar
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 honestly can't remember now why I thought they had separate requirements and I can't find it in my notes. If you can't think of any issues with doing that, I think that's a good suggestion, I will amend. Thanks.
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.
Oh, hmm, so I guess dashes are valid in label and hostnames, so that is one issue. We could just relax this to "any character" which would make it usable for all three.
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 think that would be better in a separate PR as it effects other fields. I'll look at doing that after this one has gone in.
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.
cool, that sounds fair