From c772a1dbc7ace58d099570d41a889adf851c8ba8 Mon Sep 17 00:00:00 2001 From: Ulas Kozat Date: Mon, 28 Dec 2015 16:05:13 -0800 Subject: Added networking-sfc from openstack project with merge date Dec 23 2015 Added patch 13 for subject "add missing db migration files" Change-Id: Id51a160335a14870c1dd816a44baf9b1958b9ac6 --- networking_sfc/cli/__init__.py | 0 networking_sfc/cli/flow_classifier.py | 202 ++++++++++++++++++++++++++++++++++ networking_sfc/cli/port_chain.py | 141 ++++++++++++++++++++++++ networking_sfc/cli/port_pair.py | 124 +++++++++++++++++++++ networking_sfc/cli/port_pair_group.py | 114 +++++++++++++++++++ 5 files changed, 581 insertions(+) create mode 100644 networking_sfc/cli/__init__.py create mode 100644 networking_sfc/cli/flow_classifier.py create mode 100644 networking_sfc/cli/port_chain.py create mode 100644 networking_sfc/cli/port_pair.py create mode 100644 networking_sfc/cli/port_pair_group.py (limited to 'networking_sfc/cli') diff --git a/networking_sfc/cli/__init__.py b/networking_sfc/cli/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/networking_sfc/cli/flow_classifier.py b/networking_sfc/cli/flow_classifier.py new file mode 100644 index 0000000..128aa1c --- /dev/null +++ b/networking_sfc/cli/flow_classifier.py @@ -0,0 +1,202 @@ +# Copyright (c) 2015 Huawei Technologies India Pvt.Limited. +# 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.common import utils +from neutronclient.i18n import _ +from neutronclient.neutron import v2_0 as neutronv20 + +from networking_sfc.cli import port_pair as pp + +FLOW_CLASSIFIER_RESOURCE = 'flow_classifier' + + +def get_flowclassifier_id(client, id_or_name): + return neutronv20.find_resourceid_by_name_or_id(client, + FLOW_CLASSIFIER_RESOURCE, + id_or_name) + + +class FlowClassifier(extension.NeutronClientExtension): + resource = FLOW_CLASSIFIER_RESOURCE + resource_plural = '%ss' % resource + object_path = '/sfc/%s' % resource_plural + resource_path = '/sfc/%s/%%s' % resource_plural + versions = ['2.0'] + + +class FlowClassifierCreate(extension.ClientExtensionCreate, + FlowClassifier): + """Create a Flow Classifier.""" + + shell_command = 'flow-classifier-create' + + def add_known_arguments(self, parser): + parser.add_argument( + 'name', + metavar='NAME', + help=_('Name of the Flow Classifier.')) + parser.add_argument( + '--description', + help=_('Description for the Flow Classifier.')) + parser.add_argument( + '--protocol', + help=_('IP protocol name. Protocol name should be as per ' + 'IANA standard.')) + parser.add_argument( + '--ethertype', + default='IPv4', choices=['IPv4', 'IPv6'], + help=_('L2 ethertype, default is IPv4.')) + parser.add_argument( + '--source-port', + help=_('Source protocol port (allowed range [1,65535]. Must be ' + 'specified as a:b, where a=min-port and b=max-port.)')) + parser.add_argument( + '--destination-port', + help=_('Destination protocol port (allowed range [1,65535]. Must ' + 'be specified as a:b, where a=min-port and b=max-port.)')) + parser.add_argument( + '--source-ip-prefix', + help=_('Source IP prefix or subnet.')) + parser.add_argument( + '--destination-ip-prefix', + help=_('Destination IP prefix or subnet.')) + parser.add_argument( + '--logical-source-port', + help=_('ID or name of the neutron source port.')) + parser.add_argument( + '--logical-destination-port', + help=_('ID or name of the neutron destination port.')) + parser.add_argument( + '--l7-parameters', + metavar='type=TYPE[,url=URL_PATH]', + type=utils.str2dict, + help=_('Dictionary of L7-parameters. Currently, no value is ' + 'supported for this option.')) + + def args2body(self, parsed_args): + body = {} + client = self.get_client() + if parsed_args.logical_source_port: + body['logical_source_port'] = pp.get_port_id( + client, parsed_args.logical_source_port) + if parsed_args.logical_destination_port: + body['logical_destination_port'] = pp.get_port_id( + client, parsed_args.logical_destination_port) + if parsed_args.source_port: + self._fill_protocol_port_info(body, 'source', + parsed_args.source_port) + if parsed_args.destination_port: + self._fill_protocol_port_info(body, 'destination', + parsed_args.destination_port) + neutronv20.update_dict(parsed_args, body, + ['name', 'description', 'protocol', + 'ethertype', 'source_ip_prefix', + 'destination_ip_prefix', 'l7_parameters']) + return {self.resource: body} + + def _fill_protocol_port_info(self, body, port_type, port_val): + min_port, sep, max_port = port_val.partition(":") + if not max_port: + max_port = min_port + body[port_type + '_port_range_min'] = int(min_port) + body[port_type + '_port_range_max'] = int(max_port) + + +class FlowClassifierUpdate(extension.ClientExtensionUpdate, + FlowClassifier): + """Update Flow Classifier information.""" + + shell_command = 'flow-classifier-update' + + def add_known_arguments(self, parser): + parser.add_argument( + '--name', + metavar='NAME', + help=_('Name of the Flow Classifier.')) + parser.add_argument( + '--description', + help=_('Description for the Flow Classifier.')) + + def args2body(self, parsed_args): + body = {} + neutronv20.update_dict(parsed_args, body, ['name', 'description']) + return {self.resource: body} + + +class FlowClassifierDelete(extension.ClientExtensionDelete, + FlowClassifier): + """Delete a given Flow Classifier.""" + + shell_command = 'flow-classifier-delete' + + +class FlowClassifierList(extension.ClientExtensionList, + FlowClassifier): + """List Flow Classifiers that belong to a given tenant.""" + + shell_command = 'flow-classifier-list' + list_columns = ['id', 'name', 'summary'] + pagination_support = True + sorting_support = True + + def extend_list(self, data, parsed_args): + for d in data: + val = [] + if d.get('protocol'): + protocol = d['protocol'].upper() + else: + protocol = 'any' + protocol = 'protocol: ' + protocol + val.append(protocol) + val.append(self._get_protocol_port_details(d, 'source')) + val.append(self._get_protocol_port_details(d, 'destination')) + if 'logical_source_port' in d: + val.append('neutron_source_port: ' + + str(d['logical_source_port'])) + + if 'logical_destination_port' in d: + val.append('neutron_destination_port: ' + + str(d['logical_destination_port'])) + + if 'l7_parameters' in d: + l7_param = 'l7_parameters: ' + '{' + for r in d['l7_parameters']: + l7_param = l7_param + str(r).lower() + l7_param = l7_param + '}' + val.append(l7_param) + d['summary'] = ',\n'.join(val) + + def _get_protocol_port_details(self, data, type): + type_ip_prefix = type + '_ip_prefix' + ip_prefix = data.get(type_ip_prefix) + if ip_prefix is not None: + port_info = type + '[port]: ' + str(ip_prefix) + else: + port_info = type + '[port]: any' + min_port = data.get(type + '_port_range_min') + if min_port is not None: + max_port = data.get(type + '_port_range_max') + port_info = (port_info + '[' + str(min_port) + ':' + + str(max_port) + ']') + else: + port_info = port_info + '[any:any]' + return port_info + + +class FlowClassifierShow(extension.ClientExtensionShow, FlowClassifier): + """Show information of a given Flow Classifier.""" + + shell_command = 'flow-classifier-show' diff --git a/networking_sfc/cli/port_chain.py b/networking_sfc/cli/port_chain.py new file mode 100644 index 0000000..87bccf5 --- /dev/null +++ b/networking_sfc/cli/port_chain.py @@ -0,0 +1,141 @@ +# Copyright (c) 2015 Huawei Technologies India Pvt.Limited. +# 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.common import utils +from neutronclient.i18n import _ +from neutronclient.neutron import v2_0 as neutronv20 + +from networking_sfc.cli import flow_classifier as fc +from networking_sfc.cli import port_pair_group as ppg + +PORT_CHAIN_RESOURCE = 'port_chain' + + +class PortChain(extension.NeutronClientExtension): + resource = PORT_CHAIN_RESOURCE + resource_plural = '%ss' % resource + object_path = '/sfc/%s' % resource_plural + resource_path = '/sfc/%s/%%s' % resource_plural + versions = ['2.0'] + + +class PortChainCreate(extension.ClientExtensionCreate, PortChain): + """Create a Port Chain.""" + + shell_command = 'port-chain-create' + + def add_known_arguments(self, parser): + parser.add_argument( + 'name', + metavar='NAME', + help=_('Name of the Port Chain.')) + parser.add_argument( + '--description', + help=_('Description for the Port Chain.')) + parser.add_argument( + '--port-pair-group', + metavar='PORT-PAIR-GROUP', + dest='port_pair_groups', + default=[], required=True, + action='append', + help=_('ID or name of the Port Pair Group. ' + 'This option can be repeated.')) + parser.add_argument( + '--flow-classifier', + default=[], + metavar='FLOW-CLASSIFIER', + dest='flow_classifiers', + action='append', + help=_('ID or name of the Flow Classifier.' + 'This option can be repeated.')) + parser.add_argument( + '--chain-parameters', + metavar='type=TYPE[,correlation=CORRELATION_TYPE]', + type=utils.str2dict, + help=_('Dictionary of chain parameters. Currently, only ' + 'correlation=mpls is supported by default.')) + + def args2body(self, parsed_args): + body = {} + client = self.get_client() + if parsed_args.port_pair_groups: + body['port_pair_groups'] = [ppg.get_port_pair_group_id(client, p) + for p in parsed_args.port_pair_groups] + if parsed_args.flow_classifiers: + body['flow_classifiers'] = [fc.get_flowclassifier_id(client, f) + for f in parsed_args.flow_classifiers] + neutronv20.update_dict(parsed_args, body, ['name', 'description', + 'chain_parameters']) + return {self.resource: body} + + +class PortChainUpdate(extension.ClientExtensionUpdate, PortChain): + """Update Port Chain's information.""" + + shell_command = 'port-chain-update' + + def add_known_arguments(self, parser): + parser.add_argument( + '--name', + metavar='NAME', + help=_('Name of the Port Chain.')) + parser.add_argument( + '--description', + help=_('Description for the Port Chain.')) + fw_args = parser.add_mutually_exclusive_group() + fw_args.add_argument( + '--flow-classifier', + metavar='FLOW-CLASSIFIER', + dest='flow_classifiers', + action='append', + help=_('ID or name of the Flow Classifier. ' + 'This option can be repeated.')) + fw_args.add_argument( + '--no-flow-classifier', + action='store_true', + help=_('Associate no Flow Classifier with the Port Chain.')) + + def args2body(self, parsed_args): + body = {} + if parsed_args.flow_classifiers: + client = self.get_client() + body['flow_classifiers'] = [fc.get_flowclassifier_id(client, f) + for f in parsed_args.flow_classifiers] + elif parsed_args.no_flow_classifier: + body['flow_classifiers'] = [] + neutronv20.update_dict(parsed_args, body, ['name', 'description']) + return {self.resource: body} + + +class PortChainDelete(extension.ClientExtensionDelete, PortChain): + """Delete a given Port Chain.""" + + shell_command = 'port-chain-delete' + + +class PortChainList(extension.ClientExtensionList, PortChain): + """List Port Chains that belong to a given tenant.""" + + shell_command = 'port-chain-list' + list_columns = ['id', 'name', 'port_pair_groups', 'flow_classifiers'] + pagination_support = True + sorting_support = True + + +class PortChainShow(extension.ClientExtensionShow, PortChain): + """Show information of a given Port Chain.""" + + shell_command = 'port-chain-show' diff --git a/networking_sfc/cli/port_pair.py b/networking_sfc/cli/port_pair.py new file mode 100644 index 0000000..d934b02 --- /dev/null +++ b/networking_sfc/cli/port_pair.py @@ -0,0 +1,124 @@ +# Copyright (c) 2015 Huawei Technologies India Pvt.Limited. +# 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.common import utils +from neutronclient.i18n import _ +from neutronclient.neutron import v2_0 as neutronv20 + +PORT_RESOURCE = 'port' +PORT_PAIR_RESOURCE = 'port_pair' + + +def get_port_id(client, id_or_name): + return neutronv20.find_resourceid_by_name_or_id(client, + PORT_RESOURCE, + id_or_name) + + +def get_port_pair_id(client, id_or_name): + return neutronv20.find_resourceid_by_name_or_id(client, + PORT_PAIR_RESOURCE, + id_or_name) + + +class PortPair(extension.NeutronClientExtension): + resource = PORT_PAIR_RESOURCE + resource_plural = '%ss' % resource + object_path = '/sfc/%s' % resource_plural + resource_path = '/sfc/%s/%%s' % resource_plural + versions = ['2.0'] + + +class PortPairCreate(extension.ClientExtensionCreate, PortPair): + """Create a Port Pair.""" + + shell_command = 'port-pair-create' + + def add_known_arguments(self, parser): + parser.add_argument( + 'name', + metavar='NAME', + help=_('Name of the Port Pair.')) + parser.add_argument( + '--description', + help=_('Description for the Port Pair.')) + parser.add_argument( + '--ingress', + required=True, + help=_('ID or name of the ingress neutron port.')) + parser.add_argument( + '--egress', + required=True, + help=_('ID or name of the egress neutron port.')) + parser.add_argument( + '--service-function-parameters', + metavar='type=TYPE[,correlation=CORRELATION_TYPE]', + type=utils.str2dict, + help=_('Dictionary of Service function parameters. ' + 'Currently, only correlation=None is supported.')) + + def args2body(self, parsed_args): + body = {} + client = self.get_client() + if parsed_args.ingress: + body['ingress'] = get_port_id(client, parsed_args.ingress) + if parsed_args.egress: + body['egress'] = get_port_id(client, parsed_args.egress) + neutronv20.update_dict(parsed_args, body, + ['name', 'description', + 'service_function_parameters']) + return {self.resource: body} + + +class PortPairUpdate(extension.ClientExtensionUpdate, PortPair): + """Update Port Pair's information.""" + + shell_command = 'port-pair-update' + + def add_known_arguments(self, parser): + parser.add_argument( + '--name', + metavar='NAME', + help=_('Name of the Port Pair.')) + parser.add_argument( + '--description', + help=_('Description for the Port Pair.')) + + def args2body(self, parsed_args): + body = {} + neutronv20.update_dict(parsed_args, body, ['name', 'description']) + return {self.resource: body} + + +class PortPairDelete(extension.ClientExtensionDelete, PortPair): + """Delete a given Port Pair.""" + + shell_command = 'port-pair-delete' + + +class PortPairList(extension.ClientExtensionList, PortPair): + """List Port Pairs that belongs to a given tenant.""" + + shell_command = 'port-pair-list' + list_columns = ['id', 'name', 'ingress', 'egress'] + pagination_support = True + sorting_support = True + + +class PortPairShow(extension.ClientExtensionShow, PortPair): + """Show information of a given Port Pair.""" + + shell_command = 'port-pair-show' diff --git a/networking_sfc/cli/port_pair_group.py b/networking_sfc/cli/port_pair_group.py new file mode 100644 index 0000000..2df0b89 --- /dev/null +++ b/networking_sfc/cli/port_pair_group.py @@ -0,0 +1,114 @@ +# Copyright (c) 2015 Huawei Technologies India Pvt.Limited. +# 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 neutronv20 + +from networking_sfc.cli import port_pair as pp + +PORT_PAIR_GROUP_RESOURCE = 'port_pair_group' + + +def get_port_pair_group_id(client, id_or_name): + return neutronv20.find_resourceid_by_name_or_id(client, + PORT_PAIR_GROUP_RESOURCE, + id_or_name) + + +class PortPairGroup(extension.NeutronClientExtension): + resource = PORT_PAIR_GROUP_RESOURCE + resource_plural = '%ss' % resource + object_path = '/sfc/%s' % resource_plural + resource_path = '/sfc/%s/%%s' % resource_plural + versions = ['2.0'] + + +def add_common_arguments(parser): + parser.add_argument( + '--description', + help=_('Description for the Port Pair Group.')) + parser.add_argument( + '--port-pair', + metavar='PORT-PAIR', + dest='port_pairs', + default=[], + action='append', + help=_('ID or name of the Port Pair.' + 'This option can be repeated.')) + + +def update_common_args2body(client, body, parsed_args): + if parsed_args.port_pairs: + body['port_pairs'] = [(pp.get_port_pair_id(client, pp1)) + for pp1 in parsed_args.port_pairs] + neutronv20.update_dict(parsed_args, body, ['name', 'description']) + return body + + +class PortPairGroupCreate(extension.ClientExtensionCreate, PortPairGroup): + """Create a Port Pair Group.""" + shell_command = 'port-pair-group-create' + + def add_known_arguments(self, parser): + parser.add_argument( + 'name', + metavar='NAME', + help=_('Name of the Port Pair Group.')) + add_common_arguments(parser) + + def args2body(self, parsed_args): + body = {} + body = update_common_args2body(self.get_client(), body, parsed_args) + return {self.resource: body} + + +class PortPairGroupUpdate(extension.ClientExtensionUpdate, PortPairGroup): + """Update Port Pair Group's information.""" + + shell_command = 'port-pair-group-update' + + def add_known_arguments(self, parser): + parser.add_argument( + '--name', + metavar='NAME', + help=_('Name of the Port Pair Group.')) + add_common_arguments(parser) + + def args2body(self, parsed_args): + body = {} + body = update_common_args2body(self.get_client(), body, parsed_args) + return {self.resource: body} + + +class PortPairGroupDelete(extension.ClientExtensionDelete, PortPairGroup): + """Delete a given Port Pair Group.""" + + shell_command = 'port-pair-group-delete' + + +class PortPairGroupList(extension.ClientExtensionList, PortPairGroup): + """List Port Pair Groups that belongs to a given tenant.""" + + shell_command = 'port-pair-group-list' + list_columns = ['id', 'name', 'port_pairs'] + pagination_support = True + sorting_support = True + + +class PortPairGroupShow(extension.ClientExtensionShow, PortPairGroup): + """Show information of a given Port Pair Group.""" + + shell_command = 'port-pair-group-show' -- cgit 1.2.3-korg