mirror of
https://github.com/docker/compose.git
synced 2025-07-19 19:54:28 +02:00
Add format to other v3 configs & remove unix dependency
Signed-off-by: Drew Romanyk <drewiswaycool@gmail.com>
This commit is contained in:
parent
68c636d728
commit
6c8184d0d0
@ -294,7 +294,7 @@
|
|||||||
"items": {
|
"items": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"subnet": {"type": "string"}
|
"subnet": {"type": "string", "format": "subnet_ip_address"}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
|
@ -323,7 +323,7 @@
|
|||||||
"items": {
|
"items": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"subnet": {"type": "string"}
|
"subnet": {"type": "string", "format": "subnet_ip_address"}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
|
@ -368,7 +368,7 @@
|
|||||||
"items": {
|
"items": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"subnet": {"type": "string"}
|
"subnet": {"type": "string", "format": "subnet_ip_address"}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
|
@ -412,7 +412,7 @@
|
|||||||
"items": {
|
"items": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"subnet": {"type": "string"}
|
"subnet": {"type": "string", "format": "subnet_ip_address"}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
|
@ -420,7 +420,7 @@
|
|||||||
"items": {
|
"items": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"subnet": {"type": "string"}
|
"subnet": {"type": "string", "format": "subnet_ip_address"}
|
||||||
},
|
},
|
||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import json
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import socket
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import six
|
import six
|
||||||
@ -44,9 +43,32 @@ DOCKER_CONFIG_HINTS = {
|
|||||||
|
|
||||||
VALID_NAME_CHARS = '[a-zA-Z0-9\._\-]'
|
VALID_NAME_CHARS = '[a-zA-Z0-9\._\-]'
|
||||||
VALID_EXPOSE_FORMAT = r'^\d+(\-\d+)?(\/[a-zA-Z]+)?$'
|
VALID_EXPOSE_FORMAT = r'^\d+(\-\d+)?(\/[a-zA-Z]+)?$'
|
||||||
VALID_IPV4_FORMAT = r'^(\d{1,3}.){3}\d{1,3}$'
|
|
||||||
VALID_IPV4_CIDR_FORMAT = r'^(\d|[1-2]\d|3[0-2])$'
|
VALID_IPV4_SEG = r'(\d{1,2}|1\d{2}|2[0-4]\d|25[0-5])'
|
||||||
VALID_IPV6_CIDR_FORMAT = r'^(\d|[1-9]\d|1[0-1]\d|12[0-8])$'
|
VALID_REGEX_IPV4_CIDR = r'^(\d|[1-2]\d|3[0-2])$'
|
||||||
|
VALID_IPV4_ADDR = "({IPV4_SEG}\.){{3}}{IPV4_SEG}".format(IPV4_SEG=VALID_IPV4_SEG)
|
||||||
|
VALID_REGEX_IPV4_ADDR = "^{IPV4_ADDR}$".format(IPV4_ADDR=VALID_IPV4_ADDR)
|
||||||
|
|
||||||
|
VALID_IPV6_SEG = r'[0-9a-fA-F]{1,4}'
|
||||||
|
VALID_REGEX_IPV6_CIDR = r'^(\d|[1-9]\d|1[0-1]\d|12[0-8])$'
|
||||||
|
VALID_REGEX_IPV6_ADDR = "".join("""
|
||||||
|
^
|
||||||
|
(
|
||||||
|
(({IPV6_SEG}:){{7}}{IPV6_SEG})|
|
||||||
|
(({IPV6_SEG}:){{1,7}}:)|
|
||||||
|
(({IPV6_SEG}:){{1,6}}(:{IPV6_SEG}){{1,1}})|
|
||||||
|
(({IPV6_SEG}:){{1,5}}(:{IPV6_SEG}){{1,2}})|
|
||||||
|
(({IPV6_SEG}:){{1,4}}(:{IPV6_SEG}){{1,3}})|
|
||||||
|
(({IPV6_SEG}:){{1,3}}(:{IPV6_SEG}){{1,4}})|
|
||||||
|
(({IPV6_SEG}:){{1,2}}(:{IPV6_SEG}){{1,5}})|
|
||||||
|
(({IPV6_SEG}:){{1,1}}(:{IPV6_SEG}){{1,6}})|
|
||||||
|
(:((:{IPV6_SEG}){{1,7}}|:))|
|
||||||
|
(fe80:(:{IPV6_SEG}){{0,4}}%[0-9a-zA-Z]{{1,}})|
|
||||||
|
(::(ffff(:0{{1,4}}){{0,1}}:){{0,1}}{IPV4_ADDR})|
|
||||||
|
(({IPV6_SEG}:){{1,4}}:{IPV4_ADDR})
|
||||||
|
)
|
||||||
|
$
|
||||||
|
""".format(IPV6_SEG=VALID_IPV6_SEG, IPV4_ADDR=VALID_IPV4_ADDR).split())
|
||||||
|
|
||||||
|
|
||||||
@FormatChecker.cls_checks(format="ports", raises=ValidationError)
|
@FormatChecker.cls_checks(format="ports", raises=ValidationError)
|
||||||
@ -72,24 +94,18 @@ def format_expose(instance):
|
|||||||
def format_subnet_ip_address(instance):
|
def format_subnet_ip_address(instance):
|
||||||
if isinstance(instance, six.string_types):
|
if isinstance(instance, six.string_types):
|
||||||
if '/' not in instance:
|
if '/' not in instance:
|
||||||
raise ValidationError("'{0}' 75 should be of the format 'IP_ADDRESS/CIDR'".format(instance))
|
raise ValidationError("should be of the format 'IP_ADDRESS/CIDR'")
|
||||||
|
|
||||||
ip_address, cidr = instance.split('/')
|
ip_address, cidr = instance.split('/')
|
||||||
|
|
||||||
if re.match(VALID_IPV4_FORMAT, ip_address):
|
if re.match(VALID_REGEX_IPV4_ADDR, ip_address):
|
||||||
if not (re.match(VALID_IPV4_CIDR_FORMAT, cidr) and
|
if not re.match(VALID_REGEX_IPV4_CIDR, cidr):
|
||||||
all(0 <= int(component) <= 255 for component in ip_address.split("."))):
|
raise ValidationError("should be of the format 'IP_ADDRESS/CIDR'")
|
||||||
raise ValidationError(
|
elif re.match(VALID_REGEX_IPV6_ADDR, ip_address):
|
||||||
"'{0}' 83 should be of the format 'IP_ADDRESS/CIDR'".format(instance))
|
if not re.match(VALID_REGEX_IPV6_CIDR, cidr):
|
||||||
elif re.match(VALID_IPV6_CIDR_FORMAT, cidr) and hasattr(socket, "inet_pton"):
|
raise ValidationError("should be of the format 'IP_ADDRESS/CIDR'")
|
||||||
try:
|
|
||||||
if not (socket.inet_pton(socket.AF_INET6, ip_address)):
|
|
||||||
raise ValidationError(
|
|
||||||
"'{0}' 88 should be of the format 'IP_ADDRESS/CIDR'".format(instance))
|
|
||||||
except socket.error as e:
|
|
||||||
raise ValidationError(six.text_type(e))
|
|
||||||
else:
|
else:
|
||||||
raise ValidationError("'{0}' 92 should be of the format 'IP_ADDRESS/CIDR'".format(instance))
|
raise ValidationError("should be of the format 'IP_ADDRESS/CIDR'")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -2865,10 +2865,7 @@ class SubnetTest(unittest.TestCase):
|
|||||||
"fe80:0000:0000:0000:0204:61ff:fe9d:f156/129",
|
"fe80:0000:0000:0000:0204:61ff:fe9d:f156/129",
|
||||||
"fe80:0000:0000:0000:0204:61ff:fe9d:f156/01",
|
"fe80:0000:0000:0000:0204:61ff:fe9d:f156/01",
|
||||||
"fe80:0000:0000:0000:0204:61ff:fe9d:f156",
|
"fe80:0000:0000:0000:0204:61ff:fe9d:f156",
|
||||||
]
|
"ge80:0000:0000:0000:0204:61ff:fe9d:f156/128",
|
||||||
|
|
||||||
ILLEGAL_SUBNET_MAPPINGS = [
|
|
||||||
"ge80:0000:0000:0000:0204:61ff:fe9d:f156/128"
|
|
||||||
]
|
]
|
||||||
|
|
||||||
VALID_SUBNET_MAPPINGS = [
|
VALID_SUBNET_MAPPINGS = [
|
||||||
@ -2876,6 +2873,21 @@ class SubnetTest(unittest.TestCase):
|
|||||||
"192.168.0.1/32",
|
"192.168.0.1/32",
|
||||||
"fe80:0000:0000:0000:0204:61ff:fe9d:f156/0",
|
"fe80:0000:0000:0000:0204:61ff:fe9d:f156/0",
|
||||||
"fe80:0000:0000:0000:0204:61ff:fe9d:f156/128",
|
"fe80:0000:0000:0000:0204:61ff:fe9d:f156/128",
|
||||||
|
"1:2:3:4:5:6:7:8/0",
|
||||||
|
"1::/0",
|
||||||
|
"1:2:3:4:5:6:7::/0",
|
||||||
|
"1::8/0",
|
||||||
|
"1:2:3:4:5:6::8/0",
|
||||||
|
"::/0",
|
||||||
|
"::8/0",
|
||||||
|
"::2:3:4:5:6:7:8/0",
|
||||||
|
"fe80::7:8%eth0/0",
|
||||||
|
"fe80::7:8%1/0",
|
||||||
|
"::255.255.255.255/0",
|
||||||
|
"::ffff:255.255.255.255/0",
|
||||||
|
"::ffff:0:255.255.255.255/0",
|
||||||
|
"2001:db8:3:4::192.0.2.33/0",
|
||||||
|
"64:ff9b::192.0.2.33/0",
|
||||||
]
|
]
|
||||||
|
|
||||||
def test_config_invalid_subnet_type_validation(self):
|
def test_config_invalid_subnet_type_validation(self):
|
||||||
@ -2892,16 +2904,6 @@ class SubnetTest(unittest.TestCase):
|
|||||||
|
|
||||||
assert "should be of the format 'IP_ADDRESS/CIDR'" in exc.value.msg
|
assert "should be of the format 'IP_ADDRESS/CIDR'" in exc.value.msg
|
||||||
|
|
||||||
def test_config_illegal_subnet_type_validation(self):
|
|
||||||
for invalid_subnet in self.ILLEGAL_SUBNET_MAPPINGS:
|
|
||||||
with pytest.raises(ConfigurationError) as exc:
|
|
||||||
self.check_config(invalid_subnet)
|
|
||||||
if IS_WINDOWS_PLATFORM:
|
|
||||||
assert "An invalid argument was supplied" in exc.value.msg or \
|
|
||||||
"illegal IP address string" in exc.value.msg
|
|
||||||
else:
|
|
||||||
assert "illegal IP address string" in exc.value.msg
|
|
||||||
|
|
||||||
def test_config_valid_subnet_format_validation(self):
|
def test_config_valid_subnet_format_validation(self):
|
||||||
for valid_subnet in self.VALID_SUBNET_MAPPINGS:
|
for valid_subnet in self.VALID_SUBNET_MAPPINGS:
|
||||||
self.check_config(valid_subnet)
|
self.check_config(valid_subnet)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user