Supporting Net-Partition as extension for Nuage plugin
A net-partition provides administrative separation between groups of tenant routers/networks/subnets. Within a net-partition, subnets can be shared, and VMs can connect multiple vNICs to subnets within the net-partition. For security and isolation between organizations, VMs may not connect VNICs to subnets within more than one net-partition. This work is in accordance with bp/nuage-networks-plugin which is under review: https://review.openstack.org/#/c/67272/ Change-Id: Ia9b0304f714c65548cd6b8ce6ff74a3075c4e673 Implements: blueprint nuage-net-partition-extension
This commit is contained in:
59
neutronclient/neutron/v2_0/netpartition.py
Normal file
59
neutronclient/neutron/v2_0/netpartition.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Copyright 2014 Alcatel-Lucent USA Inc.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
# @author: Ronak Shah, Nuage Networks, Alcatel-Lucent USA Inc.
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from neutronclient.neutron.v2_0 import CreateCommand
|
||||||
|
from neutronclient.neutron.v2_0 import DeleteCommand
|
||||||
|
from neutronclient.neutron.v2_0 import ListCommand
|
||||||
|
from neutronclient.neutron.v2_0 import ShowCommand
|
||||||
|
|
||||||
|
|
||||||
|
class ListNetPartition(ListCommand):
|
||||||
|
"""List netpartitions that belong to a given tenant."""
|
||||||
|
resource = 'net_partition'
|
||||||
|
log = logging.getLogger(__name__ + '.ListNetPartition')
|
||||||
|
list_columns = ['id', 'name']
|
||||||
|
|
||||||
|
|
||||||
|
class ShowNetPartition(ShowCommand):
|
||||||
|
"""Show information of a given netpartition."""
|
||||||
|
|
||||||
|
resource = 'net_partition'
|
||||||
|
log = logging.getLogger(__name__ + '.ShowNetPartition')
|
||||||
|
|
||||||
|
|
||||||
|
class CreateNetPartition(CreateCommand):
|
||||||
|
"""Create a netpartition for a given tenant."""
|
||||||
|
|
||||||
|
resource = 'net_partition'
|
||||||
|
log = logging.getLogger(__name__ + '.CreateNetPartition')
|
||||||
|
|
||||||
|
def add_known_arguments(self, parser):
|
||||||
|
parser.add_argument(
|
||||||
|
'name', metavar='name',
|
||||||
|
help='Name of NetPartition to create')
|
||||||
|
|
||||||
|
def args2body(self, parsed_args):
|
||||||
|
body = {'net_partition': {'name': parsed_args.name}, }
|
||||||
|
return body
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteNetPartition(DeleteCommand):
|
||||||
|
"""Delete a given netpartition."""
|
||||||
|
|
||||||
|
resource = 'net_partition'
|
||||||
|
log = logging.getLogger(__name__ + '.DeleteNetPartition')
|
||||||
@@ -42,6 +42,7 @@ from neutronclient.neutron.v2_0.lb import member as lb_member
|
|||||||
from neutronclient.neutron.v2_0.lb import pool as lb_pool
|
from neutronclient.neutron.v2_0.lb import pool as lb_pool
|
||||||
from neutronclient.neutron.v2_0.lb import vip as lb_vip
|
from neutronclient.neutron.v2_0.lb import vip as lb_vip
|
||||||
from neutronclient.neutron.v2_0 import metering
|
from neutronclient.neutron.v2_0 import metering
|
||||||
|
from neutronclient.neutron.v2_0 import netpartition
|
||||||
from neutronclient.neutron.v2_0 import network
|
from neutronclient.neutron.v2_0 import network
|
||||||
from neutronclient.neutron.v2_0 import networkprofile
|
from neutronclient.neutron.v2_0 import networkprofile
|
||||||
from neutronclient.neutron.v2_0.nsx import networkgateway
|
from neutronclient.neutron.v2_0.nsx import networkgateway
|
||||||
@@ -259,6 +260,10 @@ COMMAND_V2 = {
|
|||||||
'meter-label-rule-list': metering.ListMeteringLabelRule,
|
'meter-label-rule-list': metering.ListMeteringLabelRule,
|
||||||
'meter-label-rule-show': metering.ShowMeteringLabelRule,
|
'meter-label-rule-show': metering.ShowMeteringLabelRule,
|
||||||
'meter-label-rule-delete': metering.DeleteMeteringLabelRule,
|
'meter-label-rule-delete': metering.DeleteMeteringLabelRule,
|
||||||
|
'nuage-netpartition-list': netpartition.ListNetPartition,
|
||||||
|
'nuage-netpartition-show': netpartition.ShowNetPartition,
|
||||||
|
'nuage-netpartition-create': netpartition.CreateNetPartition,
|
||||||
|
'nuage-netpartition-delete': netpartition.DeleteNetPartition,
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMANDS = {'2.0': COMMAND_V2}
|
COMMANDS = {'2.0': COMMAND_V2}
|
||||||
|
|||||||
@@ -193,7 +193,8 @@ class CLITestV20Base(testtools.TestCase):
|
|||||||
'network_gateway', 'credential',
|
'network_gateway', 'credential',
|
||||||
'network_profile', 'policy_profile',
|
'network_profile', 'policy_profile',
|
||||||
'ikepolicy', 'ipsecpolicy',
|
'ikepolicy', 'ipsecpolicy',
|
||||||
'metering_label', 'metering_label_rule']
|
'metering_label', 'metering_label_rule',
|
||||||
|
'net_partition']
|
||||||
if (resource in non_admin_status_resources):
|
if (resource in non_admin_status_resources):
|
||||||
body = {resource: {}, }
|
body = {resource: {}, }
|
||||||
else:
|
else:
|
||||||
|
|||||||
59
neutronclient/tests/unit/test_cli20_nuage_netpartition.py
Normal file
59
neutronclient/tests/unit/test_cli20_nuage_netpartition.py
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Copyright 2014 Alcatel-Lucent USA Inc.
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
# @author: Ronak Shah, Nuage Networks, Alcatel-Lucent USA Inc.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from neutronclient.neutron.v2_0 import netpartition
|
||||||
|
from neutronclient.tests.unit import test_cli20
|
||||||
|
|
||||||
|
|
||||||
|
class CLITestV20NetPartitionJSON(test_cli20.CLITestV20Base):
|
||||||
|
resource = 'net_partition'
|
||||||
|
|
||||||
|
def test_create_netpartition(self):
|
||||||
|
cmd = netpartition.CreateNetPartition(test_cli20.MyApp(sys.stdout),
|
||||||
|
None)
|
||||||
|
name = 'myname'
|
||||||
|
myid = 'myid'
|
||||||
|
args = [name, ]
|
||||||
|
position_names = ['name', ]
|
||||||
|
position_values = [name, ]
|
||||||
|
self._test_create_resource(self.resource, cmd, name, myid, args,
|
||||||
|
position_names, position_values)
|
||||||
|
|
||||||
|
def test_list_netpartitions(self):
|
||||||
|
resources = '%ss' % self.resource
|
||||||
|
cmd = netpartition.ListNetPartition(test_cli20.MyApp(sys.stdout),
|
||||||
|
None)
|
||||||
|
self._test_list_resources(resources, cmd, True)
|
||||||
|
|
||||||
|
def test_show_netpartition(self):
|
||||||
|
cmd = netpartition.ShowNetPartition(test_cli20.MyApp(sys.stdout),
|
||||||
|
None)
|
||||||
|
args = ['--fields', 'id', '--fields', 'name', self.test_id]
|
||||||
|
self._test_show_resource(self.resource, cmd, self.test_id, args,
|
||||||
|
['id', 'name'])
|
||||||
|
|
||||||
|
def test_delete_netpartition(self):
|
||||||
|
cmd = netpartition.DeleteNetPartition(test_cli20.MyApp(sys.stdout),
|
||||||
|
None)
|
||||||
|
myid = 'myid'
|
||||||
|
args = [myid]
|
||||||
|
self._test_delete_resource(self.resource, cmd, myid, args)
|
||||||
|
|
||||||
|
|
||||||
|
class CLITestV20NetPartitionXML(CLITestV20NetPartitionJSON):
|
||||||
|
format = 'xml'
|
||||||
@@ -221,6 +221,8 @@ class Client(object):
|
|||||||
firewall_policy_remove_path = "/fw/firewall_policies/%s/remove_rule"
|
firewall_policy_remove_path = "/fw/firewall_policies/%s/remove_rule"
|
||||||
firewalls_path = "/fw/firewalls"
|
firewalls_path = "/fw/firewalls"
|
||||||
firewall_path = "/fw/firewalls/%s"
|
firewall_path = "/fw/firewalls/%s"
|
||||||
|
net_partitions_path = "/net-partitions"
|
||||||
|
net_partition_path = "/net-partitions/%s"
|
||||||
|
|
||||||
# API has no way to report plurals, so we have to hard code them
|
# API has no way to report plurals, so we have to hard code them
|
||||||
EXTED_PLURALS = {'routers': 'router',
|
EXTED_PLURALS = {'routers': 'router',
|
||||||
@@ -243,7 +245,8 @@ class Client(object):
|
|||||||
'firewall_policies': 'firewall_policy',
|
'firewall_policies': 'firewall_policy',
|
||||||
'firewalls': 'firewall',
|
'firewalls': 'firewall',
|
||||||
'metering_labels': 'metering_label',
|
'metering_labels': 'metering_label',
|
||||||
'metering_label_rules': 'metering_label_rule'
|
'metering_label_rules': 'metering_label_rule',
|
||||||
|
'net_partitions': 'net_partition'
|
||||||
}
|
}
|
||||||
# 8192 Is the default max URI len for eventlet.wsgi.server
|
# 8192 Is the default max URI len for eventlet.wsgi.server
|
||||||
MAX_URI_LEN = 8192
|
MAX_URI_LEN = 8192
|
||||||
@@ -1110,6 +1113,27 @@ class Client(object):
|
|||||||
return self.get(self.metering_label_rule_path %
|
return self.get(self.metering_label_rule_path %
|
||||||
(metering_label_rule), params=_params)
|
(metering_label_rule), params=_params)
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def list_net_partitions(self, **params):
|
||||||
|
"""Fetch a list of all network partitions for a tenant."""
|
||||||
|
return self.get(self.net_partitions_path, params=params)
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def show_net_partition(self, netpartition, **params):
|
||||||
|
"""Fetch a network partition."""
|
||||||
|
return self.get(self.net_partition_path % (netpartition),
|
||||||
|
params=params)
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def create_net_partition(self, body=None):
|
||||||
|
"""Create a network partition."""
|
||||||
|
return self.post(self.net_partitions_path, body=body)
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def delete_net_partition(self, netpartition):
|
||||||
|
"""Delete the network partition."""
|
||||||
|
return self.delete(self.net_partition_path % netpartition)
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
"""Initialize a new client for the Neutron v2.0 API."""
|
"""Initialize a new client for the Neutron v2.0 API."""
|
||||||
super(Client, self).__init__()
|
super(Client, self).__init__()
|
||||||
|
|||||||
Reference in New Issue
Block a user