Neutron cli support for gateway device
Python-neutronclient extension supports the following resources. * gateway-device * remote-mac-entry Change-Id: Ic310d9b632dc127e474da8bc56787752b69f0ee0 Closes-Bug: #1555205
This commit is contained in:
110
midonet/neutron/tests/unit/neutronclient_ext/test_cli20.py
Normal file
110
midonet/neutron/tests/unit/neutronclient_ext/test_cli20.py
Normal file
@@ -0,0 +1,110 @@
|
||||
# Copyright (C) 2016 Midokura SARL
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import mock
|
||||
from mox3 import mox
|
||||
|
||||
from neutronclient import shell
|
||||
from neutronclient.tests.unit import test_cli20
|
||||
|
||||
TOKEN = test_cli20.TOKEN
|
||||
|
||||
|
||||
class MyResp(test_cli20.MyResp):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class MyApp(test_cli20.MyApp):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class MyComparator(test_cli20.MyComparator):
|
||||
|
||||
pass
|
||||
|
||||
|
||||
class CLIExtTestV20Base(test_cli20.CLITestV20Base):
|
||||
|
||||
def setUp(self, plurals=None):
|
||||
super(CLIExtTestV20Base, self).setUp(plurals=plurals)
|
||||
|
||||
def _setup_mock_patch(self, name):
|
||||
patcher = mock.patch(name)
|
||||
thing = patcher.start()
|
||||
self.addCleanup(patcher.stop)
|
||||
return thing
|
||||
|
||||
def _mock_load_extensions(self, resource):
|
||||
load_method = ('neutronclient.common.extension.' +
|
||||
'_discover_via_entry_points')
|
||||
load_ext_mock = self._setup_mock_patch(load_method)
|
||||
load_ext_mock.return_value = [resource]
|
||||
return load_ext_mock
|
||||
|
||||
def _test_show_ext_resource(self, resource, cmd, myid, args, fields=(),
|
||||
cmd_resource=None, parent_id=None):
|
||||
self.mox.StubOutWithMock(cmd, "get_client")
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
cmd.get_client().MultipleTimes().AndReturn(self.client)
|
||||
if not cmd_resource:
|
||||
cmd_resource = resource
|
||||
|
||||
query = "&".join(["fields=%s" % field for field in fields])
|
||||
expected_res = {resource:
|
||||
{self.id_field: myid,
|
||||
'name': 'myname', }, }
|
||||
resstr = self.client.serialize(expected_res)
|
||||
path = getattr(self.client, cmd_resource + "_path")
|
||||
if parent_id:
|
||||
path = path % parent_id
|
||||
path = path % myid
|
||||
self.client.httpclient.request(
|
||||
test_cli20.end_url(path, query, format=self.format), 'GET',
|
||||
body=None,
|
||||
headers=mox.ContainsKeyValue(
|
||||
'X-Auth-Token', TOKEN)).AndReturn((MyResp(200), resstr))
|
||||
self.mox.ReplayAll()
|
||||
cmd_parser = cmd.get_parser("show_" + cmd_resource)
|
||||
shell.run_command(cmd, cmd_parser, args)
|
||||
self.mox.VerifyAll()
|
||||
self.mox.UnsetStubs()
|
||||
_str = self.fake_stdout.make_string()
|
||||
self.assertIn(myid, _str)
|
||||
self.assertIn('myname', _str)
|
||||
|
||||
def _test_delete_ext_resource(self, resource, cmd, myid, args,
|
||||
cmd_resource=None, parent_id=None):
|
||||
self.mox.StubOutWithMock(cmd, "get_client")
|
||||
self.mox.StubOutWithMock(self.client.httpclient, "request")
|
||||
cmd.get_client().MultipleTimes().AndReturn(self.client)
|
||||
if not cmd_resource:
|
||||
cmd_resource = resource
|
||||
path = getattr(self.client, cmd_resource + "_path")
|
||||
if parent_id:
|
||||
path = path % parent_id
|
||||
path = path % myid
|
||||
self.client.httpclient.request(
|
||||
test_cli20.end_url(path, format=self.format), 'DELETE',
|
||||
body=None,
|
||||
headers=mox.ContainsKeyValue(
|
||||
'X-Auth-Token', TOKEN)).AndReturn((MyResp(204), None))
|
||||
self.mox.ReplayAll()
|
||||
cmd_parser = cmd.get_parser("delete_" + cmd_resource)
|
||||
shell.run_command(cmd, cmd_parser, args)
|
||||
self.mox.VerifyAll()
|
||||
self.mox.UnsetStubs()
|
||||
_str = self.fake_stdout.make_string()
|
||||
self.assertIn(myid, _str)
|
||||
@@ -0,0 +1,193 @@
|
||||
# Copyright (C) 2016 Midokura SARL
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import sys
|
||||
|
||||
from midonet.neutron.tests.unit.neutronclient_ext import test_cli20
|
||||
from midonet.neutronclient.gateway_device_extension import _gateway_device
|
||||
from neutronclient import shell
|
||||
|
||||
|
||||
class CLITestV20GatewayDeviceJSON(test_cli20.CLIExtTestV20Base):
|
||||
|
||||
def setUp(self):
|
||||
gw_device = ("gateway_device", _gateway_device)
|
||||
self._mock_load_extensions(gw_device)
|
||||
super(CLITestV20GatewayDeviceJSON,
|
||||
self).setUp(plurals={'gateway_devices': 'gateway_device'})
|
||||
self.register_non_admin_status_resource('gateway_device')
|
||||
|
||||
def test_gateway_device_cmd_loaded(self):
|
||||
shell.NeutronShell('2.0')
|
||||
gw_device_cmd = {'gateway-device-list':
|
||||
_gateway_device.GatewayDeviceList,
|
||||
'gateway-device-create':
|
||||
_gateway_device.GatewayDeviceCreate,
|
||||
'gateway-device-update':
|
||||
_gateway_device.GatewayDeviceUpdate,
|
||||
'gateway-device-delete':
|
||||
_gateway_device.GatewayDeviceDelete,
|
||||
'gateway-device-show':
|
||||
_gateway_device.GatewayDeviceShow
|
||||
}
|
||||
self.assertDictContainsSubset(gw_device_cmd, shell.COMMANDS['2.0'])
|
||||
|
||||
def _create_gateway_device(self, name, args,
|
||||
position_names, position_values):
|
||||
resource = 'gateway_device'
|
||||
cmd = _gateway_device.GatewayDeviceCreate(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_create_resource(resource, cmd, name, 'myid',
|
||||
args, position_names, position_values)
|
||||
|
||||
def _update_gateway_device(self, args, values):
|
||||
resource = 'gateway_device'
|
||||
cmd = _gateway_device.GatewayDeviceUpdate(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_update_resource(resource, cmd, 'myid',
|
||||
args, values)
|
||||
|
||||
def test_create_gateway_device_for_hw_vtep_mandatory_params(self):
|
||||
name = 'hw-vtep-mandatory'
|
||||
gw_type = 'hw_vtep'
|
||||
mng_ip = '10.0.0.100'
|
||||
mng_port = '22'
|
||||
mng_protocol = 'ovsdb'
|
||||
args = ['--type', gw_type,
|
||||
'--management-ip', mng_ip,
|
||||
'--management-port', mng_port,
|
||||
'--management-protocol', mng_protocol]
|
||||
position_names = ['type', 'management_ip',
|
||||
'management_port', 'management_protocol']
|
||||
position_values = [gw_type, mng_ip, mng_port, mng_protocol]
|
||||
self._create_gateway_device(name, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_gateway_device_for_hw_vtep_with_optional_params(self):
|
||||
name = 'hw-vtep-optional'
|
||||
tenant_id = 'my_tenant'
|
||||
gw_type = 'hw_vtep'
|
||||
mng_ip = '10.0.0.100'
|
||||
mng_port = '22'
|
||||
mng_protocol = 'ovsdb'
|
||||
tunnel_ip = '200.200.200.4'
|
||||
args = ['--tenant-id', tenant_id,
|
||||
'--type', gw_type,
|
||||
'--management-ip', mng_ip,
|
||||
'--management-port', mng_port,
|
||||
'--management-protocol', mng_protocol,
|
||||
'--name', name,
|
||||
'--tunnel-ip', tunnel_ip]
|
||||
position_names = ['type', 'management_ip', 'management_port',
|
||||
'management_protocol', 'tenant_id',
|
||||
'name', 'tunnel_ips']
|
||||
position_values = [gw_type, mng_ip, mng_port, mng_protocol,
|
||||
tenant_id, name, [tunnel_ip]]
|
||||
self._create_gateway_device(name, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_gateway_device_for_router_vtep_with_mandatory_params(self):
|
||||
name = 'router-vtep-mandatory'
|
||||
gw_type = 'router_vtep'
|
||||
resource_id = 'my_router_id'
|
||||
args = ['--type', gw_type, '--resource-id', resource_id]
|
||||
position_names = ['type', 'resource_id']
|
||||
position_values = [gw_type, resource_id]
|
||||
self._create_gateway_device(name, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_create_gateway_device_for_router_vtep_with_optional_params(self):
|
||||
name = 'router-vtep-optional'
|
||||
tenant_id = 'my_tenant'
|
||||
gw_type = 'router_vtep'
|
||||
resource_id = 'my_router_id'
|
||||
tunnel_ip = '200.200.200.4'
|
||||
args = ['--tenant-id', tenant_id,
|
||||
'--type', gw_type,
|
||||
'--resource-id', resource_id,
|
||||
'--name', name,
|
||||
'--tunnel-ip', tunnel_ip]
|
||||
position_names = ['type', 'resource_id',
|
||||
'tenant_id', 'name', 'tunnel_ips']
|
||||
position_values = [gw_type, resource_id,
|
||||
tenant_id, name, [tunnel_ip]]
|
||||
self._create_gateway_device(name, args,
|
||||
position_names, position_values)
|
||||
|
||||
def test_update_gateway_device_with_name(self):
|
||||
args = ['myid', '--name', 'name_updated']
|
||||
values = {'name': 'name_updated'}
|
||||
self._update_gateway_device(args, values)
|
||||
|
||||
def test_update_gateway_device_with_tunnel_ip(self):
|
||||
args = ['myid', '--tunnel-ip', '200.200.200.4']
|
||||
values = {'tunnel_ips': ['200.200.200.4']}
|
||||
self._update_gateway_device(args, values)
|
||||
|
||||
def test_update_gateway_device_with_tunnel_ips(self):
|
||||
args = ['myid', '--tunnel-ip', '200.200.200.4',
|
||||
'--tunnel-ip', '200.200.200.10']
|
||||
values = {'tunnel_ips': ['200.200.200.4',
|
||||
'200.200.200.10']}
|
||||
self._update_gateway_device(args, values)
|
||||
|
||||
def test_delete_gateway_device(self):
|
||||
resource = 'gateway_device'
|
||||
cmd = _gateway_device.GatewayDeviceDelete(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
my_id = 'my-id'
|
||||
args = [my_id]
|
||||
self._test_delete_resource(resource, cmd, my_id, args)
|
||||
|
||||
def test_list_gateway_devices(self):
|
||||
resources = 'gateway_devices'
|
||||
cmd = _gateway_device.GatewayDeviceList(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources(resources, cmd)
|
||||
|
||||
def test_list_gateway_devices_with_pagination(self):
|
||||
resources = 'gateway_devices'
|
||||
cmd = _gateway_device.GatewayDeviceList(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_list_resources_with_pagination(resources, cmd)
|
||||
|
||||
def test_list_gateway_device_with_remote_mac_entries(self):
|
||||
resources = 'gateway_devices'
|
||||
cmd = _gateway_device.GatewayDeviceList(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
rme = [{"segmentation_id": 100,
|
||||
"vtep_address": "192.168.100.1",
|
||||
"id": "remote_mac_entry_id1",
|
||||
"mac_address": "fa:16:3e:db:79:80"},
|
||||
{"segmentation_id": 100,
|
||||
"vtep_address": "192.168.100.50",
|
||||
"id": "remote_mac_entry_id1",
|
||||
"mac_address": "fa:16:3e:df:79:80"},
|
||||
]
|
||||
response = {'gateway_devices': [{"id": 'myid',
|
||||
"name": 'gw_device',
|
||||
"type": "router_vtep",
|
||||
"resource_id": "router_id",
|
||||
"tunnel_ips": [],
|
||||
"remote_mac_entries": rme}]}
|
||||
args = ['-c', 'id', '-c', 'remote_mac_entries']
|
||||
self._test_list_columns(cmd, resources, response, args)
|
||||
|
||||
def test_show_gateway_device(self):
|
||||
resource = 'gateway_device'
|
||||
cmd = _gateway_device.GatewayDeviceShow(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||
self._test_show_resource(resource, cmd, self.test_id, args,
|
||||
['id', 'name'])
|
||||
@@ -0,0 +1,115 @@
|
||||
# Copyright (C) 2016 Midokura SARL
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import sys
|
||||
|
||||
from midonet.neutron.tests.unit.neutronclient_ext import test_cli20
|
||||
from midonet.neutronclient.gateway_device_extension import _remote_mac_entry
|
||||
from neutronclient import shell
|
||||
|
||||
|
||||
class CLITestV20RemoteMacEntryJSON(test_cli20.CLIExtTestV20Base):
|
||||
|
||||
def setUp(self):
|
||||
remote_mac_entry = ("remote_mac_entry", _remote_mac_entry)
|
||||
self._mock_load_extensions(remote_mac_entry)
|
||||
super(CLITestV20RemoteMacEntryJSON,
|
||||
self).setUp(plurals={'remote_mac_entries': 'remote_mac_entry'})
|
||||
self.register_non_admin_status_resource('remote_mac_entry')
|
||||
|
||||
def test_remote_mac_entry_cmd_loaded(self):
|
||||
shell.NeutronShell('2.0')
|
||||
remote_mac_entry_cmd = {'gateway-device-remote-mac-entry-list':
|
||||
_remote_mac_entry.RemoteMacEntryList,
|
||||
'gateway-device-remote-mac-entry-create':
|
||||
_remote_mac_entry.RemoteMacEntryCreate,
|
||||
'gateway-device-remote-mac-entry-delete':
|
||||
_remote_mac_entry.RemoteMacEntryDelete,
|
||||
'gateway-device-remote-mac-entry-show':
|
||||
_remote_mac_entry.RemoteMacEntryShow}
|
||||
self.assertDictContainsSubset(remote_mac_entry_cmd,
|
||||
shell.COMMANDS['2.0'])
|
||||
|
||||
def _create_remote_mac_entry(self, args, position_names,
|
||||
position_values, parent_id=None):
|
||||
resource = 'remote_mac_entry'
|
||||
cmd = _remote_mac_entry.RemoteMacEntryCreate(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
self._test_create_resource(resource, cmd, None, 'myid',
|
||||
args, position_names, position_values,
|
||||
parent_id=parent_id)
|
||||
|
||||
def test_create_remote_mac_entry(self):
|
||||
gw_device_id = 'my_gw_device'
|
||||
mac_addr = 'fa:16:3e:db:79:80'
|
||||
vtep_addr = '192.168.100.1'
|
||||
seg_id = '200'
|
||||
args = ['--mac-address', mac_addr, '--vtep-address', vtep_addr,
|
||||
'--segmentation-id', seg_id, gw_device_id]
|
||||
position_names = ['mac_address', 'vtep_address', 'segmentation_id']
|
||||
position_values = [mac_addr, vtep_addr, seg_id]
|
||||
self._create_remote_mac_entry(args, position_names,
|
||||
position_values, parent_id=gw_device_id)
|
||||
|
||||
def test_create_remote_mac_entry_with_missing_gw_device_id(self):
|
||||
mac_addr = ''
|
||||
vtep_addr = ''
|
||||
seg_id = '200'
|
||||
args = ['--mac-address', mac_addr,
|
||||
'--vtep-address', vtep_addr, '--segmentation-id', seg_id]
|
||||
position_names = []
|
||||
position_values = []
|
||||
self.assertRaises(SystemExit, self._create_remote_mac_entry,
|
||||
args, position_names, position_values)
|
||||
|
||||
def test_create_remote_mac_entry_with_missing_seg_id(self):
|
||||
gw_device_id = 'my_gw_device'
|
||||
mac_addr = ''
|
||||
vtep_addr = ''
|
||||
args = ['--mac-address', mac_addr, '--vtep-address', vtep_addr,
|
||||
gw_device_id]
|
||||
position_names = []
|
||||
position_values = []
|
||||
self.assertRaises(SystemExit, self._create_remote_mac_entry,
|
||||
args, position_names, position_values,
|
||||
parent_id=gw_device_id)
|
||||
|
||||
def test_delete_remote_mac_entry(self):
|
||||
resource = 'remote_mac_entry'
|
||||
cmd = _remote_mac_entry.RemoteMacEntryDelete(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
gw_device_id = 'my_gw_device'
|
||||
my_id = 'myid'
|
||||
args = [my_id, gw_device_id]
|
||||
self._test_delete_ext_resource(resource, cmd, my_id, args,
|
||||
parent_id=gw_device_id)
|
||||
|
||||
def test_list_remote_mac_entries(self):
|
||||
resources = 'remote_mac_entries'
|
||||
cmd = _remote_mac_entry.RemoteMacEntryList(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
gw_device_id = 'my_gw_device'
|
||||
args = [gw_device_id]
|
||||
self._test_list_resources(resources, cmd, base_args=args,
|
||||
parent_id=gw_device_id)
|
||||
|
||||
def test_show_remote_mac_entry(self):
|
||||
resource = 'remote_mac_entry'
|
||||
cmd = _remote_mac_entry.RemoteMacEntryShow(
|
||||
test_cli20.MyApp(sys.stdout), None)
|
||||
gw_device_id = 'my_gw_device'
|
||||
my_id = 'myid'
|
||||
args = [my_id, gw_device_id]
|
||||
self._test_show_ext_resource(resource, cmd, my_id, args,
|
||||
parent_id=gw_device_id)
|
||||
0
midonet/neutronclient/__init__.py
Normal file
0
midonet/neutronclient/__init__.py
Normal file
@@ -0,0 +1,133 @@
|
||||
# Copyright (C) 2016 Midokura SARL
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
from midonet.neutron._i18n import _
|
||||
|
||||
from neutronclient.common import extension
|
||||
from neutronclient.neutron import v2_0 as gw_deviceV20
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
|
||||
|
||||
def add_name_and_tunnel_ips_to_arguments(parser):
|
||||
parser.add_argument(
|
||||
'--name', dest='name',
|
||||
help=_('User defined device name.'))
|
||||
parser.add_argument(
|
||||
'--tunnel-ip', metavar='TUNNEL_IP',
|
||||
action='append', dest='tunnel_ips',
|
||||
help=_('IP address on which gateway device originates or '
|
||||
'terminates tunnel.'))
|
||||
|
||||
|
||||
def _format_remote_mac_entries(gw_device):
|
||||
try:
|
||||
return '\n'.join([jsonutils.dumps(rm_entry) for rm_entry
|
||||
in gw_device['remote_mac_entries']])
|
||||
except (TypeError, KeyError):
|
||||
return ''
|
||||
|
||||
|
||||
class GatewayDevice(extension.NeutronClientExtension):
|
||||
resource = 'gateway_device'
|
||||
resource_plural = 'gateway_devices'
|
||||
path = 'gw/gateway_devices'
|
||||
object_path = '/%s' % path
|
||||
resource_path = '/%s/%%s' % path
|
||||
versions = ['2.0']
|
||||
|
||||
|
||||
class GatewayDeviceCreate(extension.ClientExtensionCreate, GatewayDevice):
|
||||
"""Create Gateway Device information."""
|
||||
|
||||
shell_command = 'gateway-device-create'
|
||||
|
||||
def add_known_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'--management-ip',
|
||||
dest='management_ip',
|
||||
help=_('Management IP to the device. Defaults to None.'))
|
||||
parser.add_argument(
|
||||
'--management-port',
|
||||
dest='management_port',
|
||||
help=_('Management port to the device. Defaults to None.'))
|
||||
parser.add_argument(
|
||||
'--management-protocol',
|
||||
dest='management_protocol',
|
||||
help=_('Management protocol to manage the device: ovsdb or none. '
|
||||
'If management ip and port are specified, '
|
||||
'defaults to ovsdb. Otherwise to none.'))
|
||||
parser.add_argument(
|
||||
'--type',
|
||||
metavar='<hw_vtep | router_vtep>',
|
||||
choices=['hw_vtep', 'router_vtep'],
|
||||
help=_('Type of the device: hw_vtep or router_vtep. '
|
||||
'Defaults to hw_vtep'))
|
||||
parser.add_argument(
|
||||
'--resource-id',
|
||||
dest='resource_id',
|
||||
help=_('Resource UUID or None (for type router_vtep will '
|
||||
'be router UUID)'))
|
||||
add_name_and_tunnel_ips_to_arguments(parser)
|
||||
|
||||
return parser
|
||||
|
||||
def args2body(self, args):
|
||||
body = {}
|
||||
attributes = ['name', 'type', 'management_ip',
|
||||
'management_port', 'management_protocol',
|
||||
'resource_id', 'tenant_id', 'tunnel_ips']
|
||||
gw_deviceV20.update_dict(args, body, attributes)
|
||||
|
||||
return {'gateway_device': body}
|
||||
|
||||
|
||||
class GatewayDeviceList(extension.ClientExtensionList, GatewayDevice):
|
||||
"""List Gateway Devices."""
|
||||
|
||||
shell_command = 'gateway-device-list'
|
||||
list_columns = ['id', 'name', 'type', 'resource_id', 'tunnel_ips']
|
||||
pagination_support = True
|
||||
sorting_support = True
|
||||
|
||||
_formatters = {'remote_mac_entries': _format_remote_mac_entries, }
|
||||
|
||||
|
||||
class GatewayDeviceShow(extension.ClientExtensionShow, GatewayDevice):
|
||||
"""Show information of a given gateway-device."""
|
||||
|
||||
shell_command = 'gateway-device-show'
|
||||
|
||||
|
||||
class GatewayDeviceDelete(extension.ClientExtensionDelete, GatewayDevice):
|
||||
"""Delete a given gateway-device."""
|
||||
|
||||
shell_command = 'gateway-device-delete'
|
||||
|
||||
|
||||
class GatewayDeviceUpdate(extension.ClientExtensionUpdate, GatewayDevice):
|
||||
"""Update a given gateway-device."""
|
||||
|
||||
shell_command = 'gateway-device-update'
|
||||
|
||||
def add_known_arguments(self, parser):
|
||||
add_name_and_tunnel_ips_to_arguments(parser)
|
||||
|
||||
def args2body(self, args):
|
||||
body = {}
|
||||
attributes = ['name', 'tunnel_ips']
|
||||
gw_deviceV20.update_dict(args, body, attributes)
|
||||
|
||||
return {'gateway_device': body}
|
||||
@@ -0,0 +1,93 @@
|
||||
# Copyright (C) 2016 Midokura SARL
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from neutronclient.common import extension
|
||||
from neutronclient.i18n import _
|
||||
from neutronclient.neutron import v2_0 as gw_deviceV20
|
||||
|
||||
|
||||
def _get_gateway_device_id(client, gw_device_id_or_name):
|
||||
return gw_deviceV20.find_resourceid_by_name_or_id(client, 'gateway_device',
|
||||
gw_device_id_or_name)
|
||||
|
||||
|
||||
class RemoteMacEntry(extension.NeutronClientExtension):
|
||||
parent_resource = 'gateway_devices'
|
||||
resource = 'remote_mac_entry'
|
||||
resource_plural = 'remote_mac_entries'
|
||||
object_path = '/gw/%s/%%s/%s' % (parent_resource, resource_plural)
|
||||
resource_path = '/gw/%s/%%s/%s/%%%%s' % (parent_resource, resource_plural)
|
||||
versions = ['2.0']
|
||||
|
||||
def add_known_arguments(self, parser):
|
||||
parser.add_argument(
|
||||
'gateway_device', metavar='GATEWAY_DEVICE',
|
||||
help=_('ID of the gateway device.'))
|
||||
|
||||
def set_extra_attrs(self, parsed_args):
|
||||
self.parent_id = _get_gateway_device_id(self.get_client(),
|
||||
parsed_args.gateway_device)
|
||||
|
||||
|
||||
class RemoteMacEntryCreate(extension.ClientExtensionCreate, RemoteMacEntry):
|
||||
"""Create Gateway Device Remote Mac Entry information."""
|
||||
|
||||
shell_command = 'gateway-device-remote-mac-entry-create'
|
||||
|
||||
def get_parser(self, parser):
|
||||
parser = super(gw_deviceV20.CreateCommand, self).get_parser(parser)
|
||||
parser.add_argument(
|
||||
'--mac-address', dest='mac_address',
|
||||
required=True,
|
||||
help=_('Remote MAC address'))
|
||||
parser.add_argument(
|
||||
'--vtep-address', dest='vtep_address',
|
||||
required=True,
|
||||
help=_('Remote VTEP Tunnel IP'))
|
||||
parser.add_argument(
|
||||
'--segmentation-id', dest='segmentation_id',
|
||||
required=True,
|
||||
help=_('VNI to be used'))
|
||||
self.add_known_arguments(parser)
|
||||
return parser
|
||||
|
||||
def args2body(self, args):
|
||||
body = {}
|
||||
attributes = ['mac_address', 'vtep_address', 'segmentation_id']
|
||||
gw_deviceV20.update_dict(args, body, attributes)
|
||||
return {'remote_mac_entry': body}
|
||||
|
||||
|
||||
class RemoteMacEntryList(extension.ClientExtensionList, RemoteMacEntry):
|
||||
"""List Gateway Device Remote Mac Entries."""
|
||||
|
||||
shell_command = 'gateway-device-remote-mac-entry-list'
|
||||
list_columns = ['id', 'mac_address', 'vtep_address', 'segmentation_id']
|
||||
pagination_support = True
|
||||
sorting_support = True
|
||||
|
||||
|
||||
class RemoteMacEntryShow(extension.ClientExtensionShow, RemoteMacEntry):
|
||||
"""Show information of a given gateway-device-remote-mac-entry."""
|
||||
|
||||
shell_command = 'gateway-device-remote-mac-entry-show'
|
||||
allow_names = False
|
||||
|
||||
|
||||
class RemoteMacEntryDelete(extension.ClientExtensionDelete, RemoteMacEntry):
|
||||
"""Delete a given gateway-device-remote-mac-entry."""
|
||||
|
||||
shell_command = 'gateway-device-remote-mac-entry-delete'
|
||||
allow_names = False
|
||||
@@ -70,6 +70,9 @@ neutron.interface_drivers =
|
||||
oslo.config.opts =
|
||||
midonet_v1 = midonet.neutron.plugin_v1:list_opts
|
||||
midonet_v2 = midonet.neutron.common.config:list_opts
|
||||
neutronclient.extension =
|
||||
gateway_device = midonet.neutronclient.gateway_device_extension._gateway_device
|
||||
remote_mac_entry = midonet.neutronclient.gateway_device_extension._remote_mac_entry
|
||||
|
||||
[wheel]
|
||||
universal = 1
|
||||
|
||||
4
tox.ini
4
tox.ini
@@ -34,7 +34,9 @@ commands = python -m testtools.run \
|
||||
midonet.neutron.tests.unit.test_midonet_plugin_ml2 \
|
||||
midonet.neutron.tests.unit.test_midonet_plugin_v2 \
|
||||
midonet.neutron.tests.unit.test_midonet_type_driver \
|
||||
midonet.neutron.tests.unit.test_uplink_type_driver}
|
||||
midonet.neutron.tests.unit.test_uplink_type_driver \
|
||||
midonet.neutron.tests.unit.neutronclient_ext.test_cli20_gateway_device \
|
||||
midonet.neutron.tests.unit.neutronclient_ext.test_cli20_remote_mac_entry}
|
||||
|
||||
[testenv:cover]
|
||||
basepython = python2.7
|
||||
|
||||
Reference in New Issue
Block a user