Add IPv4Data and IPv6Data to the schema for the network
This patch adds the newly introduced properties, IPv4Data and IPv6Data, in the request against /NetworkDriver.CreateNetwork. This patch covers only the schema change to validate the request against /NetworkDriver.CreateNetwork, and the actual logic to use the passed data and create subnets is not implemented in this patch. It will be added in the following patches. Change-Id: I4e5cf7a0c8ea97c39e5450846818806408467352 Signed-off-by: Taku Fukushima <f.tac.mac@gmail.com> Closes-Bug: #1514668
This commit is contained in:
parent
acd35ba743
commit
db80d0ef4a
|
@ -312,12 +312,32 @@ def network_driver_create_network():
|
|||
network creation to the Neutron client. libnetwork's NetworkID is used as
|
||||
the name of Network in Neutron. ::
|
||||
|
||||
{
|
||||
"NetworkID": string,
|
||||
"Options": {
|
||||
{
|
||||
"NetworkID": string,
|
||||
"IPv4Data" : [{
|
||||
"AddressSpace": string,
|
||||
"Pool": ipv4-cidr-string,
|
||||
"Gateway" : ipv4-address,
|
||||
"AuxAddresses": {
|
||||
"<identifier1>" : "<ipv4-address1>",
|
||||
"<identifier2>" : "<ipv4-address2>",
|
||||
...
|
||||
}
|
||||
}, ...],
|
||||
"IPv6Data" : [{
|
||||
"AddressSpace": string,
|
||||
"Pool": ipv6-cidr-string,
|
||||
"Gateway" : ipv6-address,
|
||||
"AuxAddresses": {
|
||||
"<identifier1>" : "<ipv6-address1>",
|
||||
"<identifier2>" : "<ipv6-address2>",
|
||||
...
|
||||
}
|
||||
}, ...],
|
||||
"Options": {
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
See the following link for more details about the spec:
|
||||
|
||||
|
|
|
@ -10,6 +10,34 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
EPSILON_PATTERN = '^$'
|
||||
IPV4_PATTERN_BASE = (u'((25[0-5]|2[0-4][0-9]|1?[0-9]?[0-9])\\.){3}'
|
||||
u'(25[0-5]|2[0-4][0-9]|1?[0-9]?[0-9])')
|
||||
IPV4_PATTERN = EPSILON_PATTERN + u'|^' + IPV4_PATTERN_BASE + u'$'
|
||||
CIDRV4_PATTERN = EPSILON_PATTERN + '|^(' + IPV4_PATTERN_BASE + \
|
||||
u'(/(1[0-2][0-8]|[1-9]?[0-9]))' + u')$'
|
||||
|
||||
IPV6_PATTERN_BASE = (u'('
|
||||
u'([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|'
|
||||
u'([0-9a-fA-F]{1,4}:){1,7}:|'
|
||||
u'([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|'
|
||||
u'([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|'
|
||||
u'([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|'
|
||||
u'([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|'
|
||||
u'([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|'
|
||||
u'[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'
|
||||
u':((:[0-9a-fA-F]{1,4}){1,7}|:)|'
|
||||
u'fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|'
|
||||
u'::(ffff(:0{1,4}){0,1}:){0,1}'
|
||||
u'((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}'
|
||||
u'(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|'
|
||||
u'([0-9a-fA-F]{1,4}:){1,4}:'
|
||||
u'((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}'
|
||||
u'(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))')
|
||||
IPV6_PATTERN = EPSILON_PATTERN + u'|^' + IPV6_PATTERN_BASE + u'$'
|
||||
CIDRV6_PATTERN = EPSILON_PATTERN + u'|^(' + IPV6_PATTERN_BASE + \
|
||||
u'(/(1[0-2][0-8]|[1-9]?[0-9]))' + u')$'
|
||||
|
||||
COMMONS = {
|
||||
u'description': u'Common data schemata shared among other schemata.',
|
||||
u'links': [],
|
||||
|
@ -29,7 +57,7 @@ COMMONS = {
|
|||
u'example': {}
|
||||
},
|
||||
u'mac': {
|
||||
u'pattern': (u'^$|'
|
||||
u'pattern': (EPSILON_PATTERN + u'|'
|
||||
u'^((?:[0-9a-f]{2}:){5}[0-9a-f]{2}|'
|
||||
u'(?:[0-9A-F]{2}:){5}[0-9A-F]{2})$'),
|
||||
u'type': u'string',
|
||||
|
@ -37,25 +65,7 @@ COMMONS = {
|
|||
u'example': u'aa:bb:cc:dd:ee:ff'
|
||||
},
|
||||
u'cidrv6': {
|
||||
u'pattern': (u'^$|'
|
||||
u'^(('
|
||||
u'([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|'
|
||||
u'([0-9a-fA-F]{1,4}:){1,7}:|'
|
||||
u'([0-9a-fA-F]{1,4}:){1,6}\:[0-9a-fA-F]{1,4}|'
|
||||
u'([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|'
|
||||
u'([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|'
|
||||
u'([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|'
|
||||
u'([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|'
|
||||
u'[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|'
|
||||
u':((:[0-9a-fA-F]{1,4}){1,7}|:)|'
|
||||
u'fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|'
|
||||
u'::(ffff(:0{1,4}){0,1}:){0,1}'
|
||||
u'((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}'
|
||||
u'(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|'
|
||||
u'([0-9a-fA-F]{1,4}:){1,4}:'
|
||||
u'((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}'
|
||||
u'(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))'
|
||||
u'(/(1[0-2][0-8]|[1-9]?[0-9])))$'),
|
||||
u'pattern': CIDRV6_PATTERN,
|
||||
u'type': u'string',
|
||||
u'description': u'A IPv6 CIDR of the subnet'
|
||||
},
|
||||
|
@ -87,10 +97,7 @@ COMMONS = {
|
|||
}
|
||||
},
|
||||
u'cidr': {
|
||||
u'pattern': (u'^$|'
|
||||
u'^((25[0-5]|2[0-4][0-9]|1?[0-9]?[0-9])\\.){3}'
|
||||
u'(25[0-5]|2[0-4][0-9]|1?[0-9]?[0-9])'
|
||||
u'/(3[0-2]|((1|2)?[0-9]))$'),
|
||||
u'pattern': CIDRV4_PATTERN,
|
||||
u'type': u'string',
|
||||
u'description': u'A IPv4 CIDR of the subnet.',
|
||||
u'example': u'10.0.0.0/24'
|
||||
|
@ -102,6 +109,114 @@ COMMONS = {
|
|||
u'example':
|
||||
u'51c75a2515d47edecc3f720bb541e287224416fb66715eb7802011d6ffd499f1'
|
||||
},
|
||||
u'ipv4': {
|
||||
u'pattern': IPV4_PATTERN,
|
||||
u'type': u'string',
|
||||
u'description': u'An IPv4 adddress',
|
||||
u'example': u'10.0.0.1'
|
||||
},
|
||||
u'ipv4datum': {
|
||||
u'description': u'IPv4 data',
|
||||
u'required': [
|
||||
u'AddressSpace', u'Pool', u'Gateway', u'AuxAddresses'],
|
||||
u'type': u'object',
|
||||
u'example': {
|
||||
u'AddressSpace': u'foo',
|
||||
u'Pool': u'192.168.42.0/24',
|
||||
u'Gateway': u'192.168.42.1/24',
|
||||
u'AuxAddresses': {
|
||||
u'web': u'192.168.42.2',
|
||||
u'db': u'192.168.42.3'
|
||||
}
|
||||
},
|
||||
u'properties': {
|
||||
u'AddressSpace': {
|
||||
u'description': u'The name of the address space.',
|
||||
u'type': u'string',
|
||||
u'example': u'foo',
|
||||
},
|
||||
u'Pool': {
|
||||
u'description': u'A range of IP Addresses represted in '
|
||||
u'CIDR format address/mask.',
|
||||
u'$ref': u'#/definitions/commons/definitions/cidr'
|
||||
},
|
||||
u'Gateway': {
|
||||
u'description': u'Optionally, the IPAM driver may provide '
|
||||
u'a Gateway for the subnet represented by '
|
||||
u'the Pool.',
|
||||
u'$ref': u'#/definitions/commons/definitions/cidr',
|
||||
},
|
||||
u'AuxAddresses': {
|
||||
u'description': u'A list of pre-allocated ip-addresses '
|
||||
u'with an associated identifier as '
|
||||
u'provided by the user to assist network '
|
||||
u'driver if it requires specific '
|
||||
u'ip-addresses for its operation.',
|
||||
u'type': u'object',
|
||||
u'patternProperties': {
|
||||
u'.+': {
|
||||
u'description': u'key-vavule pair of the ID and '
|
||||
u'the IP address',
|
||||
u'$ref': u'#/definitions/commons/definitions/ipv4'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
u'ipv6': {
|
||||
u'pattern': IPV6_PATTERN,
|
||||
u'type': u'string',
|
||||
u'description': u'An IPv6 address.',
|
||||
u'example': u'fe80::f816:3eff:fe20:57c4'
|
||||
},
|
||||
u'ipv6datum': {
|
||||
u'description': u'IPv6 data',
|
||||
u'required': [
|
||||
u'AddressSpace', u'Pool', u'Gateway', u'AuxAddresses'],
|
||||
u'type': u'object',
|
||||
u'example': {
|
||||
u'AddressCpace': u'bar',
|
||||
u'Pool': u'fe80::/64',
|
||||
u'Gateway': u'fe80::f816:3eff:fe20:57c3/64',
|
||||
u'AuxAddresses': {
|
||||
u'web': u'fe80::f816:3eff:fe20:57c4',
|
||||
u'db': u'fe80::f816:3eff:fe20:57c5'
|
||||
}
|
||||
},
|
||||
u'properties': {
|
||||
u'AddressSpace': {
|
||||
u'description': u'The name of the address space.',
|
||||
u'type': u'string',
|
||||
u'example': u'foo',
|
||||
},
|
||||
u'Pool': {
|
||||
u'description': u'A range of IP Addresses represted in '
|
||||
u'CIDR format address/mask.',
|
||||
u'$ref': u'#/definitions/commons/definitions/cidrv6'
|
||||
},
|
||||
u'Gateway': {
|
||||
u'description': u'Optionally, the IPAM driver may provide '
|
||||
u'a Gateway for the subnet represented by '
|
||||
u'the Pool.',
|
||||
u'$ref': u'#/definitions/commons/definitions/cidrv6',
|
||||
},
|
||||
u'AuxAddresses': {
|
||||
u'description': u'A list of pre-allocated ip-addresses '
|
||||
u'with an associated identifier as '
|
||||
u'provided by the user to assist network '
|
||||
u'driver if it requires specific '
|
||||
u'ip-addresses for its operation.',
|
||||
u'type': u'object',
|
||||
u'patternProperties': {
|
||||
u'.+': {
|
||||
u'description': u'key-vavule pair of the ID and '
|
||||
u'the IP address',
|
||||
u'$ref': u'#/definitions/commons/definitions/ipv6'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
u'sandbox_key': {
|
||||
u'pattern': u'^(/var/run/docker/netns/[0-9a-f]{12})$',
|
||||
u'type': u'string',
|
||||
|
|
|
@ -21,7 +21,7 @@ NETWORK_CREATE_SCHEMA = {
|
|||
u'title': u'Create'
|
||||
}],
|
||||
u'title': u'Create network',
|
||||
u'required': [u'NetworkID'],
|
||||
u'required': [u'NetworkID', u'IPv4Data', u'IPv6Data'],
|
||||
u'definitions': {u'commons': {}},
|
||||
u'$schema': u'http://json-schema.org/draft-04/hyper-schema',
|
||||
u'type': u'object',
|
||||
|
@ -30,10 +30,25 @@ NETWORK_CREATE_SCHEMA = {
|
|||
u'description': u'ID of a Network to be created',
|
||||
u'$ref': u'#/definitions/commons/definitions/id'
|
||||
},
|
||||
u'Options':
|
||||
{u'type': [u'object', u'null'],
|
||||
u'description': u'Options',
|
||||
u'example': {}}
|
||||
u'IPv4Data': {
|
||||
u'description': u'IPv4 data for the network',
|
||||
u'type': u'array',
|
||||
u'items': {
|
||||
u'$ref': u'#/definitions/commons/definitions/ipv4datum'
|
||||
}
|
||||
},
|
||||
u'IPv6Data': {
|
||||
u'description': u'IPv6 data for the network',
|
||||
u'type': u'array',
|
||||
u'items': {
|
||||
u'$ref': u'#/definitions/commons/definitions/ipv6datum'
|
||||
}
|
||||
},
|
||||
u'Options': {
|
||||
u'type': [u'object', u'null'],
|
||||
u'description': u'Options',
|
||||
u'example': {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,10 +80,25 @@ class TestKuryr(base.TestKuryrBase):
|
|||
|
||||
self.mox.ReplayAll()
|
||||
|
||||
data = {'NetworkID': docker_network_id, 'Options': {}}
|
||||
network_request = {
|
||||
'NetworkID': docker_network_id,
|
||||
'IPv4Data': [{
|
||||
'AddressSpace': 'foo',
|
||||
'Pool': '192.168.42.0/24',
|
||||
'Gateway': '192.168.42.1/24',
|
||||
'AuxAddresses': {}
|
||||
}],
|
||||
'IPv6Data': [{
|
||||
'AddressSpace': 'bar',
|
||||
'Pool': 'fe80::/64',
|
||||
'Gateway': 'fe80::f816:3eff:fe20:57c3/64',
|
||||
'AuxAddresses': {}
|
||||
}],
|
||||
'Options': {}
|
||||
}
|
||||
response = self.app.post('/NetworkDriver.CreateNetwork',
|
||||
content_type='application/json',
|
||||
data=jsonutils.dumps(data))
|
||||
data=jsonutils.dumps(network_request))
|
||||
|
||||
self.assertEqual(200, response.status_code)
|
||||
decoded_json = jsonutils.loads(response.data)
|
||||
|
|
|
@ -41,10 +41,25 @@ class TestKuryrNetworkCreateFailures(base.TestKuryrFailures):
|
|||
self.mox.ReplayAll()
|
||||
|
||||
def _invoke_create_request(self, network_name):
|
||||
data = {'NetworkID': network_name, 'Options': {}}
|
||||
network_request = {
|
||||
'NetworkID': network_name,
|
||||
'IPv4Data': [{
|
||||
'AddressSpace': 'foo',
|
||||
'Pool': '192.168.42.0/24',
|
||||
'Gateway': '192.168.42.1/24',
|
||||
'AuxAddresses': {}
|
||||
}],
|
||||
'IPv6Data': [{
|
||||
'AddressSpace': 'bar',
|
||||
'Pool': 'fe80::/64',
|
||||
'Gateway': 'fe80::f816:3eff:fe20:57c3/64',
|
||||
'AuxAddresses': {}
|
||||
}],
|
||||
'Options': {}
|
||||
}
|
||||
response = self.app.post('/NetworkDriver.CreateNetwork',
|
||||
content_type='application/json',
|
||||
data=jsonutils.dumps(data))
|
||||
data=jsonutils.dumps(network_request))
|
||||
return response
|
||||
|
||||
def test_create_network_unauthorized(self):
|
||||
|
|
Loading…
Reference in New Issue