Read service secrets as a type.

Signed-off-by: Daniel Nephin <dnephin@docker.com>
This commit is contained in:
Daniel Nephin 2017-01-04 15:58:14 -05:00
parent a82de8863e
commit add56ce818
4 changed files with 38 additions and 7 deletions

View File

@ -12,10 +12,12 @@ import six
import yaml
from cached_property import cached_property
from . import types
from ..const import COMPOSEFILE_V1 as V1
from ..const import COMPOSEFILE_V2_0 as V2_0
from ..const import COMPOSEFILE_V2_1 as V2_1
from ..const import COMPOSEFILE_V3_0 as V3_0
from ..const import COMPOSEFILE_V3_1 as V3_1
from ..utils import build_string_dict
from ..utils import parse_nanoseconds_int
from ..utils import splitdrive
@ -82,6 +84,7 @@ DOCKER_CONFIG_KEYS = [
'privileged',
'read_only',
'restart',
'secrets',
'security_opt',
'shm_size',
'stdin_open',
@ -202,8 +205,11 @@ class ConfigFile(namedtuple('_ConfigFile', 'filename config')):
def get_networks(self):
return {} if self.version == V1 else self.config.get('networks', {})
def get_secrets(self):
return {} if self.version < V3_1 else self.config.get('secrets', {})
class Config(namedtuple('_Config', 'version services volumes networks')):
class Config(namedtuple('_Config', 'version services volumes networks secrets')):
"""
:param version: configuration version
:type version: int
@ -328,6 +334,8 @@ def load(config_details):
networks = load_mapping(
config_details.config_files, 'get_networks', 'Network'
)
secrets = load_mapping(
config_details.config_files, 'get_secrets', 'Secrets')
service_dicts = load_services(config_details, main_file)
if main_file.version != V1:
@ -342,7 +350,7 @@ def load(config_details):
"`docker stack deploy` to deploy to a swarm."
.format(", ".join(sorted(s['name'] for s in services_using_deploy))))
return Config(main_file.version, service_dicts, volumes, networks)
return Config(main_file.version, service_dicts, volumes, networks, secrets)
def load_mapping(config_files, get_func, entity_type):
@ -820,6 +828,7 @@ def merge_service_dicts(base, override, version):
md.merge_mapping('sysctls', parse_sysctls)
md.merge_mapping('depends_on', parse_depends_on)
md.merge_sequence('links', ServiceLink.parse)
md.merge_sequence('secrets', types.ServiceSecret.parse)
for field in ['volumes', 'devices']:
md.merge_field(field, merge_path_mappings)

View File

@ -46,7 +46,7 @@
"type": "object",
"patternProperties": {
"^[a-zA-Z0-9._-]+$": {
"$ref": "#/definitions/secrets"
"$ref": "#/definitions/secret"
}
},
"additionalProperties": false
@ -188,8 +188,8 @@
"properties": {
"source": {"type": "string"},
"target": {"type": "string"},
"uid": {"type": "number"},
"gid": {"type": "number"},
"uid": {"type": "string"},
"gid": {"type": "string"},
"mode": {"type": "number"}
}
}

View File

@ -10,8 +10,8 @@ from collections import namedtuple
import six
from compose.config.config import V1
from compose.config.errors import ConfigurationError
from ..const import COMPOSEFILE_V1 as V1
from .errors import ConfigurationError
from compose.const import IS_WINDOWS_PLATFORM
from compose.utils import splitdrive
@ -234,3 +234,22 @@ class ServiceLink(namedtuple('_ServiceLink', 'target alias')):
@property
def merge_field(self):
return self.alias
class ServiceSecret(namedtuple('_ServiceSecret', 'source target uid gid mode')):
@classmethod
def parse(cls, spec):
if isinstance(spec, six.string_types):
return cls(spec, None, None, None, None)
return cls(
spec.get('source'),
spec.get('target'),
spec.get('uid'),
spec.get('gid'),
spec.get('mode'),
)
@property
def merge_field(self):
return self.source

View File

@ -20,12 +20,14 @@ COMPOSEFILE_V1 = '1'
COMPOSEFILE_V2_0 = '2.0'
COMPOSEFILE_V2_1 = '2.1'
COMPOSEFILE_V3_0 = '3.0'
COMPOSEFILE_V3_1 = '3.1'
API_VERSIONS = {
COMPOSEFILE_V1: '1.21',
COMPOSEFILE_V2_0: '1.22',
COMPOSEFILE_V2_1: '1.24',
COMPOSEFILE_V3_0: '1.25',
COMPOSEFILE_V3_1: '1.25',
}
API_VERSION_TO_ENGINE_VERSION = {
@ -33,4 +35,5 @@ API_VERSION_TO_ENGINE_VERSION = {
API_VERSIONS[COMPOSEFILE_V2_0]: '1.10.0',
API_VERSIONS[COMPOSEFILE_V2_1]: '1.12.0',
API_VERSIONS[COMPOSEFILE_V3_0]: '1.13.0',
API_VERSIONS[COMPOSEFILE_V3_1]: '1.13.0',
}