def updatable_args2body(parsed_args, body, for_create=True, ip_version=None):
    if parsed_args.disable_dhcp and parsed_args.enable_dhcp:
        raise exceptions.CommandError(_(
            "You cannot enable and disable DHCP at the same time."))

    if parsed_args.no_gateway:
        body['gateway_ip'] = None
    elif parsed_args.gateway:
        body['gateway_ip'] = parsed_args.gateway
    if parsed_args.name:
        body['name'] = parsed_args.name
    if parsed_args.disable_dhcp:
        body['enable_dhcp'] = False
    if parsed_args.enable_dhcp:
        body['enable_dhcp'] = True
    if parsed_args.allocation_pools:
        body['allocation_pools'] = parsed_args.allocation_pools
    if parsed_args.host_routes:
        body['host_routes'] = parsed_args.host_routes
    if parsed_args.dns_nameservers:
        body['dns_nameservers'] = parsed_args.dns_nameservers
    if for_create and parsed_args.ipv6_ra_mode:
        if ip_version == 4:
            raise exceptions.CommandError(_("--ipv6-ra-mode is invalid "
                                            "when --ip-version is 4"))
        body['ipv6_ra_mode'] = parsed_args.ipv6_ra_mode
    if for_create and parsed_args.ipv6_address_mode:
        if ip_version == 4:
            raise exceptions.CommandError(_("--ipv6-address-mode is "
                                            "invalid when --ip-version "
                                            "is 4"))
        body['ipv6_address_mode'] = parsed_args.ipv6_address_mode
Beispiel #2
0
 def add_known_arguments(self, parser):
     add_updatable_arguments(parser)
     parser.add_argument(
         '--ip-version',
         type=int,
         default=4, choices=[4, 6],
         help=_('IP version to use, default is 4.'))
     parser.add_argument(
         '--ip_version',
         type=int,
         choices=[4, 6],
         help=argparse.SUPPRESS)
     parser.add_argument(
         'network_id', metavar='NETWORK',
         help=_('Network ID or name this subnet belongs to.'))
     parser.add_argument(
         'cidr', metavar='CIDR',
         help=_('CIDR of subnet to create.'))
     parser.add_argument(
         '--ipv6-ra-mode',
         choices=['dhcpv6-stateful', 'dhcpv6-stateless', 'slaac'],
         help=_('IPv6 RA (Router Advertisement) mode.'))
     parser.add_argument(
         '--ipv6-address-mode',
         choices=['dhcpv6-stateful', 'dhcpv6-stateless', 'slaac'],
         help=_('IPv6 address mode.'))
Beispiel #3
0
    def add_known_arguments(self, parser):
        """Adds to parser arguments common to create and update commands."""

        parser.add_argument(
            '--name',
            help=_('Name of the BGP VPN'))
        parser.add_argument(
            '--route-targets',
            help=_('Route Targets list to import/export for this BGP '
                   'VPN. Usage: -- --route-targets '
                   'list=true <asn1>:<nn1> <asn2>:<nn2> ...'))
        parser.add_argument(
            '--import-targets',
            help=_('List of additional Route Targets to import from.'
                   ' Usage: -- --import-targets list=true '
                   '<asn1>:<nn1> <asn2>:<nn2> ...'))
        parser.add_argument(
            '--export-targets',
            help=_('List of additional Route Targets to export to. Usage: -- '
                   '--export-targets list=true <asn1>:<nn1> <asn2>:<nn2> ...'))
        parser.add_argument(
            '--route-distinguishers',
            help=_('List of RDs that will be used to advertize VPN routes.'
                   'Usage: -- --route-distinguishers list=true '
                   '<asn1>:<nn1> <asn2>:<nn2> ...'))
def _networktemplateassignment_updatable_args(parser):
    parser.add_argument(
        'template_id', metavar='template-id',
        help=_('ID of the network template associated with this tenant.'))
    parser.add_argument(
        'stack_id', metavar='stack-id',
        help=_('ID of the heat template associated with this tenant.'))
def _add_updatable_args(parser):
    parser.add_argument(
        '--name',
        help=_('Name of this router type.'))
    parser.add_argument(
        '--description',
        help=_('Description of this router type.'))
    parser.add_argument(
        '--ha-enabled',
        dest='ha_enabled_by_default',
        action='store_true',
        help=_('Make HA enabled for the router type.'),
        default=argparse.SUPPRESS)
    parser.add_argument(
        '--ha_enabled',
        dest='ha_enabled_by_default',
        action='store_true',
        help=argparse.SUPPRESS,
        default=argparse.SUPPRESS)
    parser.add_argument(
        '--unshared',
        dest='shared',
        action='store_false',
        help=_('Make router type NOT shared among tenants.'),
        default=argparse.SUPPRESS)
    parser.add_argument(
        '--slot-need',
        help=_('Number of slots routers of this type consumes.'))
    parser.add_argument(
        '--slot_need',
        help=argparse.SUPPRESS)
Beispiel #6
0
    def add_known_arguments(self, parser):
        _add_updatable_args(parser)
        parser.add_argument(
            '--admin-state-down',
            dest='admin_state', action='store_false',
            help=_('Set admin state up to false.'))
        parser.add_argument(
            '--admin_state_down',
            dest='admin_state', action='store_false',
            help=argparse.SUPPRESS)
        parser.add_argument(
            '--mac-address',
            help=_('MAC address of this port.'))
        parser.add_argument(
            '--mac_address',
            help=argparse.SUPPRESS)
        parser.add_argument(
            '--vnic-type', metavar='<direct | macvtap | normal>',
            choices=['direct', 'macvtap', 'normal'],
            help=_('VNIC type for this port.'))
        parser.add_argument(
            '--vnic_type',
            choices=['direct', 'macvtap', 'normal'],
            help=argparse.SUPPRESS)
        self.add_arguments_secgroup(parser)
        self.add_arguments_extradhcpopt(parser)

        parser.add_argument(
            'network_id', metavar='NETWORK',
            help=_('Network ID or name this port belongs to.'))
 def get_parser(self, prog_name):
     parser = super(CreatePortPairGroup, self).get_parser(prog_name)
     parser.add_argument(
         'name',
         metavar='NAME',
         help=_('Name of the Port Pair Group.'))
     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.'))
     parser.add_argument(
         '--port-pair-group-parameters',
         metavar='[lb_fields=LB_FIELDS]',
         type=nc_utils.str2dict_type(optional_keys=['lb_fields']),
         help=_('Dictionary of Port pair group parameters. '
                'Currently, only \'&\' separated string of the lb_fields '
                'are supported.'))
     return parser
 def add_known_arguments(self, parser):
     parser.add_argument(
         '--name',
         help=_('Name of security group.'))
     parser.add_argument(
         '--description',
         help=_('Description of security group.'))
Beispiel #9
0
def add_bandwidth_limit_arguments(parser):
    parser.add_argument(
        '--max_kbps',
        help=_('max bandwidth in kbps.'))
    parser.add_argument(
        '--max_burst_kbps',
        help=_('Max burst bandwidth in kbps.'))
Beispiel #10
0
 def add_known_arguments(self, parser):
     parser.add_argument(
         '--name',
         help=_('Name of this router.'))
     utils.add_boolean_argument(
         parser, '--admin-state-up', dest='admin_state',
         help=_('Specify the administrative state of the router'
                ' (True meaning "Up")'))
     utils.add_boolean_argument(
         parser, '--admin_state_up', dest='admin_state',
         help=argparse.SUPPRESS)
     utils.add_boolean_argument(
         parser, '--distributed', dest='distributed',
         help=_('True means this router should operate in'
                ' distributed mode.'))
     routes_group = parser.add_mutually_exclusive_group()
     routes_group.add_argument(
         '--route', metavar='destination=CIDR,nexthop=IP_ADDR',
         action='append', dest='routes', type=utils.str2dict,
         help=_('Route to associate with the router.'
                ' You can repeat this option.'))
     routes_group.add_argument(
         '--no-routes',
         action='store_true',
         help=_('Remove routes associated with the router.'))
Beispiel #11
0
 def get_parser(self, prog_name):
     parser = super(CreatePortChain, self).get_parser(prog_name)
     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',
         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='[correlation=CORRELATION_TYPE, symmetric=BOOLEAN_TYPE]',
         type=nc_utils.str2dict_type(optional_keys=['correlation',
                                                    'symmetric']),
         help=_('Dictionary of chain parameters. Supports '
                'correlation=mpls and symmetric=true|false'))
     return parser
Beispiel #12
0
def _add_updatable_args(parser):
    parser.add_argument(
        '--name',
        help=_('Name of this port.'))
    parser.add_argument(
        '--fixed-ip', metavar='subnet_id=SUBNET,ip_address=IP_ADDR',
        action='append',
        help=_('Desired IP and/or subnet for this port: '
               'subnet_id=<name_or_id>,ip_address=<ip>. '
               'You can repeat this option.'))
    parser.add_argument(
        '--fixed_ip',
        action='append',
        help=argparse.SUPPRESS)
    parser.add_argument(
        '--device-id',
        help=_('Device ID of this port.'))
    parser.add_argument(
        '--device_id',
        help=argparse.SUPPRESS)
    parser.add_argument(
        '--device-owner',
        help=_('Device owner of this port.'))
    parser.add_argument(
        '--device_owner',
        help=argparse.SUPPRESS)
 def add_known_arguments(self, parser):
     parser.add_argument(
         '--servicetype', dest='service_type',
         help=_('Service type ID or the Service Type name'))
     parser.add_argument(
         '--config',
         help=_('Service Configuration for the Service Chain Node.'))
 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."),
     )
Beispiel #15
0
def add_updatable_arguments(parser):
    parser.add_argument("--min-prefixlen", type=int, help=_("Subnetpool minimum prefix length."))
    parser.add_argument("--max-prefixlen", type=int, help=_("Subnetpool maximum prefix length."))
    parser.add_argument("--default-prefixlen", type=int, help=_("Subnetpool default prefix length."))
    parser.add_argument(
        "--pool-prefix", action="append", dest="prefixes", help=_("Subnetpool prefixes (This option can be repeated).")
    )
Beispiel #16
0
def updatable_args2body(parsed_args, body, for_create=True, ip_version=None):
    if parsed_args.disable_dhcp and parsed_args.enable_dhcp:
        raise exceptions.CommandError(_("You cannot enable and disable DHCP at the same time."))

    if parsed_args.no_gateway:
        body["subnet"].update({"gateway_ip": None})
    elif parsed_args.gateway:
        body["subnet"].update({"gateway_ip": parsed_args.gateway})
    if parsed_args.name:
        body["subnet"].update({"name": parsed_args.name})
    if parsed_args.disable_dhcp:
        body["subnet"].update({"enable_dhcp": False})
    if parsed_args.enable_dhcp:
        body["subnet"].update({"enable_dhcp": True})
    if parsed_args.allocation_pools:
        body["subnet"]["allocation_pools"] = parsed_args.allocation_pools
    if parsed_args.host_routes:
        body["subnet"]["host_routes"] = parsed_args.host_routes
    if parsed_args.dns_nameservers:
        body["subnet"]["dns_nameservers"] = parsed_args.dns_nameservers
    if for_create and parsed_args.ipv6_ra_mode:
        if ip_version == 4:
            raise exceptions.CommandError(_("--ipv6-ra-mode is invalid " "when --ip-version is 4"))
        body["subnet"]["ipv6_ra_mode"] = parsed_args.ipv6_ra_mode
    if for_create and parsed_args.ipv6_address_mode:
        if ip_version == 4:
            raise exceptions.CommandError(_("--ipv6-address-mode is " "invalid when --ip-version " "is 4"))
        body["subnet"]["ipv6_address_mode"] = parsed_args.ipv6_address_mode
 def add_known_arguments(self, parser):
     # adding admin_state_up here so that it is available for update only
     # as it is True by default and not meaningful in the create operation
     parser.add_argument(
         '--admin-state-up',
         dest='admin_state_up',
         action='store_true',
         help=_('Set hosting device administratively up.'),
         default=argparse.SUPPRESS)
     parser.add_argument(
         '--admin_state_up',
         dest='admin_state_up',
         action='store_true',
         help=argparse.SUPPRESS,
         default=argparse.SUPPRESS)
     # adding no_auto_delete here so that it is available for update only
     # as auto_delete is False by default and not meaningful in the create
     # operation
     parser.add_argument(
         '--no-auto-delete',
         dest='auto_delete',
         action='store_false',
         help=_('Exempt hosting device from automated life cycle '
                'management.'),
         default=argparse.SUPPRESS)
     parser.add_argument(
         '--no_auto_delete',
         dest='auto_delete',
         action='store_false',
         help=argparse.SUPPRESS,
         default=argparse.SUPPRESS)
     _add_updatable_args(parser)
Beispiel #18
0
 def get_parser(self, prog_name):
     parser = super(CreatePortPair, self).get_parser(prog_name)
     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-parameter',
         metavar='[correlation=CORRELATION_TYPE, weight=WEIGHT]',
         type=nc_utils.str2dict_type(optional_keys=['correlation',
                                                    'weight']),
         help=_('Dictionary of Service function parameters. '
                'Currently, only correlation=None and weight '
                'is supported. Weight is an integer that influences '
                'the selection of a port pair within a port pair group '
                'for a flow. The higher the weight, the more flows will '
                'hash to the port pair. The default weight is 1.'))
     return parser
Beispiel #19
0
def validate_dpd_dict(dpd_dict):
    for key, value in dpd_dict.items():
        if key not in dpd_supported_keys:
            message = _(
                "DPD Dictionary KeyError: "
                "Reason-Invalid DPD key : "
                "'%(key)s' not in %(supported_key)s ") % {
                    'key': key, 'supported_key': dpd_supported_keys}
            raise exceptions.CommandError(message)
        if key == 'action' and value not in dpd_supported_actions:
            message = _(
                "DPD Dictionary ValueError: "
                "Reason-Invalid DPD action : "
                "'%(key_value)s' not in %(supported_action)s ") % {
                    'key_value': value,
                    'supported_action': dpd_supported_actions}
            raise exceptions.CommandError(message)
        if key in ('interval', 'timeout'):
            try:
                if int(value) <= 0:
                    raise ValueError()
            except ValueError:
                message = _(
                    "DPD Dictionary ValueError: "
                    "Reason-Invalid positive integer value: "
                    "'%(key)s' = %(value)s ") % {
                        'key': key, 'value': value}
                raise exceptions.CommandError(message)
            else:
                dpd_dict[key] = int(value)
    return
Beispiel #20
0
def validate_lifetime_dict(lifetime_dict):

    for key, value in lifetime_dict.items():
        if key not in lifetime_keys:
            message = _(
                "Lifetime Dictionary KeyError: "
                "Reason-Invalid unit key : "
                "'%(key)s' not in %(supported_key)s ") % {
                    'key': key, 'supported_key': lifetime_keys}
            raise exceptions.CommandError(message)
        if key == 'units' and value not in lifetime_units:
            message = _(
                "Lifetime Dictionary ValueError: "
                "Reason-Invalid units : "
                "'%(key_value)s' not in %(supported_units)s ") % {
                    'key_value': key, 'supported_units': lifetime_units}
            raise exceptions.CommandError(message)
        if key == 'value':
            try:
                if int(value) < 60:
                    raise ValueError()
            except ValueError:
                message = _(
                    "Lifetime Dictionary ValueError: "
                    "Reason-Invalid value should be at least 60:"
                    "'%(key_value)s' = %(value)s ") % {
                        'key_value': key, 'value': value}
                raise exceptions.CommandError(message)
            else:
                lifetime_dict['value'] = int(value)
    return
 def get_parser(self, prog_name):
     parser = super(UpdatePolicyProfileV2, self).get_parser(prog_name)
     parser.add_argument("--add-tenant",
                         help=_("Add tenant to the policy profile."))
     parser.add_argument("--remove-tenant",
                         help=_("Remove tenant from the policy profile."))
     return parser
 def add_known_arguments(self, parser):
     parser.add_argument(
         "--nodes",
         type=string.split,
         help=_("List of Service Chain Node IDs or names of the Service " "Chain Nodes"),
     )
     parser.add_argument("--shared", type=bool, help=_("Shared flag"))
def _networktemplate_updatable_args(parser):
    parser.add_argument(
        'name',
        help=_('Name of this network template.'))
    parser.add_argument(
        'body',
        help=_('Body of this network template.'))
    def add_known_arguments(self, parser):
        _add_updatable_args(parser)
        parser.add_argument(
            '--id',
            help=_('Id for this hosting device.'))
        parser.add_argument(
            '--management-port',
            help=_('Neutron port used for management of hosting device.'))
        parser.add_argument(
            '--management_port',
            help=argparse.SUPPRESS)
        parser.add_argument(
            '--cfg-agent-id',
            help=_('Config agent to handle the hosting device.'))
        parser.add_argument(
            '--cfg_agent_id',
            help=argparse.SUPPRESS)

        parser.add_argument(
            'name', metavar='NAME',
            help=_('Name of hosting device to create.'))
        parser.add_argument(
            'template_id', metavar='TEMPLATE',
            help=_('Hosting device template template to associate '
                   'hosting device with.'))
def _add_updatable_args(parser):
    parser.add_argument(
        '--name',
        help=_('Name of this Tap service.'))
    parser.add_argument(
        '--description',
        help=_('Description for this Tap service.'))
    def retry_request(self, method, action, body=None,
                      headers=None, params=None):
        """Call do_request with the default retry configuration.

        Only idempotent requests should retry failed connection attempts.
        :raises: ConnectionFailed if the maximum # of retries is exceeded
        """
        max_attempts = self.retries + 1
        for i in range(max_attempts):
            try:
                return self.do_request(method, action, body=body,
                                       headers=headers, params=params)
            except exceptions.ConnectionFailed:
                # Exception has already been logged by do_request()
                if i < self.retries:
                    _logger.debug('Retrying connection to Neutron service')
                    time.sleep(self.retry_interval)
                elif self.raise_errors:
                    raise

        if self.retries:
            msg = (_("Failed to connect to Neutron server after %d attempts")
                   % max_attempts)
        else:
            msg = _("Failed to connect Neutron server")

        raise exceptions.ConnectionFailed(reason=msg)
 def run(self, parsed_args):
     self.log.debug('run(%s)', parsed_args)
     self.set_extra_attrs(parsed_args)
     neutron_client = self.get_client()
     neutron_client.format = parsed_args.request_format
     _extra_values = parse_args_to_dict(self.values_specs)
     _merge_args(self, parsed_args, _extra_values,
                 self.values_specs)
     body = self.args2body(parsed_args)
     if self.resource in body:
         body[self.resource].update(_extra_values)
     else:
         body[self.resource] = _extra_values
     if not body[self.resource]:
         raise exceptions.CommandError(
             _("Must specify new values to update %s") %
             self.cmd_resource)
     if self.allow_names:
         _id = find_resourceid_by_name_or_id(
             neutron_client, self.resource, parsed_args.id,
             cmd_resource=self.cmd_resource, parent_id=self.parent_id)
     else:
         _id = find_resourceid_by_id(
             neutron_client, self.resource, parsed_args.id,
             self.cmd_resource, self.parent_id)
     obj_updater = getattr(neutron_client,
                           "update_%s" % self.cmd_resource)
     if self.parent_id:
         obj_updater(_id, self.parent_id, body)
     else:
         obj_updater(_id, body)
     print((_('Updated %(resource)s: %(id)s') %
            {'id': parsed_args.id, 'resource': self.resource}),
           file=self.app.stdout)
     return
 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.'))
Beispiel #29
0
 def get_parser(self, prog_name):
     parser = super(SetGatewayRouter, self).get_parser(prog_name)
     parser.add_argument("router_id", metavar="router-id", help=_("ID of the router."))
     parser.add_argument(
         "external_network_id", metavar="external-network-id", help=_("ID of the external network for the gateway.")
     )
     parser.add_argument("--disable-snat", action="store_true", help=_("Disable source NAT on the router gateway."))
     return parser
 def add_known_arguments(self, parser):
     parser.add_argument(
         '--qos-policy',
         help=_('Attach QoS policy ID or name to the network.'))
     parser.add_argument(
         '--no-qos-policy',
         action='store_true',
         help=_('Detach QoS policy from the network.'))
 def run(self, parsed_args):
     self.log.debug('run(%s)' % parsed_args)
     neutron_client = self.get_client()
     neutron_client.format = parsed_args.request_format
     (gateway_id, network_id) = self.retrieve_ids(neutron_client,
                                                  parsed_args)
     neutron_client.disconnect_network_gateway(
         gateway_id, {
             'network_id': network_id,
             'segmentation_type': parsed_args.segmentation_type,
             'segmentation_id': parsed_args.segmentation_id
         })
     # TODO(Salvatore-Orlando): Do output formatting as
     # any other command
     print(_('Disconnected network from gateway %s') % gateway_id,
           file=self.app.stdout)
 def _validate_protocol(self, protocol):
     if not protocol or protocol == 'action=clear':
         return
     try:
         protocol = int(protocol, 0)
         if 0 <= protocol <= 255:
             return
     except ValueError:
         # Use string as a protocol name
         # Exact check will be done in the server side.
         return
     msg = (_('protocol %s should be either of name '
              '(tcp, udp, icmp, arp; '
              'case insensitive) or integer [0:255] (decimal or hex).') %
            protocol)
     raise exceptions.CommandError(msg)
Beispiel #33
0
 def __call__(self, parser, namespace, values, option_string=None):
     outputs = []
     max_len = 0
     app = self.default
     parser.print_help(app.stdout)
     app.stdout.write(_('\nCommands for API v%s:\n') % app.api_version)
     command_manager = app.command_manager
     for name, ep in sorted(command_manager):
         factory = ep.load()
         cmd = factory(self, None)
         one_liner = cmd.get_description().split('\n')[0]
         outputs.append((name, one_liner))
         max_len = max(len(name), max_len)
     for (name, one_liner) in outputs:
         app.stdout.write('  %s  %s\n' % (name.ljust(max_len), one_liner))
     sys.exit(0)
Beispiel #34
0
 def add_known_arguments(self, parser):
     parser.add_argument(
         '--admin-state-down',
         dest='admin_state', action='store_false',
         help=_('Set admin state up to false.'))
     parser.add_argument(
         '--connection-limit',
         help=_('The maximum number of connections per second allowed for '
                'the vip. Positive integer or -1 for unlimited (default).'))
     parser.add_argument(
         '--description',
         help=_('Description of the listener.'))
     parser.add_argument(
         '--name',
         help=_('The name of the listener.'))
     parser.add_argument(
         '--default-tls-container-id',
         dest='default_tls_container_id',
         help=_('Default TLS container ID to retrieve TLS information.'))
     parser.add_argument(
         '--sni-container-ids',
         dest='sni_container_ids',
         nargs='+',
         help=_('List of TLS container IDs for SNI.'))
     parser.add_argument(
         '--loadbalancer',
         required=True,
         metavar='LOADBALANCER',
         help=_('ID or name of the load balancer.'))
     parser.add_argument(
         '--protocol',
         required=True,
         choices=['TCP', 'HTTP', 'HTTPS', 'TERMINATED_HTTPS'],
         help=_('Protocol for the listener.'))
     parser.add_argument(
         '--protocol-port',
         dest='protocol_port', required=True,
         metavar='PORT',
         help=_('Protocol port for the listener.'))
 def get_data(self, parsed_args):
     self.log.debug('run(%s)' % parsed_args)
     neutron_client = self.get_client()
     neutron_client.format = parsed_args.request_format
     _id_hd = neutronV20.find_resourceid_by_name_or_id(
         neutron_client, 'hosting_device', parsed_args.hosting_device)
     _id_r = neutronV20.find_resourceid_by_name_or_id(
         neutron_client, 'router', parsed_args.router)
     self.add_router_to_hosting_device(neutron_client, _id_hd,
                                       {'router_id': _id_r})
     print(_('Added router \'%(router)s\' to hosting device \'%(hd)s\'') % {
         'router': parsed_args.router,
         'hd': parsed_args.hosting_device
     },
           file=self.app.stdout,
           end='')
     return [], []
 def get_data(self, parsed_args):
     self.log.debug('run(%s)' % parsed_args)
     neutron_client = self.get_client()
     neutron_client.format = parsed_args.request_format
     _id_hd = neutronV20.find_resourceid_by_name_or_id(
         neutron_client, 'hosting_device', parsed_args.hosting_device)
     self.associate_hosting_device_with_config_agent(
         neutron_client, parsed_args.config_agent_id,
         {'hosting_device_id': _id_hd})
     print(_('Associated hosting device \'%(hd)s\' with Cisco '
             'configuration agent \'%(agent)s\'') % {
                 'hd': parsed_args.hosting_device,
                 'agent': parsed_args.config_agent_id
             },
           file=self.app.stdout,
           end='')
     return [], []
 def run(self, parsed_args):
     self.log.debug('run(%s)' % parsed_args)
     neutron_client = self.get_client()
     neutron_client.format = parsed_args.request_format
     data = {self.resource: parse_args_to_dict(parsed_args)}
     if parsed_args.add_tenant:
         data[self.resource]['add_tenant'] = parsed_args.add_tenant
     if parsed_args.remove_tenant:
         data[self.resource]['remove_tenant'] = parsed_args.remove_tenant
     neutron_client.update_policy_profile(parsed_args.id,
                                          {self.resource: data})
     print((_('Updated %(resource)s: %(id)s') % {
         'id': parsed_args.id,
         'resource': self.resource
     }),
           file=self.app.stdout)
     return
def _process_previous_argument(current_arg, _value_number, current_type_str,
                               _list_flag, _values_specs, _clear_flag,
                               values_specs):
    if current_arg is not None:
        if _value_number == 0 and (current_type_str or _list_flag):
            # This kind of argument should have value
            raise exceptions.CommandError(
                _("Invalid values_specs %s") % ' '.join(values_specs))
        if _value_number > 1 or _list_flag or current_type_str == 'list':
            current_arg.update({'nargs': '+'})
        elif _value_number == 0:
            if _clear_flag:
                # if we have action=clear, we use argument's default
                # value None for argument
                _values_specs.pop()
            else:
                # We assume non value argument as bool one
                current_arg.update({'action': 'store_true'})
 def add_known_arguments(self, parser):
     parser.add_argument('--admin-state-down',
                         dest='admin_state',
                         action='store_false',
                         help=_('Set admin state up to false.'))
     parser.add_argument(
         '--expected-codes',
         help=_('The list of HTTP status codes expected in '
                'response from the member to declare it healthy. This '
                'attribute can contain one value, '
                'or a list of values separated by comma, '
                'or a range of values (e.g. "200-299"). If this attribute '
                'is not specified, it defaults to "200".'))
     parser.add_argument(
         '--http-method',
         help=_('The HTTP method used for requests by the monitor of type '
                'HTTP.'))
     parser.add_argument(
         '--url-path',
         help=_('The HTTP path used in the HTTP request used by the monitor'
                ' to test a member health. This must be a string '
                'beginning with a / (forward slash).'))
     parser.add_argument(
         '--delay',
         required=True,
         help=_('The time in seconds between sending probes to members.'))
     parser.add_argument(
         '--max-retries',
         required=True,
         help=_('Number of permissible connection failures before changing '
                'the member status to INACTIVE. [1..10]'))
     parser.add_argument(
         '--timeout',
         required=True,
         help=_('Maximum number of seconds for a monitor to wait for a '
                'connection to be established before it times out. The '
                'value must be less than the delay value.'))
     parser.add_argument(
         '--type',
         required=True,
         choices=['PING', 'TCP', 'HTTP', 'HTTPS'],
         help=_('One of the predefined health monitor types.'))
 def add_known_arguments(self, parser):
     parser.add_argument('name', metavar='NAME', help=_('Name of queue.'))
     parser.add_argument('--min', help=_('Minimum rate.')),
     parser.add_argument('--max', help=_('Maximum rate.')),
     parser.add_argument('--qos-marking',
                         help=_('QOS marking as untrusted or trusted.')),
     parser.add_argument(
         '--default',
         default=False,
         help=_('If true all created ports will be the size of this queue, '
                'if queue is not specified')),
     parser.add_argument('--dscp',
                         help=_('Differentiated Services Code Point.')),
    def args2body(self, parsed_args):
        _network_id = neutronV20.find_resourceid_by_name_or_id(
            self.get_client(), 'network', parsed_args.network_id)
        body = {'network_id': _network_id}

        if parsed_args.prefixlen:
            body['prefixlen'] = parsed_args.prefixlen
        ip_version = parsed_args.ip_version
        if parsed_args.subnetpool:
            if parsed_args.subnetpool == 'None':
                _subnetpool_id = None
            else:
                _subnetpool = neutronV20.find_resource_by_name_or_id(
                    self.get_client(), 'subnetpool', parsed_args.subnetpool)
                _subnetpool_id = _subnetpool['id']
                # Now that we have the pool_id - let's just have a check on the
                # ip version used in the pool
                ip_version = _subnetpool['ip_version']
            body['subnetpool_id'] = _subnetpool_id

        # IP version needs to be set as IP version can be
        # determined by subnetpool.
        body['ip_version'] = ip_version

        if parsed_args.cidr:
            # With subnetpool, cidr is now optional for creating subnet.
            cidr = parsed_args.cidr
            body['cidr'] = cidr
            unusable_cidr = '/32' if ip_version == 4 else '/128'
            if cidr.endswith(unusable_cidr):
                self.log.warning(
                    _("An IPv%(ip)d subnet with a %(cidr)s CIDR "
                      "will have only one usable IP address so "
                      "the device attached to it will not have "
                      "any IP connectivity.") % {
                          "ip": ip_version,
                          "cidr": unusable_cidr
                      })

        updatable_args2body(parsed_args, body, ip_version=ip_version)
        if parsed_args.tenant_id:
            body['tenant_id'] = parsed_args.tenant_id

        return {'subnet': body}
 def add_known_arguments(self, parser):
     parser.add_argument('--name', help=_('Name for the Service Profile.'))
     parser.add_argument('--description',
                         help=_('Description of the Service Profile.'))
     n_utils.add_boolean_argument(parser,
                                  '--shared',
                                  dest='shared',
                                  help=_('Shared flag'))
     parser.add_argument('--vendor',
                         help=_('Vendor providing the service node'))
     parser.add_argument('--insertion-mode',
                         help=_('Insertion mode of the service'))
     parser.add_argument('--servicetype',
                         dest='service_type',
                         help=_('Type of the service'))
     parser.add_argument('--service-flavor',
                         help=_('Flavor of the service'))
Beispiel #43
0
 def add_known_arguments(self, parser):
     parser.add_argument('--admin-state-down',
                         dest='admin_state',
                         action='store_false',
                         help=_('Set admin state up to false.'))
     parser.add_argument('--admin_state_down',
                         dest='admin_state',
                         action='store_false',
                         help=argparse.SUPPRESS)
     parser.add_argument('--shared',
                         action='store_true',
                         help=_('Set the network as shared.'),
                         default=argparse.SUPPRESS)
     parser.add_argument(
         '--router:external',
         action='store_true',
         help=_('Set network as external, it is only available for admin'),
         default=argparse.SUPPRESS)
     parser.add_argument(
         '--provider:network_type',
         metavar='<network_type>',
         help=_('The physical mechanism by which the virtual network'
                ' is implemented.'))
     parser.add_argument(
         '--provider:physical_network',
         metavar='<physical_network_name>',
         help=_('Name of the physical network over which the virtual'
                ' network is implemented.'))
     parser.add_argument(
         '--provider:segmentation_id',
         metavar='<segmentation_id>',
         help=_('VLAN ID for VLAN networks or tunnel-id for GRE/VXLAN'
                ' networks.'))
     utils.add_boolean_argument(
         parser,
         '--vlan-transparent',
         default=argparse.SUPPRESS,
         help=_('Create a vlan transparent network.'))
     parser.add_argument('name',
                         metavar='NAME',
                         help=_('Name of network to create.'))
    def get_parser(self, prog_name):
        parser = super(NeutronCommand, self).get_parser(prog_name)
        parser.add_argument(
            '--request-format',
            help=_('The XML or JSON request format.'),
            default='json',
            choices=[
                'json',
                'xml',
            ],
        )
        parser.add_argument('--request_format',
                            choices=[
                                'json',
                                'xml',
                            ],
                            help=argparse.SUPPRESS)

        return parser
Beispiel #45
0
 def add_known_arguments(self, parser):
     parser.add_argument('security_group_id',
                         metavar='SECURITY_GROUP',
                         help=_('Security group name or ID to add rule.'))
     parser.add_argument('--direction',
                         default='ingress',
                         choices=['ingress', 'egress'],
                         help=_('Direction of traffic: ingress/egress.'))
     parser.add_argument('--ethertype', default='IPv4', help=_('IPv4/IPv6'))
     parser.add_argument('--protocol', help=_('Protocol of packet.'))
     parser.add_argument('--port-range-min', help=_('Starting port range.'))
     parser.add_argument('--port_range_min', help=argparse.SUPPRESS)
     parser.add_argument('--port-range-max', help=_('Ending port range.'))
     parser.add_argument('--port_range_max', help=argparse.SUPPRESS)
     parser.add_argument('--remote-ip-prefix', help=_('CIDR to match on.'))
     parser.add_argument('--remote_ip_prefix', help=argparse.SUPPRESS)
     parser.add_argument(
         '--remote-group-id',
         metavar='REMOTE_GROUP',
         help=_('Remote security group name or ID to apply rule.'))
     parser.add_argument('--remote_group_id', help=argparse.SUPPRESS)
 def add_known_arguments(self, parser):
     parser.add_argument('--description',
                         help=_('Description of the load balancer.'))
     parser.add_argument('--admin-state-down',
                         dest='admin_state',
                         action='store_false',
                         help=_('Set admin state up to false.'))
     parser.add_argument('--name',
                         metavar='NAME',
                         help=_('Name of the load balancer.'))
     parser.add_argument('--provider',
                         help=_('Provider name of load balancer service.'))
     parser.add_argument('--flavor', help=_('ID or name of flavor.'))
     parser.add_argument('--vip-address',
                         help=_('VIP address for the load balancer.'))
     parser.add_argument('vip_subnet',
                         metavar='VIP_SUBNET',
                         help=_('Load balancer VIP subnet.'))
 def get_data(self, parsed_args):
     self.log.debug('get_data(%s)' % parsed_args)
     neutron_client = self.get_client()
     neutron_client.format = parsed_args.request_format
     _extra_values = parse_args_to_dict(self.values_specs)
     _merge_args(self, parsed_args, _extra_values, self.values_specs)
     body = self.args2body(parsed_args)
     body[self.resource].update(_extra_values)
     obj_creator = getattr(neutron_client, "create_%s" % self.cmd_resource)
     if self.parent_id:
         data = obj_creator(self.parent_id, body)
     else:
         data = obj_creator(body)
     self.format_output_data(data)
     info = self.resource in data and data[self.resource] or None
     if info:
         print(_('Created a new %s:') % self.resource, file=self.app.stdout)
     else:
         info = {'': ''}
     return zip(*sorted(six.iteritems(info)))
class NeutronException(Exception):
    """Base Neutron Exception.

    To correctly use this class, inherit from it and define
    a 'message' property. That message will get printf'd
    with the keyword arguments provided to the constructor.
    """
    message = _("An unknown exception occurred.")

    def __init__(self, message=None, **kwargs):
        if message:
            self.message = message
        try:
            self._error_string = self.message % kwargs
        except Exception:
            # at least get the core message out if something happened
            self._error_string = self.message

    def __str__(self):
        return self._error_string
Beispiel #49
0
 def run_subcommand(self, argv):
     subcommand = self.command_manager.find_command(argv)
     cmd_factory, cmd_name, sub_argv = subcommand
     cmd = cmd_factory(self, self.options)
     try:
         self.prepare_to_run_command(cmd)
         full_name = (cmd_name if self.interactive_mode else ' '.join(
             [self.NAME, cmd_name]))
         cmd_parser = cmd.get_parser(full_name)
         return run_command(cmd, cmd_parser, sub_argv)
     except SystemExit:
         print(_("Try 'neutron help %s' for more information.") % cmd_name,
               file=sys.stderr)
         raise
     except Exception as e:
         if self.options.verbose_level >= self.DEBUG_LEVEL:
             self.log.exception("%s", e)
             raise
         self.log.error("%s", e)
     return 1
Beispiel #50
0
def get_client_class(api_name, version, version_map):
    """Returns the client class for the requested API version.

    :param api_name: the name of the API, e.g. 'compute', 'image', etc
    :param version: the requested API version
    :param version_map: a dict of client classes keyed by version
    :rtype: a client class for the requested API version
    """
    try:
        client_path = version_map[str(version)]
    except (KeyError, ValueError):
        msg = _("Invalid %(api_name)s client version '%(version)s'. must be "
                "one of: %(map_keys)s")
        msg = msg % {
            'api_name': api_name,
            'version': version,
            'map_keys': ', '.join(version_map.keys())
        }
        raise exceptions.UnsupportedVersion(msg)

    return importutils.import_class(client_path)
    def args2body(self, parsed_args):
        _vpnservice_id = neutronv20.find_resourceid_by_name_or_id(
            self.get_client(), 'vpnservice', parsed_args.vpnservice_id)
        _ikepolicy_id = neutronv20.find_resourceid_by_name_or_id(
            self.get_client(), 'ikepolicy', parsed_args.ikepolicy_id)
        _ipsecpolicy_id = neutronv20.find_resourceid_by_name_or_id(
            self.get_client(), 'ipsecpolicy', parsed_args.ipsecpolicy_id)
        if int(parsed_args.mtu) < 68:
            message = _("Invalid MTU value: MTU must be "
                        "greater than or equal to 68")
            raise exceptions.CommandError(message)
        body = {
            'ipsec_site_connection': {
                'vpnservice_id': _vpnservice_id,
                'ikepolicy_id': _ikepolicy_id,
                'ipsecpolicy_id': _ipsecpolicy_id,
                'peer_address': parsed_args.peer_address,
                'peer_id': parsed_args.peer_id,
                'mtu': parsed_args.mtu,
                'initiator': parsed_args.initiator,
                'psk': parsed_args.psk,
                'admin_state_up': parsed_args.admin_state_down,
            },
        }
        if parsed_args.name:
            body['ipsec_site_connection'].update({'name': parsed_args.name})
        if parsed_args.description:
            body['ipsec_site_connection'].update(
                {'description': parsed_args.description})
        if parsed_args.tenant_id:
            body['ipsec_site_connection'].update(
                {'tenant_id': parsed_args.tenant_id})
        if parsed_args.dpd:
            vpn_utils.validate_dpd_dict(parsed_args.dpd)
            body['ipsec_site_connection'].update({'dpd': parsed_args.dpd})
        if parsed_args.peer_cidrs:
            body['ipsec_site_connection'][
                'peer_cidrs'] = parsed_args.peer_cidrs

        return body
Beispiel #52
0
    def args2body(self, parsed_args):
        _network_id = neutronV20.find_resourceid_by_name_or_id(
            self.get_client(), 'network', parsed_args.network_id)
        body = {
            'subnet': {
                'network_id': _network_id,
                'ip_version': parsed_args.ip_version,
            },
        }

        if parsed_args.cidr:
            # With subnetpool, cidr is now optional for creating subnet.
            cidr = parsed_args.cidr
            body['subnet'].update({'cidr': cidr})
            unusable_cidr = '/32' if parsed_args.ip_version == 4 else '/128'
            if cidr.endswith(unusable_cidr):
                self.log.warning(
                    _("An IPv%(ip)d subnet with a %(cidr)s CIDR "
                      "will have only one usable IP address so "
                      "the device attached to it will not have "
                      "any IP connectivity.") % {
                          "ip": parsed_args.ip_version,
                          "cidr": unusable_cidr
                      })

        if parsed_args.prefixlen:
            body['subnet'].update({'prefixlen': parsed_args.prefixlen})
        if parsed_args.subnetpool:
            if parsed_args.subnetpool == 'None':
                _subnetpool_id = None
            else:
                _subnetpool_id = neutronV20.find_resourceid_by_name_or_id(
                    self.get_client(), 'subnetpool', parsed_args.subnetpool)
            body['subnet'].update({'subnetpool_id': _subnetpool_id})

        updatable_args2body(parsed_args, body)
        if parsed_args.tenant_id:
            body['subnet'].update({'tenant_id': parsed_args.tenant_id})

        return body
Beispiel #53
0
    def args2body(self, parsed_args):
        if parsed_args.ip_version == 4 and parsed_args.cidr.endswith('/32'):
            self.log.warning(
                _("An IPv4 subnet with a /32 CIDR will have "
                  "only one usable IP address so the device "
                  "attached to it will not have any IP "
                  "connectivity."))
        _network_id = neutronV20.find_resourceid_by_name_or_id(
            self.get_client(), 'network', parsed_args.network_id)
        body = {
            'subnet': {
                'cidr': parsed_args.cidr,
                'network_id': _network_id,
                'ip_version': parsed_args.ip_version,
            },
        }

        updatable_args2body(parsed_args, body)
        if parsed_args.tenant_id:
            body['subnet'].update({'tenant_id': parsed_args.tenant_id})

        return body
Beispiel #54
0
    def add_known_arguments(self, parser):
        _add_updatable_args(parser)
        parser.add_argument(
            '--id',
            help=_('Id for this hosting device template.'))
        parser.add_argument(
            '--slot-capacity',
            help=_('Capacity (in slots) for hosting devices based on this '
                   'template.'))
        parser.add_argument(
            '--slot_capacity',
            help=argparse.SUPPRESS)
        parser.add_argument(
            '--desired-slots-free',
            help=_('Number of slots to keep available in hosting devices '
                   'based on this template.'))
        parser.add_argument(
            '--desired_slots_free',
            help=argparse.SUPPRESS)
        parser.add_argument(
            '--device-driver',
            help=_('Device driver module to use for hosting devices based on '
                   'this template.'))
        parser.add_argument(
            '--device_driver',
            help=argparse.SUPPRESS)
        parser.add_argument(
            '--plugging-driver',
            help=_('Plugging driver module to use for hosting devices based '
                   'on this template.'))
        parser.add_argument(
            '--plugging_driver',
            help=argparse.SUPPRESS)

        parser.add_argument(
            'name', metavar='NAME',
            help=_('Name of this hosting device template.'))
        parser.add_argument(
            'host_category', metavar='HOST_CATEGORY',
            help=_('Host category for this hosting device template. One of '
                   'VM, Hardware, or, Network_Node.'))
Beispiel #55
0
def _reachabilitytest_updatable_args(parser):
    parser.add_argument('name', help=_('Name of this reachability test.'))
    parser.add_argument('src_tenant_name',
                        metavar='src-tenant-name',
                        help=_('Tenant name of the src-ip.'))
    parser.add_argument('src_segment_name',
                        metavar='src-segment-name',
                        help=_('Network name of the src-ip.'))
    parser.add_argument('src_ip',
                        metavar='src-ip',
                        help=_('Source IP of the reachability test.'))
    parser.add_argument('dst_ip',
                        metavar='dst-ip',
                        help=_('Destination IP of the reachability test.'))
    parser.add_argument('expected_result',
                        metavar='expected-result',
                        help=_('Expected result of the test.'))
Beispiel #56
0
    def add_known_arguments(self, parser):
        parser.add_argument(
            '--policy', metavar='POLICY',
            help=_('Optimizer policy name or ID.'))
        #OaaS
        parser.add_argument(
            '--solowan',
            dest='solowan',
            metavar="service True| False",
            help=_("Set the state of solowan's service"))
        parser.add_argument(
            '--local_id',
            dest='local_id',
            metavar="local_id IP",
            help=_("Set the local_id IP of Optimizer"))
        parser.add_argument(
            '--action',
            dest='action',
            metavar="action 'optimization (compression|deduplication|combined)'",
            help=_("Set the action"))
        parser.add_argument(
            '--pkt',
            dest='num_pkt_cache_size',
            metavar="pkt integer'",
            help=_("Set the hash table max number of packets"))



        router_sg = parser.add_mutually_exclusive_group()
        router_sg.add_argument(
            '--router',
            dest='routers',
            metavar='ROUTER',
            action='append',
            help=_('Optimizer associated router names or IDs (requires OaaS '
                   'router insertion extension, this option can be repeated)'))
        router_sg.add_argument(
            '--no-routers',
            action='store_true',
            help=_('Associate no routers with the optimizer (requires OaaS '
                   'router insertion extension)'))
Beispiel #57
0
def find_resourceid_by_id(client, resource, resource_id, cmd_resource=None,
                          parent_id=None):
    if not cmd_resource:
        cmd_resource = resource
    cmd_resource_plural = _get_resource_plural(cmd_resource, client)
    resource_plural = _get_resource_plural(resource, client)
    obj_lister = getattr(client, "list_%s" % cmd_resource_plural)
    # perform search by id only if we are passing a valid UUID
    match = re.match(UUID_PATTERN, resource_id)
    collection = resource_plural
    if match:
        if parent_id:
            data = obj_lister(parent_id, id=resource_id, fields='id')
        else:
            data = obj_lister(id=resource_id, fields='id')
        if data and data[collection]:
            return data[collection][0]['id']
    not_found_message = (_("Unable to find %(resource)s with id "
                           "'%(id)s'") %
                         {'resource': resource, 'id': resource_id})
    # 404 is used to simulate server side behavior
    raise exceptions.NeutronClientException(
        message=not_found_message, status_code=404)
 def add_known_arguments(self, parser):
     add_updatable_arguments(parser)
     parser.add_argument('--ip-version',
                         type=int,
                         default=4,
                         choices=[4, 6],
                         help=_(
                             'IP version to use, default is 4. '
                             'Note that when subnetpool is specified, '
                             'IP version is determined from the subnetpool '
                             'and this option is ignored.'))
     parser.add_argument('--ip_version',
                         type=int,
                         choices=[4, 6],
                         help=argparse.SUPPRESS)
     parser.add_argument(
         'network_id',
         metavar='NETWORK',
         help=_('Network ID or name this subnet belongs to.'))
     parser.add_argument('cidr',
                         nargs='?',
                         metavar='CIDR',
                         help=_('CIDR of subnet to create.'))
     parser.add_argument(
         '--ipv6-ra-mode',
         choices=['dhcpv6-stateful', 'dhcpv6-stateless', 'slaac'],
         help=_('IPv6 RA (Router Advertisement) mode.'))
     parser.add_argument(
         '--ipv6-address-mode',
         choices=['dhcpv6-stateful', 'dhcpv6-stateless', 'slaac'],
         help=_('IPv6 address mode.'))
     parser.add_argument(
         '--subnetpool',
         metavar='SUBNETPOOL',
         help=_('ID or name of subnetpool from which this subnet '
                'will obtain a CIDR.'))
     parser.add_argument(
         '--prefixlen',
         metavar='PREFIX_LENGTH',
         help=_('Prefix length for subnet allocation from subnetpool.'))
    def run(self, parsed_args):
        self.log.debug('run(%s)' % parsed_args)
        neutron_client = self.get_client()

        if '=' in parsed_args.interface:
            resource, value = parsed_args.interface.split('=', 1)
            if resource not in ['subnet', 'port']:
                exceptions.CommandError(_('You must specify either subnet or '
                                        'port for INTERFACE parameter.'))
        else:
            resource = 'subnet'
            value = parsed_args.interface

        _router_id = neutronV20.find_resourceid_by_name_or_id(
            neutron_client, self.resource, parsed_args.router)

        _interface_id = neutronV20.find_resourceid_by_name_or_id(
            neutron_client, resource, value)
        body = {'%s_id' % resource: _interface_id}

        portinfo = self.call_api(neutron_client, _router_id, body)
        print(self.success_message(parsed_args.router, portinfo),
              file=self.app.stdout)
    def args2body_extradhcpopt(self, parsed_args, port):
        ops = []
        if parsed_args.extra_dhcp_opts:
            # the extra_dhcp_opt params (opt_name & opt_value)
            # must come in pairs, if there is a parm error
            # both must be thrown out.
            opt_ele = {}
            edo_err_msg = _("Invalid --extra-dhcp-opt option, can only be: "
                            "opt_name=<dhcp_option_name>,opt_value=<value>,"
                            "ip_version={4,6}. "
                            "You can repeat this option.")
            for opt in parsed_args.extra_dhcp_opts:
                opt_ele.update(utils.str2dict(opt))
                if ('opt_name' in opt_ele and
                        ('opt_value' in opt_ele or 'ip_version' in opt_ele)):
                    if opt_ele.get('opt_value') == 'null':
                        opt_ele['opt_value'] = None
                    ops.append(opt_ele)
                    opt_ele = {}
                else:
                    raise exceptions.CommandError(edo_err_msg)

        if ops:
            port['extra_dhcp_opts'] = ops