Merge "Support network_attach with more parameters"
This commit is contained in:
commit
15e29a81f2
@ -1026,7 +1026,9 @@ Response Codes
|
|||||||
.. rest_parameters:: parameters.yaml
|
.. rest_parameters:: parameters.yaml
|
||||||
|
|
||||||
- container_ident: container_ident
|
- container_ident: container_ident
|
||||||
- network: network
|
- network: network-query
|
||||||
|
- port: port-query
|
||||||
|
- fixed_ip: fixed_ip-query
|
||||||
|
|
||||||
Response
|
Response
|
||||||
--------
|
--------
|
||||||
|
@ -56,6 +56,13 @@ exec_run:
|
|||||||
in: query
|
in: query
|
||||||
required: false
|
required: false
|
||||||
type: boolean
|
type: boolean
|
||||||
|
fixed_ip-query:
|
||||||
|
description: |
|
||||||
|
Fixed IP addresses. If you request a specific fixed IP address without
|
||||||
|
a ``network``, the request returns a Bad Request (400) response code.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
force:
|
force:
|
||||||
description: |
|
description: |
|
||||||
Specify to delete container forcefully.
|
Specify to delete container forcefully.
|
||||||
@ -70,16 +77,31 @@ height:
|
|||||||
type: string
|
type: string
|
||||||
network:
|
network:
|
||||||
description: |
|
description: |
|
||||||
Network to be detached of the container.
|
The ID or name of the network to be detached from the container.
|
||||||
in: query
|
in: query
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
network-query:
|
||||||
|
description: |
|
||||||
|
The ID or name of the network to be attached to the container.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
new_name:
|
new_name:
|
||||||
description: |
|
description: |
|
||||||
The new name for the container.
|
The new name for the container.
|
||||||
in: query
|
in: query
|
||||||
required: true
|
required: true
|
||||||
type: string
|
type: string
|
||||||
|
port-query:
|
||||||
|
description: |
|
||||||
|
The ID or name of the port for which you want to bind to the container.
|
||||||
|
The ``network`` and ``port`` parameters are mutually exclusive.
|
||||||
|
If you do not specify the ``port`` parameter, Zun will allocate a port
|
||||||
|
and bind the port to the container.
|
||||||
|
in: query
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
ps_args:
|
ps_args:
|
||||||
description: |
|
description: |
|
||||||
The arguments of ps command.
|
The arguments of ps command.
|
||||||
|
@ -184,4 +184,34 @@ network_detach = {
|
|||||||
'additionalProperties': False
|
'additionalProperties': False
|
||||||
}
|
}
|
||||||
|
|
||||||
network_attach = copy.deepcopy(network_detach)
|
network_attach = {
|
||||||
|
'type': 'object',
|
||||||
|
'properties': {
|
||||||
|
'network': {
|
||||||
|
'type': ['string'],
|
||||||
|
'minLength': 1,
|
||||||
|
'maxLength': 255,
|
||||||
|
},
|
||||||
|
'fixed_ip': {
|
||||||
|
'type': ['string'],
|
||||||
|
'oneOf': [
|
||||||
|
{'format': 'ipv4'},
|
||||||
|
{'format': 'ipv6'}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'port': {
|
||||||
|
'type': ['string'],
|
||||||
|
'maxLength': 255,
|
||||||
|
'minLength': 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'additionalProperties': False,
|
||||||
|
'oneOf': [
|
||||||
|
{
|
||||||
|
'required': ['network']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'required': ['port']
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
@ -500,8 +500,7 @@ def build_requested_networks(context, nets):
|
|||||||
'router:external':
|
'router:external':
|
||||||
network.get('router:external'),
|
network.get('router:external'),
|
||||||
'shared': network.get('shared'),
|
'shared': network.get('shared'),
|
||||||
'v4-fixed-ip': '',
|
'fixed_ip': '',
|
||||||
'v6-fixed-ip': '',
|
|
||||||
'preserve_on_delete': True})
|
'preserve_on_delete': True})
|
||||||
elif net.get('network'):
|
elif net.get('network'):
|
||||||
network = neutron_api.get_neutron_network(net['network'])
|
network = neutron_api.get_neutron_network(net['network'])
|
||||||
@ -510,9 +509,9 @@ def build_requested_networks(context, nets):
|
|||||||
'router:external':
|
'router:external':
|
||||||
network.get('router:external'),
|
network.get('router:external'),
|
||||||
'shared': network.get('shared'),
|
'shared': network.get('shared'),
|
||||||
'v4-fixed-ip':
|
'fixed_ip':
|
||||||
net.get('v4-fixed-ip', ''),
|
net.get('fixed_ip') or
|
||||||
'v6-fixed-ip':
|
net.get('v4-fixed-ip', '') or
|
||||||
net.get('v6-fixed-ip', ''),
|
net.get('v6-fixed-ip', ''),
|
||||||
'preserve_on_delete': False})
|
'preserve_on_delete': False})
|
||||||
if not requested_networks:
|
if not requested_networks:
|
||||||
@ -521,8 +520,7 @@ def build_requested_networks(context, nets):
|
|||||||
neutron_net = neutron_api.get_available_network()
|
neutron_net = neutron_api.get_available_network()
|
||||||
requested_networks.append({'network': neutron_net['id'],
|
requested_networks.append({'network': neutron_net['id'],
|
||||||
'port': '',
|
'port': '',
|
||||||
'v4-fixed-ip': '',
|
'fixed_ip': '',
|
||||||
'v6-fixed-ip': '',
|
|
||||||
'preserve_on_delete': False})
|
'preserve_on_delete': False})
|
||||||
|
|
||||||
check_external_network_attach(context, requested_networks)
|
check_external_network_attach(context, requested_networks)
|
||||||
|
@ -229,8 +229,7 @@ class KuryrNetwork(network.Network):
|
|||||||
'tenant_id': self.context.project_id,
|
'tenant_id': self.context.project_id,
|
||||||
'device_id': container.uuid,
|
'device_id': container.uuid,
|
||||||
}
|
}
|
||||||
ip_addr = requested_network.get("v4-fixed-ip") or requested_network.\
|
ip_addr = requested_network.get("fixed_ip")
|
||||||
get("v6-fixed-ip")
|
|
||||||
if ip_addr:
|
if ip_addr:
|
||||||
port_dict['fixed_ips'] = [{'ip_address': ip_addr}]
|
port_dict['fixed_ips'] = [{'ip_address': ip_addr}]
|
||||||
if security_groups is not None:
|
if security_groups is not None:
|
||||||
|
@ -1811,6 +1811,81 @@ class TestContainerController(api_base.FunctionalTest):
|
|||||||
"use an ID to be more specific." % security_group_to_add,
|
"use an ID to be more specific." % security_group_to_add,
|
||||||
response.json['errors'][0]['detail'])
|
response.json['errors'][0]['detail'])
|
||||||
|
|
||||||
|
@patch('zun.network.neutron.NeutronAPI.get_neutron_network')
|
||||||
|
@patch('zun.compute.api.API.network_attach')
|
||||||
|
@patch('zun.objects.Container.get_by_uuid')
|
||||||
|
def test_network_attach(self, mock_by_uuid, mock_attach, mock_get_network):
|
||||||
|
built_requested_network = {
|
||||||
|
'network': 'fake-net-id',
|
||||||
|
'port': '',
|
||||||
|
'router:external': False,
|
||||||
|
'shared': False,
|
||||||
|
'fixed_ip': '',
|
||||||
|
'preserve_on_delete': False}
|
||||||
|
query = 'network=private'
|
||||||
|
self._test_network_attach(mock_by_uuid, mock_attach, mock_get_network,
|
||||||
|
query, built_requested_network)
|
||||||
|
mock_get_network.assert_called_once_with('private')
|
||||||
|
|
||||||
|
@patch('zun.network.neutron.NeutronAPI.get_neutron_network')
|
||||||
|
@patch('zun.compute.api.API.network_attach')
|
||||||
|
@patch('zun.objects.Container.get_by_uuid')
|
||||||
|
def test_network_attach_with_fixed_ip(self, mock_by_uuid, mock_attach,
|
||||||
|
mock_get_network):
|
||||||
|
built_requested_network = {
|
||||||
|
'network': 'fake-net-id',
|
||||||
|
'port': '',
|
||||||
|
'router:external': False,
|
||||||
|
'shared': False,
|
||||||
|
'fixed_ip': '10.0.0.3',
|
||||||
|
'preserve_on_delete': False}
|
||||||
|
query = 'network=private&fixed_ip=10.0.0.3'
|
||||||
|
self._test_network_attach(mock_by_uuid, mock_attach, mock_get_network,
|
||||||
|
query, built_requested_network)
|
||||||
|
mock_get_network.assert_called_once_with('private')
|
||||||
|
|
||||||
|
@patch('zun.network.neutron.NeutronAPI.get_neutron_port')
|
||||||
|
@patch('zun.network.neutron.NeutronAPI.ensure_neutron_port_usable')
|
||||||
|
@patch('zun.network.neutron.NeutronAPI.get_neutron_network')
|
||||||
|
@patch('zun.compute.api.API.network_attach')
|
||||||
|
@patch('zun.objects.Container.get_by_uuid')
|
||||||
|
def test_network_attach_with_port(self, mock_by_uuid, mock_attach,
|
||||||
|
mock_get_network,
|
||||||
|
mock_ensure, mock_get_port):
|
||||||
|
mock_get_port.return_value = {
|
||||||
|
'id': 'fake-port-id',
|
||||||
|
'network_id': 'fake-net-id',
|
||||||
|
}
|
||||||
|
built_requested_network = {
|
||||||
|
'network': 'fake-net-id',
|
||||||
|
'port': 'fake-port-id',
|
||||||
|
'router:external': False,
|
||||||
|
'shared': False,
|
||||||
|
'fixed_ip': '',
|
||||||
|
'preserve_on_delete': True}
|
||||||
|
query = 'port=fake-port'
|
||||||
|
self._test_network_attach(mock_by_uuid, mock_attach, mock_get_network,
|
||||||
|
query, built_requested_network)
|
||||||
|
mock_get_port.assert_called_once_with('fake-port')
|
||||||
|
mock_get_network.assert_called_once_with('fake-net-id')
|
||||||
|
|
||||||
|
def _test_network_attach(self, mock_by_uuid, mock_attach, mock_get_network,
|
||||||
|
query, built_requested_network):
|
||||||
|
test_container = utils.get_test_container()
|
||||||
|
test_container_obj = objects.Container(self.context, **test_container)
|
||||||
|
mock_by_uuid.return_value = test_container_obj
|
||||||
|
container_uuid = test_container.get('uuid')
|
||||||
|
fake_network = {'id': 'fake-net-id',
|
||||||
|
'router:external': False,
|
||||||
|
'shared': False}
|
||||||
|
mock_get_network.return_value = fake_network
|
||||||
|
url = '/v1/containers/%s/%s?%s' % (container_uuid, 'network_attach',
|
||||||
|
query)
|
||||||
|
response = self.post(url)
|
||||||
|
self.assertEqual(200, response.status_int)
|
||||||
|
mock_attach.assert_called_once_with(mock.ANY, test_container_obj,
|
||||||
|
built_requested_network)
|
||||||
|
|
||||||
@patch('zun.network.neutron.NeutronAPI.get_neutron_network')
|
@patch('zun.network.neutron.NeutronAPI.get_neutron_network')
|
||||||
@patch('zun.compute.api.API.network_detach')
|
@patch('zun.compute.api.API.network_detach')
|
||||||
@patch('zun.objects.Container.get_by_uuid')
|
@patch('zun.objects.Container.get_by_uuid')
|
||||||
|
@ -798,8 +798,7 @@ class TestDockerDriver(base.DriverTestCase):
|
|||||||
mock_list.return_value = {'network': 'network'}
|
mock_list.return_value = {'network': 'network'}
|
||||||
requested_network = {'network': 'network',
|
requested_network = {'network': 'network',
|
||||||
'port': '',
|
'port': '',
|
||||||
'v4-fixed-ip': '',
|
'fixed_ip': '',
|
||||||
'v6-fixed-ip': '',
|
|
||||||
'preserve_on_delete': False}
|
'preserve_on_delete': False}
|
||||||
self.driver.network_attach(self.context, mock_container,
|
self.driver.network_attach(self.context, mock_container,
|
||||||
requested_network)
|
requested_network)
|
||||||
@ -814,8 +813,7 @@ class TestDockerDriver(base.DriverTestCase):
|
|||||||
mock_container.addresses = {'already-attached-net': []}
|
mock_container.addresses = {'already-attached-net': []}
|
||||||
requested_network = {'network': 'already-attached-net',
|
requested_network = {'network': 'already-attached-net',
|
||||||
'port': '',
|
'port': '',
|
||||||
'v4-fixed-ip': '',
|
'fixed_ip': '',
|
||||||
'v6-fixed-ip': '',
|
|
||||||
'preserve_on_delete': False}
|
'preserve_on_delete': False}
|
||||||
self.assertRaises(exception.ZunException,
|
self.assertRaises(exception.ZunException,
|
||||||
self.driver.network_attach,
|
self.driver.network_attach,
|
||||||
@ -837,8 +835,7 @@ class TestDockerDriver(base.DriverTestCase):
|
|||||||
mock_get_sec_group_id.return_value = test_sec_group_id
|
mock_get_sec_group_id.return_value = test_sec_group_id
|
||||||
requested_network = {'network': 'network',
|
requested_network = {'network': 'network',
|
||||||
'port': '',
|
'port': '',
|
||||||
'v4-fixed-ip': '',
|
'fixed_ip': '',
|
||||||
'v6-fixed-ip': '',
|
|
||||||
'preserve_on_delete': False}
|
'preserve_on_delete': False}
|
||||||
self.driver.network_attach(self.context, mock_container,
|
self.driver.network_attach(self.context, mock_container,
|
||||||
requested_network)
|
requested_network)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user