Add APIC fields in Openstack CLI

Add APIC fields for below resources in Openstack CLI:
Network, Subnet, Address Scope, Router

Change-Id: I9a7fc4c098f0e58e008a8eeec29f84094ebafa7f
This commit is contained in:
Sayali Naval 2020-10-19 13:21:58 -07:00
parent 32fe945467
commit 35d30bcf3d
10 changed files with 1298 additions and 0 deletions

View File

@ -0,0 +1,89 @@
# 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.
#
"""
Address Scope extension implementations
"""
from oslo_serialization import jsonutils
from cliff import hooks
from openstack.network.v2 import address_scope as address_scope_sdk
from openstack import resource
from openstackclient.network.v2 import address_scope
from openstackclient.i18n import _
_get_attrs_address_scope_new = address_scope._get_attrs
def _get_attrs_address_scope_extension(client_manager, parsed_args):
attrs = _get_attrs_address_scope_new(client_manager, parsed_args)
if parsed_args.apic_distinguished_names:
attrs['apic:distinguished_names'
] = jsonutils.loads(parsed_args.apic_distinguished_names)
if parsed_args.apic_synchronization_state:
attrs['apic:synchronization_state'
] = parsed_args.apic_synchronization_state
return attrs
address_scope._get_attrs = _get_attrs_address_scope_extension
address_scope_sdk.AddressScope.apic_distinguished_names = resource.Body(
'apic:distinguished_names')
address_scope_sdk.AddressScope.apic_synchronization_state = resource.Body(
'apic:synchronization_state')
class CreateAndSetAddressScopeExtension(hooks.CommandHook):
def get_parser(self, parser):
parser.add_argument(
'--apic-distinguished-names',
metavar="<apic_distinguished_names>",
dest='apic_distinguished_names',
help=_("Apic distinguished names")
)
parser.add_argument(
'--apic-synchronization-state',
metavar="<apic_synchronization_state>",
dest='apic_synchronization_state',
help=_("Apic synchronization state")
)
return parser
def get_epilog(self):
return ''
def before(self, parsed_args):
return parsed_args
def after(self, parsed_args, return_code):
return return_code
class ShowAddressScopeExtension(hooks.CommandHook):
def get_parser(self, parser):
return parser
def get_epilog(self):
return ''
def before(self, parsed_args):
return parsed_args
def after(self, parsed_args, return_code):
return return_code

View File

@ -0,0 +1,265 @@
# 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.
#
"""
Network extension implementations
"""
import ast
from oslo_serialization import jsonutils
from cliff import hooks
from openstack.network.v2 import network as network_sdk
from openstack import resource
from openstackclient.network.v2 import network
from openstackclient.i18n import _
_get_attrs_network_new = network._get_attrs_network
def _get_attrs_network_extension(client_manager, parsed_args):
attrs = _get_attrs_network_new(client_manager, parsed_args)
if parsed_args.apic_synchronization_state:
attrs['apic:synchronization_state'
] = parsed_args.apic_synchronization_state
if parsed_args.apic_svi_enable:
attrs['apic:svi'] = True
if parsed_args.apic_svi_disable:
attrs['apic:svi'] = False
if parsed_args.apic_bgp_enable:
attrs['apic:bgp_enable'] = True
if parsed_args.apic_bgp_disable:
attrs['apic:bgp_enable'] = False
if parsed_args.apic_bgp_type:
attrs['apic:bgp_type'] = parsed_args.apic_bgp_type
if parsed_args.apic_bgp_asn:
attrs['apic:bgp_asn'] = parsed_args.apic_bgp_asn
if parsed_args.apic_nested_domain_name:
attrs['apic:nested_domain_name'
] = parsed_args.apic_nested_domain_name
if parsed_args.apic_nested_domain_type:
attrs['apic:nested_domain_type'
] = parsed_args.apic_nested_domain_type
if parsed_args.apic_nested_domain_infra_vlan:
attrs['apic:nested_domain_infra_vlan'
] = parsed_args.apic_nested_domain_infra_vlan
if parsed_args.apic_nested_domain_service_vlan:
attrs['apic:nested_domain_service_vlan'
] = parsed_args.apic_nested_domain_service_vlan
if parsed_args.apic_nested_domain_node_network_vlan:
attrs['apic:nested_domain_node_network_vlan'
] = parsed_args.apic_nested_domain_node_network_vlan
if parsed_args.apic_nested_domain_allowed_vlans:
attrs['apic:nested_domain_allowed_vlans'
] = ast.literal_eval(
parsed_args.apic_nested_domain_allowed_vlans)
if parsed_args.apic_extra_provided_contracts:
attrs['apic:extra_provided_contracts'
] = ast.literal_eval(parsed_args.apic_extra_provided_contracts)
if parsed_args.apic_extra_consumed_contracts:
attrs['apic:extra_consumed_contracts'
] = ast.literal_eval(parsed_args.apic_extra_consumed_contracts)
if parsed_args.apic_epg_contract_masters:
attrs['apic:epg_contract_masters'
] = ast.literal_eval(parsed_args.apic_epg_contract_masters)
if parsed_args.apic_distinguished_names:
attrs['apic:distinguished_names'
] = jsonutils.loads(parsed_args.apic_distinguished_names)
if parsed_args.external:
if parsed_args.apic_nat_type:
attrs['apic:nat_type'] = parsed_args.apic_nat_type
if parsed_args.apic_external_cidrs:
attrs['apic:external_cidrs'
] = ast.literal_eval(parsed_args.apic_external_cidrs)
return attrs
network._get_attrs_network = _get_attrs_network_extension
network_sdk.Network.apic_synchronization_state = resource.Body(
'apic:synchronization_state')
network_sdk.Network.apic_svi = resource.Body('apic:svi')
network_sdk.Network.apic_bgp = resource.Body('apic:bgp_enable')
network_sdk.Network.apic_bgp_type = resource.Body('apic:bgp_type')
network_sdk.Network.apic_bgp_asn = resource.Body('apic:bgp_asn')
network_sdk.Network.apic_nested_domain_name = resource.Body(
'apic:nested_domain_name')
network_sdk.Network.apic_nested_domain_type = resource.Body(
'apic:nested_domain_type')
network_sdk.Network.apic_nested_domain_infra_vlan = resource.Body(
'apic:nested_domain_infra_vlan')
network_sdk.Network.apic_nested_domain_service_vlan = resource.Body(
'apic:nested_domain_service_vlan')
network_sdk.Network.apic_nested_domain_node_network_vlan = resource.Body(
'apic:nested_domain_node_network_vlan')
network_sdk.Network.apic_nested_domain_allowed_vlans = resource.Body(
'apic:nested_domain_allowed_vlans')
network_sdk.Network.apic_extra_provided_contracts = resource.Body(
'apic:extra_provided_contracts')
network_sdk.Network.apic_extra_consumed_contracts = resource.Body(
'apic:extra_consumed_contracts')
network_sdk.Network.apic_epg_contract_masters = resource.Body(
'apic:epg_contract_masters')
network_sdk.Network.apic_distinguished_names = resource.Body(
'apic:distinguished_names')
network_sdk.Network.apic_nat_type = resource.Body('apic:nat_type')
network_sdk.Network.apic_external_cidrs = resource.Body('apic:external_cidrs')
class CreateAndSetNetworkExtension(hooks.CommandHook):
def get_parser(self, parser):
parser.add_argument(
'--apic-synchronization-state',
metavar="<apic_synchronization_state>",
dest='apic_synchronization_state',
help=_("Apic synchronization state")
)
parser.add_argument(
'--apic-svi-enable',
action='store_true',
default=None,
dest='apic_svi_enable',
help=_("Set Apic SVI to true")
)
parser.add_argument(
'--apic-svi-disable',
action='store_true',
dest='apic_svi_disable',
help=_("Set Apic SVI to false")
)
parser.add_argument(
'--apic-bgp-enable',
action='store_true',
default=None,
dest='apic_bgp_enable',
help=_("Set Apic BGP to true")
)
parser.add_argument(
'--apic-bgp-disable',
action='store_true',
dest='apic_bgp_disable',
help=_("Set Apic BGP to false")
)
parser.add_argument(
'--apic-bgp-type',
metavar="<apic_bgp_type>",
dest='apic_bgp_type',
help=_("Apic BGP Type")
)
parser.add_argument(
'--apic-bgp-asn',
metavar="<apic_bgp_asn>",
dest='apic_bgp_asn',
help=_("Apic BGP ASN")
)
parser.add_argument(
'--apic-nested-domain-name',
metavar="<apic_nested_domain_name>",
dest='apic_nested_domain_name',
help=_("Apic nested domain name")
)
parser.add_argument(
'--apic-nested-domain-type',
metavar="<apic_nested_domain_type>",
dest='apic_nested_domain_type',
help=_("Apic nested domain type")
)
parser.add_argument(
'--apic-nested-domain-infra-vlan',
metavar="<apic_nested_domain_infra_vlan>",
dest='apic_nested_domain_infra_vlan',
help=_("Apic nested domain infra vlan")
)
parser.add_argument(
'--apic-nested-domain-service-vlan',
metavar="<apic_nested_domain_service_vlan>",
dest='apic_nested_domain_service_vlan',
help=_("Apic nested domain service vlan")
)
parser.add_argument(
'--apic-nested-domain-node-network-vlan',
metavar="<apic_nested_domain_node_network_vlan>",
dest='apic_nested_domain_node_network_vlan',
help=_("Apic nested domain node network vlan")
)
parser.add_argument(
'--apic-nested-domain-allowed-vlans',
metavar="<apic_nested_domain_allowed_vlans>",
dest='apic_nested_domain_allowed_vlans',
help=_("Apic nested domain allowed vlans")
)
parser.add_argument(
'--apic-extra-provided-contracts',
metavar="<apic_extra_provided_contracts>",
dest='apic_extra_provided_contracts',
help=_("Apic extra provided contracts")
)
parser.add_argument(
'--apic-extra-consumed-contracts',
metavar="<apic_extra_consumed_contracts>",
dest='apic_extra_consumed_contracts',
help=_("Apic extra consumed contracts")
)
parser.add_argument(
'--apic-epg-contract-masters',
metavar="<apic_epg_contract_masters>",
dest='apic_epg_contract_masters',
help=_("Apic epg contract masters")
)
parser.add_argument(
'--apic-distinguished-names',
metavar="<apic_distinguished_names>",
dest='apic_distinguished_names',
help=_("Apic distinguished names")
)
parser.add_argument(
'--apic-nat-type',
metavar="<apic_nat_type>",
dest='apic_nat_type',
help=_("Apic nat type for external network")
)
parser.add_argument(
'--apic-external-cidrs',
metavar="<apic_external_cidrs>",
dest='apic_external_cidrs',
help=_("Apic external CIDRS for external network")
)
return parser
def get_epilog(self):
return ''
def before(self, parsed_args):
return parsed_args
def after(self, parsed_args, return_code):
return return_code
class ShowNetworkExtension(hooks.CommandHook):
def get_parser(self, parser):
return parser
def get_epilog(self):
return ''
def before(self, parsed_args):
return parsed_args
def after(self, parsed_args, return_code):
return return_code

View File

@ -0,0 +1,115 @@
# 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.
#
"""
Router extension implementations
"""
import ast
from oslo_serialization import jsonutils
from cliff import hooks
from openstack.network.v2 import router as router_sdk
from openstack import resource
from openstackclient.network.v2 import router
from openstackclient.i18n import _
_get_attrs_router_new = router._get_attrs
def _get_attrs_router_extension(client_manager, parsed_args):
attrs = _get_attrs_router_new(client_manager, parsed_args)
if parsed_args.apic_distinguished_names:
attrs['apic:distinguished_names'
] = jsonutils.loads(parsed_args.apic_distinguished_names)
if parsed_args.apic_synchronization_state:
attrs['apic:synchronization_state'
] = parsed_args.apic_synchronization_state
if parsed_args.apic_external_provided_contracts:
attrs['apic:external_provided_contracts'
] = ast.literal_eval(
parsed_args.apic_external_provided_contracts)
if parsed_args.apic_external_consumed_contracts:
attrs['apic:external_consumed_contracts'
] = ast.literal_eval(
parsed_args.apic_external_consumed_contracts)
return attrs
router._get_attrs = _get_attrs_router_extension
router_sdk.Router.apic_distinguished_names = resource.Body(
'apic:distinguished_names')
router_sdk.Router.apic_synchronization_state = resource.Body(
'apic:synchronization_state')
router_sdk.Router.apic_external_provided_contracts = resource.Body(
'apic:external_provided_contracts')
router_sdk.Router.apic_external_consumed_contracts = resource.Body(
'apic:external_consumed_contracts')
class CreateAndSetRouterExtension(hooks.CommandHook):
def get_parser(self, parser):
parser.add_argument(
'--apic-distinguished-names',
metavar="<apic_distinguished_names>",
dest='apic_distinguished_names',
help=_("Apic distinguished names")
)
parser.add_argument(
'--apic-synchronization-state',
metavar="<apic_synchronization_state>",
dest='apic_synchronization_state',
help=_("Apic synchronization state")
)
parser.add_argument(
'--apic-external-provided-contracts',
metavar="<apic_external_provided_contracts>",
dest='apic_external_provided_contracts',
help=_("Apic external provided contracts")
)
parser.add_argument(
'--apic-external-consumed-contracts',
metavar="<apic_external_consumed_contracts>",
dest='apic_external_consumed_contracts',
help=_("Apic external consumed contracts")
)
return parser
def get_epilog(self):
return ''
def before(self, parsed_args):
return parsed_args
def after(self, parsed_args, return_code):
return return_code
class ShowRouterExtension(hooks.CommandHook):
def get_parser(self, parser):
return parser
def get_epilog(self):
return ''
def before(self, parsed_args):
return parsed_args
def after(self, parsed_args, return_code):
return return_code

View File

@ -0,0 +1,127 @@
# 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.
#
"""
Subnet extension implementations
"""
from oslo_serialization import jsonutils
from cliff import hooks
from openstack.network.v2 import subnet as subnet_sdk
from openstack import resource
from openstackclient.network.v2 import subnet
from openstackclient.i18n import _
_get_attrs_subnet_new = subnet._get_attrs
def _get_attrs_subnet_extension(client_manager, parsed_args, is_create=True):
attrs = _get_attrs_subnet_new(client_manager, parsed_args, is_create)
if parsed_args.apic_distinguished_names:
attrs['apic:distinguished_names'
] = jsonutils.loads(parsed_args.apic_distinguished_names)
if parsed_args.apic_synchronization_state:
attrs['apic:synchronization_state'
] = parsed_args.apic_synchronization_state
if parsed_args.apic_snat_host_pool_enable:
attrs['apic:snat_host_pool'] = True
if parsed_args.apic_snat_host_pool_disable:
attrs['apic:snat_host_pool'] = False
if parsed_args.apic_active_active_aap_enable:
attrs['apic:active_active_aap'] = True
if parsed_args.apic_active_active_aap_disable:
attrs['apic:active_active_aap'] = False
return attrs
subnet._get_attrs = _get_attrs_subnet_extension
subnet_sdk.Subnet.apic_distinguished_names = resource.Body(
'apic:distinguished_names')
subnet_sdk.Subnet.apic_synchronization_state = resource.Body(
'apic:synchronization_state')
subnet_sdk.Subnet.apic_snat_host_pool = resource.Body(
'apic:snat_host_pool')
subnet_sdk.Subnet.apic_active_active_aap = resource.Body(
'apic:active_active_aap')
class CreateAndSetSubnetExtension(hooks.CommandHook):
def get_parser(self, parser):
parser.add_argument(
'--apic-distinguished-names',
metavar="<apic_distinguished_names>",
dest='apic_distinguished_names',
help=_("Apic distinguished names")
)
parser.add_argument(
'--apic-synchronization-state',
metavar="<apic_synchronization_state>",
dest='apic_synchronization_state',
help=_("Apic synchronization state")
)
parser.add_argument(
'--apic-snat-host-pool-enable',
action='store_true',
default=None,
dest='apic_snat_host_pool_enable',
help=_("Set Apic snat host pool to true")
)
parser.add_argument(
'--apic-snat-host-pool-disable',
action='store_true',
dest='apic_snat_host_pool_disable',
help=_("Set Apic snat host pool to false")
)
parser.add_argument(
'--apic-active-active-aap-enable',
action='store_true',
default=None,
dest='apic_active_active_aap_enable',
help=_("Set Apic active active aap to true")
)
parser.add_argument(
'--apic-active-active-aap-disable',
action='store_true',
dest='apic_active_active_aap_disable',
help=_("Set Apic active active aap to false")
)
return parser
def get_epilog(self):
return ''
def before(self, parsed_args):
return parsed_args
def after(self, parsed_args, return_code):
return return_code
class ShowSubnetExtension(hooks.CommandHook):
def get_parser(self, parser):
return parser
def get_epilog(self):
return ''
def before(self, parsed_args):
return parsed_args
def after(self, parsed_args, return_code):
return return_code

View File

@ -0,0 +1,110 @@
# 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 unittest import mock
from gbpclient.gbp.v2_0 import address_scope as address_scope_ext
from gbpclient.tests.unit import test_cli20
from openstackclient.network.v2 import address_scope
from openstackclient.tests.unit.network.v2 import test_address_scope
# Tests for address scope create for APIC extensions
#
class TestAddressScopeCreate(
test_address_scope.TestAddressScope, test_cli20.CLITestV20Base):
def setUp(self):
super(TestAddressScopeCreate, self).setUp()
self.new_address_scope = (
test_address_scope.TestCreateAddressScope.new_address_scope)
self.network.create_address_scope = mock.Mock(
return_value=self.new_address_scope)
self.cmd = address_scope.CreateAddressScope(self.app, self.namespace)
def test_create_default_options(self):
arglist = [
test_address_scope.TestCreateAddressScope.new_address_scope.name,
]
verifylist = [
('name', self.new_address_scope.name),
('apic_distinguished_names', None),
('apic_synchronization_state', None),
]
create_ext = address_scope_ext.CreateAndSetAddressScopeExtension(
self.app)
parsed_args = self.check_parser_ext(
self.cmd, arglist, verifylist, create_ext)
columns, data = self.cmd.take_action(parsed_args)
self.network.create_address_scope.assert_called_once_with(**{
'ip_version': self.new_address_scope.ip_version,
'name': self.new_address_scope.name,
})
def test_create_all_options(self):
arglist = [
self.new_address_scope.name,
"--apic-distinguished-names", '{"disttest1": "test1"}',
]
verifylist = [
('name', self.new_address_scope.name),
('apic_distinguished_names', '{"disttest1": "test1"}'),
('apic_synchronization_state', None),
]
create_ext = address_scope_ext.CreateAndSetAddressScopeExtension(
self.app)
parsed_args = self.check_parser_ext(
self.cmd, arglist, verifylist, create_ext)
columns, data = self.cmd.take_action(parsed_args)
self.network.create_address_scope.assert_called_once_with(**{
'ip_version': self.new_address_scope.ip_version,
'apic:distinguished_names': {"disttest1": "test1"},
'name': self.new_address_scope.name,
})
# Tests for address scope set for APIC extensions
#
class TestAddressScopeSet(
test_address_scope.TestAddressScope, test_cli20.CLITestV20Base):
_address_scope = test_address_scope.TestSetAddressScope._address_scope
def setUp(self):
super(TestAddressScopeSet, self).setUp()
self.network.update_address_scope = mock.Mock(return_value=None)
self.network.find_address_scope = mock.Mock(
return_value=self._address_scope)
self.cmd = address_scope.SetAddressScope(self.app, self.namespace)
def test_set_no_options(self):
arglist = [
self._address_scope.name,
]
verifylist = [
('address_scope', self._address_scope.name),
('apic_distinguished_names', None),
('apic_synchronization_state', None),
]
set_ext = address_scope_ext.CreateAndSetAddressScopeExtension(self.app)
parsed_args = self.check_parser_ext(
self.cmd, arglist, verifylist, set_ext)
result = self.cmd.take_action(parsed_args)
attrs = {}
self.network.update_address_scope.assert_called_with(
self._address_scope, **attrs)
self.assertIsNone(result)

View File

@ -13,6 +13,7 @@
from unittest import mock
import fixtures
import requests
from neutronclient.common import exceptions
@ -21,6 +22,8 @@ from neutronclient.tests.unit import test_cli20 as neutron_test_cli20
from gbpclient import gbpshell
from gbpclient.v2_0 import client as gbpclient
from six.moves import StringIO
API_VERSION = neutron_test_cli20.API_VERSION
TOKEN = neutron_test_cli20.TOKEN
ENDURL = neutron_test_cli20.ENDURL
@ -28,6 +31,10 @@ capture_std_streams = neutron_test_cli20.capture_std_streams
end_url = neutron_test_cli20.end_url
class ParserException(Exception):
pass
class FakeStdout(neutron_test_cli20.FakeStdout):
pass
@ -115,6 +122,23 @@ class CLITestV20Base(neutron_test_cli20.CLITestV20Base):
if name:
self.assertIn(name, _str)
def check_parser_ext(self, cmd, args, verify_args, ext):
cmd_parser = self.cmd.get_parser('check_parser')
cmd_parser = ext.get_parser(cmd_parser)
stderr = StringIO()
with fixtures.MonkeyPatch('sys.stderr', stderr):
try:
parsed_args = cmd_parser.parse_args(args)
except SystemExit:
raise ParserException("Argument parse failed: %s" %
stderr.getvalue())
for av in verify_args:
attr, value = av
if attr:
self.assertIn(attr, parsed_args)
self.assertEqual(value, getattr(parsed_args, attr))
return parsed_args
class ClientV2TestJson(CLITestV20Base):

View File

@ -0,0 +1,241 @@
# 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 unittest import mock
from gbpclient.gbp.v2_0 import network as network_ext
from gbpclient.tests.unit import test_cli20
from openstackclient.network.v2 import network
from openstackclient.tests.unit.network.v2 import test_network
# Tests for network create with APIC extensions
#
class TestNetworkCreate(test_network.TestNetwork, test_cli20.CLITestV20Base):
_network = test_network.TestCreateNetworkIdentityV3._network
def setUp(self):
super(TestNetworkCreate, self).setUp()
self.network.create_network = mock.Mock(
return_value=self._network)
self.cmd = network.CreateNetwork(self.app, self.namespace)
def test_create_default_options(self):
arglist = [
self._network.name,
]
verifylist = [
('name', self._network.name),
('apic_nested_domain_name', None),
('apic_nested_domain_type', None),
('apic_distinguished_names', None),
('apic_synchronization_state', None),
('apic_nat_type', None),
('apic_external_cidrs', None),
('apic_svi_enable', None),
('apic_bgp_enable', None),
('apic_bgp_asn', None),
('apic_bgp_type', None),
('apic_nested_domain_infra_vlan', None),
('apic_nested_domain_allowed_vlans', None),
('apic_nested_domain_service_vlan', None),
('apic_nested_domain_node_network_vlan', None),
('apic_extra_provided_contracts', None),
('apic_extra_consumed_contracts', None),
]
create_ext = network_ext.CreateAndSetNetworkExtension(self.app)
parsed_args = self.check_parser_ext(
self.cmd, arglist, verifylist, create_ext)
columns, data = self.cmd.take_action(parsed_args)
self.network.create_network.assert_called_once_with(**{
'admin_state_up': True,
'name': self._network.name,
})
def test_create_all_options(self):
arglist = [
self._network.name,
"--external",
"--apic-nested-domain-name", "dntest1",
"--apic-nested-domain-type", "dntype1",
"--apic-distinguished-names", '{"disttest1": "test1"}',
"--apic-nat-type", "edge",
"--apic-external-cidrs", "['20.20.20.0/8']",
"--apic-svi-enable",
"--apic-bgp-enable",
"--apic-bgp-asn", '1',
"--apic-bgp-type", "bgptest1",
"--apic-nested-domain-infra-vlan", '1',
"--apic-nested-domain-allowed-vlans", "[2]",
"--apic-nested-domain-service-vlan", '3',
"--apic-nested-domain-node-network-vlan", '4',
"--apic-extra-provided-contracts", "['pcontest1']",
"--apic-extra-consumed-contracts", "['contest1']",
]
verifylist = [
('name', self._network.name),
('external', True),
('apic_nested_domain_name', "dntest1"),
('apic_nested_domain_type', "dntype1"),
('apic_distinguished_names', '{"disttest1": "test1"}'),
('apic_synchronization_state', None),
('apic_nat_type', "edge"),
('apic_external_cidrs', "['20.20.20.0/8']"),
('apic_svi_enable', True),
('apic_bgp_enable', True),
('apic_bgp_asn', '1'),
('apic_bgp_type', "bgptest1"),
('apic_nested_domain_infra_vlan', '1'),
('apic_nested_domain_allowed_vlans', "[2]"),
('apic_nested_domain_service_vlan', '3'),
('apic_nested_domain_node_network_vlan', '4'),
('apic_extra_provided_contracts', "['pcontest1']"),
('apic_extra_consumed_contracts', "['contest1']"),
]
create_ext = network_ext.CreateAndSetNetworkExtension(self.app)
parsed_args = self.check_parser_ext(
self.cmd, arglist, verifylist, create_ext)
columns, data = self.cmd.take_action(parsed_args)
self.network.create_network.assert_called_once_with(**{
'admin_state_up': True,
'name': self._network.name,
'router:external': True,
'apic:nested_domain_name': 'dntest1',
'apic:distinguished_names': {"disttest1": "test1"},
'apic:external_cidrs': ['20.20.20.0/8'],
'apic:nat_type': 'edge',
'apic:nested_domain_name': 'dntest1',
'apic:nested_domain_type': 'dntype1',
'apic:svi': True,
'apic:bgp_enable': True,
'apic:bgp_asn': '1',
'apic:bgp_type': 'bgptest1',
'apic:extra_consumed_contracts': ['contest1'],
'apic:extra_provided_contracts': ['pcontest1'],
'apic:nested_domain_allowed_vlans': [2],
'apic:nested_domain_infra_vlan': '1',
'apic:nested_domain_node_network_vlan': '4',
'apic:nested_domain_service_vlan': '3',
})
# Tests for network set with APIC extensions
#
class TestNetworkSet(test_network.TestNetwork, test_cli20.CLITestV20Base):
_network = test_network.TestSetNetwork._network
def setUp(self):
super(TestNetworkSet, self).setUp()
self.network.update_network = mock.Mock(return_value=None)
self.network.find_network = mock.Mock(return_value=self._network)
self.cmd = network.SetNetwork(self.app, self.namespace)
def test_set_no_options(self):
arglist = [
self._network.name,
]
verifylist = [
('network', self._network.name),
('apic_nested_domain_name', None),
('apic_nested_domain_type', None),
('apic_distinguished_names', None),
('apic_synchronization_state', None),
('apic_nat_type', None),
('apic_external_cidrs', None),
('apic_svi_enable', None),
('apic_bgp_enable', None),
('apic_bgp_asn', None),
('apic_bgp_type', None),
('apic_nested_domain_infra_vlan', None),
('apic_nested_domain_allowed_vlans', None),
('apic_nested_domain_service_vlan', None),
('apic_nested_domain_node_network_vlan', None),
('apic_extra_provided_contracts', None),
('apic_extra_consumed_contracts', None),
]
set_ext = network_ext.CreateAndSetNetworkExtension(self.app)
parsed_args = self.check_parser_ext(
self.cmd, arglist, verifylist, set_ext)
result = self.cmd.take_action(parsed_args)
self.assertFalse(self.network.update_network.called)
self.assertIsNone(result)
def test_set_all_valid_options(self):
arglist = [
self._network.name,
"--external",
"--apic-nested-domain-name", "dntest11",
"--apic-nested-domain-type", "dntype11",
"--apic-nat-type", "distributed",
"--apic-external-cidrs", "['30.30.30.0/8']",
"--apic-bgp-disable",
"--apic-bgp-asn", '2',
"--apic-bgp-type", "bgptest11",
"--apic-nested-domain-infra-vlan", '2',
"--apic-nested-domain-allowed-vlans", "[2, 3]",
"--apic-nested-domain-service-vlan", '4',
"--apic-nested-domain-node-network-vlan", '5',
"--apic-extra-provided-contracts", "['pcontest1', 'pcontest11']",
"--apic-extra-consumed-contracts", "['contest1', 'contest11']",
]
verifylist = [
('network', self._network.name),
('external', True),
('apic_nested_domain_name', "dntest11"),
('apic_nested_domain_type', "dntype11"),
('apic_distinguished_names', None),
('apic_synchronization_state', None),
('apic_nat_type', "distributed"),
('apic_external_cidrs', "['30.30.30.0/8']"),
('apic_svi_enable', None),
('apic_bgp_disable', True),
('apic_bgp_asn', '2'),
('apic_bgp_type', "bgptest11"),
('apic_nested_domain_infra_vlan', '2'),
('apic_nested_domain_allowed_vlans', "[2, 3]"),
('apic_nested_domain_service_vlan', '4'),
('apic_nested_domain_node_network_vlan', '5'),
('apic_extra_provided_contracts', "['pcontest1', 'pcontest11']"),
('apic_extra_consumed_contracts', "['contest1', 'contest11']"),
]
set_ext = network_ext.CreateAndSetNetworkExtension(self.app)
parsed_args = self.check_parser_ext(
self.cmd, arglist, verifylist, set_ext)
result = self.cmd.take_action(parsed_args)
attrs = {
'router:external': True,
'apic:nested_domain_name': 'dntest11',
'apic:external_cidrs': ['30.30.30.0/8'],
'apic:nat_type': 'distributed',
'apic:nested_domain_name': 'dntest11',
'apic:nested_domain_type': 'dntype11',
'apic:bgp_enable': False,
'apic:bgp_asn': '2',
'apic:bgp_type': 'bgptest11',
'apic:extra_consumed_contracts': ['contest1', 'contest11'],
'apic:extra_provided_contracts': ['pcontest1', 'pcontest11'],
'apic:nested_domain_allowed_vlans': [2, 3],
'apic:nested_domain_infra_vlan': '2',
'apic:nested_domain_node_network_vlan': '5',
'apic:nested_domain_service_vlan': '4',
}
self.network.update_network.assert_called_once_with(
self._network, **attrs)
self.assertIsNone(result)

View File

@ -0,0 +1,137 @@
# 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 unittest import mock
from gbpclient.gbp.v2_0 import router as router_ext
from gbpclient.tests.unit import test_cli20
from openstackclient.network.v2 import router
from openstackclient.tests.unit.network.v2 import test_router
# Tests for router create for APIC extensions
#
class TestRouterCreate(test_router.TestRouter, test_cli20.CLITestV20Base):
def setUp(self):
super(TestRouterCreate, self).setUp()
self.new_router = test_router.TestCreateRouter.new_router
self.network.create_router = mock.Mock(return_value=self.new_router)
self.cmd = router.CreateRouter(self.app, self.namespace)
def test_create_default_options(self):
arglist = [
self.new_router.name,
]
verifylist = [
('name', self.new_router.name),
('apic_distinguished_names', None),
('apic_synchronization_state', None),
('apic_external_provided_contracts', None),
('apic_external_consumed_contracts', None),
]
create_ext = router_ext.CreateAndSetRouterExtension(self.app)
parsed_args = self.check_parser_ext(
self.cmd, arglist, verifylist, create_ext)
columns, data = self.cmd.take_action(parsed_args)
self.network.create_router.assert_called_once_with(**{
'admin_state_up': True,
'name': self.new_router.name,
})
def test_create_all_options(self):
arglist = [
self.new_router.name,
"--apic-distinguished-names", '{"disttest1": "test1"}',
"--apic-external-provided-contracts", "['ptest1']",
"--apic-external-consumed-contracts", "['ctest1']",
]
verifylist = [
('name', self.new_router.name),
('apic_distinguished_names', '{"disttest1": "test1"}'),
('apic_synchronization_state', None),
('apic_external_provided_contracts', "['ptest1']"),
('apic_external_consumed_contracts', "['ctest1']"),
]
create_ext = router_ext.CreateAndSetRouterExtension(self.app)
parsed_args = self.check_parser_ext(
self.cmd, arglist, verifylist, create_ext)
columns, data = self.cmd.take_action(parsed_args)
self.network.create_router.assert_called_once_with(**{
'admin_state_up': True,
'name': self.new_router.name,
'apic:distinguished_names': {"disttest1": "test1"},
'apic:external_provided_contracts': ['ptest1'],
'apic:external_consumed_contracts': ['ctest1'],
})
# Tests for router set for APIC extensions
#
class TestRouterSet(test_router.TestRouter, test_cli20.CLITestV20Base):
_network = test_router.TestSetRouter._network
_subnet = test_router.TestSetRouter._subnet
_router = test_router.TestSetRouter._router
def setUp(self):
super(TestRouterSet, self).setUp()
self.network.router_add_gateway = mock.Mock()
self.network.update_router = mock.Mock(return_value=None)
self.network.set_tags = mock.Mock(return_value=None)
self.network.find_router = mock.Mock(return_value=self._router)
self.network.find_network = mock.Mock(return_value=self._network)
self.network.find_subnet = mock.Mock(return_value=self._subnet)
self.cmd = router.SetRouter(self.app, self.namespace)
def test_set_no_options(self):
arglist = [
self._router.name,
]
verifylist = [
('router', self._router.name),
]
set_ext = router_ext.CreateAndSetRouterExtension(self.app)
parsed_args = self.check_parser_ext(
self.cmd, arglist, verifylist, set_ext)
result = self.cmd.take_action(parsed_args)
self.assertFalse(self.network.update_router.called)
self.assertFalse(self.network.set_tags.called)
self.assertIsNone(result)
def test_set_all_valid_options(self):
arglist = [
self._router.name,
"--apic-external-provided-contracts", "['ptest1', 'ptest11']",
"--apic-external-consumed-contracts", "['ctest1', 'ctest11']",
]
verifylist = [
('router', self._router.name),
('apic_external_provided_contracts', "['ptest1', 'ptest11']"),
('apic_external_consumed_contracts', "['ctest1', 'ctest11']"),
]
set_ext = router_ext.CreateAndSetRouterExtension(self.app)
parsed_args = self.check_parser_ext(
self.cmd, arglist, verifylist, set_ext)
result = self.cmd.take_action(parsed_args)
attrs = {
'apic:external_provided_contracts': ['ptest1', 'ptest11'],
'apic:external_consumed_contracts': ['ctest1', 'ctest11'],
}
self.network.update_router.assert_called_once_with(
self._router, **attrs)
self.assertIsNone(result)

View File

@ -0,0 +1,154 @@
# 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 unittest import mock
from gbpclient.gbp.v2_0 import subnet as subnet_ext
from gbpclient.tests.unit import test_cli20
from openstackclient.network.v2 import subnet
from openstackclient.tests.unit.network.v2 import fakes as network_fakes
from openstackclient.tests.unit.network.v2 import test_subnet
# Tests for subnet create for APIC extensions
#
class TestSubnetCreate(test_subnet.TestSubnet, test_cli20.CLITestV20Base):
def setUp(self):
super(TestSubnetCreate, self).setUp()
self._subnet = network_fakes.FakeSubnet.create_one_subnet(
attrs={
'tenant_id': '1',
}
)
self._network = network_fakes.FakeNetwork.create_one_network(
attrs={
'id': self._subnet.network_id,
}
)
self.network.create_subnet = mock.Mock(return_value=self._subnet)
self.network.find_network = mock.Mock(return_value=self._network)
self.cmd = subnet.CreateSubnet(self.app, self.namespace)
def test_create_default_options(self):
arglist = [
"--subnet-range", self._subnet.cidr,
"--network", self._subnet.network_id,
self._subnet.name,
]
verifylist = [
('name', self._subnet.name),
('network', self._subnet.network_id),
('apic_distinguished_names', None),
('apic_synchronization_state', None),
('apic_snat_host_pool_enable', None),
('apic_active_active_aap_enable', None),
]
create_ext = subnet_ext.CreateAndSetSubnetExtension(self.app)
parsed_args = self.check_parser_ext(
self.cmd, arglist, verifylist, create_ext)
columns, data = self.cmd.take_action(parsed_args)
self.network.create_subnet.assert_called_once_with(**{
'ip_version': 4,
'cidr': '10.10.10.0/24',
'name': self._subnet.name,
'network_id': self._subnet.network_id,
})
def test_create_all_options(self):
arglist = [
"--subnet-range", self._subnet.cidr,
"--network", self._subnet.network_id,
self._subnet.name,
"--apic-distinguished-names", '{"disttest1": "test1"}',
"--apic-snat-host-pool-enable",
"--apic-active-active-aap-enable",
]
verifylist = [
('name', self._subnet.name),
('network', self._subnet.network_id),
('apic_distinguished_names', '{"disttest1": "test1"}'),
('apic_synchronization_state', None),
('apic_snat_host_pool_enable', True),
('apic_active_active_aap_enable', True),
]
create_ext = subnet_ext.CreateAndSetSubnetExtension(self.app)
parsed_args = self.check_parser_ext(
self.cmd, arglist, verifylist, create_ext)
columns, data = self.cmd.take_action(parsed_args)
self.network.create_subnet.assert_called_once_with(**{
'ip_version': 4,
'cidr': '10.10.10.0/24',
'name': self._subnet.name,
'network_id': self._subnet.network_id,
'apic:active_active_aap': True,
'apic:distinguished_names': {"disttest1": "test1"},
'apic:snat_host_pool': True,
})
# Tests for subnet set for APIC extensions
#
class TestSubnetSet(test_subnet.TestSubnet, test_cli20.CLITestV20Base):
_subnet = test_subnet.TestSetSubnet._subnet
def setUp(self):
super(TestSubnetSet, self).setUp()
self.network.update_subnet = mock.Mock(return_value=None)
self.network.find_subnet = mock.Mock(return_value=self._subnet)
self.cmd = subnet.SetSubnet(self.app, self.namespace)
def test_set_no_options(self):
arglist = [
self._subnet.name,
]
verifylist = [
('subnet', self._subnet.name),
('apic_distinguished_names', None),
('apic_synchronization_state', None),
('apic_snat_host_pool_enable', None),
('apic_active_active_aap_enable', None),
]
set_ext = subnet_ext.CreateAndSetSubnetExtension(self.app)
parsed_args = self.check_parser_ext(
self.cmd, arglist, verifylist, set_ext)
result = self.cmd.take_action(parsed_args)
self.assertFalse(self.network.update_subnet.called)
self.assertIsNone(result)
def test_set_all_valid_options(self):
arglist = [
self._subnet.name,
"--apic-snat-host-pool-disable",
]
verifylist = [
('subnet', self._subnet.name),
('apic_distinguished_names', None),
('apic_synchronization_state', None),
('apic_snat_host_pool_disable', True),
('apic_active_active_aap_enable', None),
]
set_ext = subnet_ext.CreateAndSetSubnetExtension(self.app)
parsed_args = self.check_parser_ext(
self.cmd, arglist, verifylist, set_ext)
result = self.cmd.take_action(parsed_args)
attrs = {
'apic:snat_host_pool': False,
}
self.network.update_subnet.assert_called_with(self._subnet, **attrs)
self.assertIsNone(result)

View File

@ -30,6 +30,42 @@ setup-hooks =
console_scripts =
gbp = gbpclient.gbpshell:main
openstack.cli.network_create =
network_create_extension = gbpclient.gbp.v2_0.network:CreateAndSetNetworkExtension
openstack.cli.network_show =
network_show_extension = gbpclient.gbp.v2_0.network:ShowNetworkExtension
openstack.cli.network_set =
network_set_extension = gbpclient.gbp.v2_0.network:CreateAndSetNetworkExtension
openstack.cli.subnet_create =
subnet_create_extension = gbpclient.gbp.v2_0.subnet:CreateAndSetSubnetExtension
openstack.cli.subnet_show =
subnet_show_extension = gbpclient.gbp.v2_0.subnet:ShowSubnetExtension
openstack.cli.subnet_set =
subnet_set_extension = gbpclient.gbp.v2_0.subnet:CreateAndSetSubnetExtension
openstack.cli.address_scope_create =
address_scope_create_extension = gbpclient.gbp.v2_0.address_scope:CreateAndSetAddressScopeExtension
openstack.cli.address_scope_show =
address_scope_show_extension = gbpclient.gbp.v2_0.address_scope:ShowAddressScopeExtension
openstack.cli.address_scope_set =
address_scope_set_extension = gbpclient.gbp.v2_0.address_scope:CreateAndSetAddressScopeExtension
openstack.cli.router_create =
router_create_extension = gbpclient.gbp.v2_0.router:CreateAndSetRouterExtension
openstack.cli.router_show =
router_show_extension = gbpclient.gbp.v2_0.router:ShowRouterExtension
openstack.cli.router_set =
router_set_extension = gbpclient.gbp.v2_0.router:CreateAndSetRouterExtension
[build_sphinx]
all_files = 1
build-dir = doc/build