Support for credential_spec

Signed-off-by: Djordje Lukic <djordje.lukic@docker.com>
This commit is contained in:
Djordje Lukic 2019-01-16 13:47:23 +01:00 committed by Ulysses Souza
parent 3934617e37
commit 82a89aef1c
5 changed files with 42 additions and 5 deletions

View File

@ -206,8 +206,8 @@ class TopLevelCommand(object):
name specified in the client certificate name specified in the client certificate
--project-directory PATH Specify an alternate working directory --project-directory PATH Specify an alternate working directory
(default: the path of the Compose file) (default: the path of the Compose file)
--compatibility If set, Compose will attempt to convert deploy --compatibility If set, Compose will attempt to convert keys
keys in v3 files to their non-Swarm equivalent in v3 files to their non-Swarm equivalent
Commands: Commands:
build Build or rebuild services build Build or rebuild services

View File

@ -51,6 +51,7 @@ from .validation import match_named_volumes
from .validation import validate_against_config_schema from .validation import validate_against_config_schema
from .validation import validate_config_section from .validation import validate_config_section
from .validation import validate_cpu from .validation import validate_cpu
from .validation import validate_credential_spec
from .validation import validate_depends_on from .validation import validate_depends_on
from .validation import validate_extends_file_path from .validation import validate_extends_file_path
from .validation import validate_healthcheck from .validation import validate_healthcheck
@ -369,7 +370,6 @@ def check_swarm_only_config(service_dicts, compatibility=False):
) )
if not compatibility: if not compatibility:
check_swarm_only_key(service_dicts, 'deploy') check_swarm_only_key(service_dicts, 'deploy')
check_swarm_only_key(service_dicts, 'credential_spec')
check_swarm_only_key(service_dicts, 'configs') check_swarm_only_key(service_dicts, 'configs')
@ -706,6 +706,7 @@ def validate_service(service_config, service_names, config_file):
validate_depends_on(service_config, service_names) validate_depends_on(service_config, service_names)
validate_links(service_config, service_names) validate_links(service_config, service_names)
validate_healthcheck(service_config) validate_healthcheck(service_config)
validate_credential_spec(service_config)
if not service_dict.get('image') and has_uppercase(service_name): if not service_dict.get('image') and has_uppercase(service_name):
raise ConfigurationError( raise ConfigurationError(
@ -894,6 +895,7 @@ def finalize_service(service_config, service_names, version, environment, compat
normalize_build(service_dict, service_config.working_dir, environment) normalize_build(service_dict, service_config.working_dir, environment)
if compatibility: if compatibility:
service_dict = translate_credential_spec_to_security_opt(service_dict)
service_dict, ignored_keys = translate_deploy_keys_to_container_config( service_dict, ignored_keys = translate_deploy_keys_to_container_config(
service_dict service_dict
) )
@ -930,6 +932,25 @@ def convert_restart_policy(name):
raise ConfigurationError('Invalid restart policy "{}"'.format(name)) raise ConfigurationError('Invalid restart policy "{}"'.format(name))
def convert_credential_spec_to_security_opt(credential_spec):
if 'file' in credential_spec:
return 'file://{file}'.format(file=credential_spec['file'])
return 'registry://{registry}'.format(registry=credential_spec['registry'])
def translate_credential_spec_to_security_opt(service_dict):
result = []
if 'credential_spec' in service_dict:
spec = convert_credential_spec_to_security_opt(service_dict['credential_spec'])
result.append('credentialspec={spec}'.format(spec=spec))
if result:
service_dict['security_opt'] = result
return service_dict
def translate_deploy_keys_to_container_config(service_dict): def translate_deploy_keys_to_container_config(service_dict):
if 'credential_spec' in service_dict: if 'credential_spec' in service_dict:
del service_dict['credential_spec'] del service_dict['credential_spec']

View File

@ -240,6 +240,18 @@ def validate_depends_on(service_config, service_names):
) )
def validate_credential_spec(service_config):
credential_spec = service_config.config.get('credential_spec')
if not credential_spec:
return
if 'registry' not in credential_spec and 'file' not in credential_spec:
raise ConfigurationError(
"Service '{s.name}' is missing 'credential_spec.file' or "
"credential_spec.registry'".format(s=service_config)
)
def get_unsupported_config_msg(path, error_key): def get_unsupported_config_msg(path, error_key):
msg = "Unsupported config option for {}: '{}'".format(path_string(path), error_key) msg = "Unsupported config option for {}: '{}'".format(path_string(path), error_key)
if error_key in DOCKER_CONFIG_HINTS: if error_key in DOCKER_CONFIG_HINTS:

View File

@ -339,7 +339,7 @@ _docker-compose() {
'(- :)'{-h,--help}'[Get help]' \ '(- :)'{-h,--help}'[Get help]' \
'*'{-f,--file}"[${file_description}]:file:_files -g '*.yml'" \ '*'{-f,--file}"[${file_description}]:file:_files -g '*.yml'" \
'(-p --project-name)'{-p,--project-name}'[Specify an alternate project name (default: directory name)]:project name:' \ '(-p --project-name)'{-p,--project-name}'[Specify an alternate project name (default: directory name)]:project name:' \
"--compatibility[If set, Compose will attempt to convert deploy keys in v3 files to their non-Swarm equivalent]" \ "--compatibility[If set, Compose will attempt to convert keys in v3 files to their non-Swarm equivalent]" \
'(- :)'{-v,--version}'[Print version and exit]' \ '(- :)'{-v,--version}'[Print version and exit]' \
'--verbose[Show more output]' \ '--verbose[Show more output]' \
'--log-level=[Set log level]:level:(DEBUG INFO WARNING ERROR CRITICAL)' \ '--log-level=[Set log level]:level:(DEBUG INFO WARNING ERROR CRITICAL)' \

View File

@ -3593,6 +3593,9 @@ class InterpolationTest(unittest.TestCase):
'reservations': {'memory': '100M'}, 'reservations': {'memory': '100M'},
}, },
}, },
'credential_spec': {
'file': 'spec.json'
},
}, },
}, },
}) })
@ -3610,7 +3613,8 @@ class InterpolationTest(unittest.TestCase):
'mem_limit': '300M', 'mem_limit': '300M',
'mem_reservation': '100M', 'mem_reservation': '100M',
'cpus': 0.7, 'cpus': 0.7,
'name': 'foo' 'name': 'foo',
'security_opt': ['credentialspec=file://spec.json'],
} }
@mock.patch.dict(os.environ) @mock.patch.dict(os.environ)