diff options
| author | Jenkins <jenkins@review.openstack.org> | 2016-03-04 23:39:22 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2016-03-04 23:39:22 +0000 |
| commit | a61c5cc8a4884fd97d0938b3559f6a630cd4ad50 (patch) | |
| tree | b40156e012f2eee95f76303c277ff5d7955ba157 /openstackclient/network | |
| parent | 5c1633f5050a21ad1866eb3056df74595780e5ae (diff) | |
| parent | d1d4a40808741c416ecc51294fab78138f9184fa (diff) | |
| download | python-openstackclient-a61c5cc8a4884fd97d0938b3559f6a630cd4ad50.tar.gz | |
Merge "Add 'port create' command"
Diffstat (limited to 'openstackclient/network')
| -rw-r--r-- | openstackclient/network/v2/port.py | 171 |
1 files changed, 168 insertions, 3 deletions
diff --git a/openstackclient/network/v2/port.py b/openstackclient/network/v2/port.py index 19b3701d..f9d0fc95 100644 --- a/openstackclient/network/v2/port.py +++ b/openstackclient/network/v2/port.py @@ -14,13 +14,14 @@ """Port action implementations""" from openstackclient.common import command +from openstackclient.common import parseractions from openstackclient.common import utils +from openstackclient.identity import common as identity_common def _format_admin_state(state): return 'UP' if state else 'DOWN' - _formatters = { 'admin_state_up': _format_admin_state, 'allowed_address_pairs': utils.format_list_of_dicts, @@ -49,7 +50,171 @@ def _get_columns(item): if binding_column in columns: columns.remove(binding_column) columns.append(binding_column.replace('binding:', 'binding_', 1)) - return sorted(columns) + return tuple(sorted(columns)) + + +def _get_attrs(client_manager, parsed_args): + attrs = {} + + if parsed_args.name is not None: + attrs['name'] = str(parsed_args.name) + if parsed_args.fixed_ip is not None: + attrs['fixed_ips'] = parsed_args.fixed_ip + if parsed_args.device_id is not None: + attrs['device_id'] = parsed_args.device_id + if parsed_args.device_owner is not None: + attrs['device_owner'] = parsed_args.device_owner + if parsed_args.admin_state is not None: + attrs['admin_state_up'] = parsed_args.admin_state + if parsed_args.binding_profile is not None: + attrs['binding:profile'] = parsed_args.binding_profile + if parsed_args.vnic_type is not None: + attrs['binding:vnic_type'] = parsed_args.vnic_type + if parsed_args.host_id is not None: + attrs['binding:host_id'] = parsed_args.host_id + + # The remaining options do not support 'port set' command, so they require + # additional check + if 'mac_address' in parsed_args and parsed_args.mac_address is not None: + attrs['mac_address'] = parsed_args.mac_address + if 'network' in parsed_args and parsed_args.network is not None: + attrs['network_id'] = parsed_args.network + if 'project' in parsed_args and parsed_args.project is not None: + # TODO(singhj): since 'project' logic is common among + # router, network, port etc., maybe move it to a common file. + identity_client = client_manager.identity + project_id = identity_common.find_project( + identity_client, + parsed_args.project, + parsed_args.project_domain, + ).id + attrs['tenant_id'] = project_id + + return attrs + + +def _prepare_fixed_ips(client_manager, parsed_args): + """Fix and properly format fixed_ip option. + + Appropriately convert any subnet names to their respective ids. + Convert fixed_ips in parsed args to be in valid dictionary format: + {'subnet': 'foo'}. + """ + client = client_manager.network + ips = [] + + if parsed_args.fixed_ip: + for ip_spec in parsed_args.fixed_ip: + if 'subnet' in ip_spec: + subnet_name_id = ip_spec['subnet'] + if subnet_name_id: + _subnet = client.find_subnet(subnet_name_id, + ignore_missing=False) + ip_spec['subnet_id'] = _subnet.id + del ip_spec['subnet'] + + if 'ip-address' in ip_spec: + ip_spec['ip_address'] = ip_spec['ip-address'] + del ip_spec['ip-address'] + + ips.append(ip_spec) + + if ips: + parsed_args.fixed_ip = ips + + +def _add_updatable_args(parser): + parser.add_argument( + '--fixed-ip', + metavar='subnet=<subnet>,ip-address=<ip-address>', + action=parseractions.MultiKeyValueAction, + optional_keys=['subnet', 'ip-address'], + help='Desired IP and/or subnet (name or ID) for this port: ' + 'subnet=<subnet>,ip-address=<ip-address> ' + '(this option can be repeated)') + parser.add_argument( + '--device-id', + metavar='<device-id>', + help='Device ID of this port') + parser.add_argument( + '--device-owner', + metavar='<device-owner>', + help='Device owner of this port') + parser.add_argument( + '--vnic-type', + metavar='<vnic-type>', + choices=['direct', 'direct-physical', 'macvtap', + 'normal', 'baremetal'], + help='VNIC type for this port (direct | direct-physical |' + ' macvtap | normal(default) | baremetal)') + parser.add_argument( + '--binding-profile', + metavar='<binding-profile>', + action=parseractions.KeyValueAction, + help='Custom data to be passed as binding:profile: <key>=<value> ' + '(this option can be repeated)') + parser.add_argument( + '--host-id', + metavar='<host-id>', + help='The ID of the host where the port is allocated' + ) + + +class CreatePort(command.ShowOne): + """Create a new port""" + + def get_parser(self, prog_name): + parser = super(CreatePort, self).get_parser(prog_name) + + parser.add_argument( + '--network', + metavar='<network>', + required=True, + help='Network this port belongs to (name or ID)') + _add_updatable_args(parser) + admin_group = parser.add_mutually_exclusive_group() + admin_group.add_argument( + '--enable', + dest='admin_state', + action='store_true', + default=True, + help='Enable port (default)', + ) + admin_group.add_argument( + '--disable', + dest='admin_state', + action='store_false', + help='Disable port', + ) + parser.add_argument( + '--mac-address', + metavar='<mac-address>', + help='MAC address of this port') + parser.add_argument( + '--project', + metavar='<project>', + help="Owner's project (name or ID)") + parser.add_argument( + 'name', + metavar='<name>', + help='Name of this port') + identity_common.add_project_domain_option_to_parser(parser) + # TODO(singhj): Add support for extended options: + # qos,security groups,dhcp, address pairs + return parser + + def take_action(self, parsed_args): + client = self.app.client_manager.network + _network = client.find_network(parsed_args.network, + ignore_missing=False) + parsed_args.network = _network.id + _prepare_fixed_ips(self.app.client_manager, parsed_args) + attrs = _get_attrs(self.app.client_manager, parsed_args) + obj = client.create_port(**attrs) + columns = _get_columns(obj) + data = utils.get_item_properties(obj, columns, formatters=_formatters) + + return columns, data class DeletePort(command.Command): @@ -90,4 +255,4 @@ class ShowPort(command.ShowOne): obj = client.find_port(parsed_args.port, ignore_missing=False) columns = _get_columns(obj) data = utils.get_item_properties(obj, columns, formatters=_formatters) - return (tuple(columns), data) + return columns, data |
