def take_action(self, parsed_args):
        network_client = self.app.client_manager.network
        try:
            # Verify that the extension exists.
            network_client.find_extension('network-segment-range',
                                          ignore_missing=False)
        except Exception as e:
            msg = (_('Network segment range create not supported by '
                     'Network API: %(e)s') % {'e': e})
            raise exceptions.CommandError(msg)

        identity_client = self.app.client_manager.identity

        if not parsed_args.private and parsed_args.project:
            msg = _("--project is only allowed with --private")
            raise exceptions.CommandError(msg)

        if (parsed_args.network_type.lower() != 'vlan' and
                parsed_args.physical_network):
            msg = _("--physical-network is only allowed with --network-type "
                    "vlan")
            raise exceptions.CommandError(msg)

        attrs = {}
        if parsed_args.shared or parsed_args.private:
            attrs['shared'] = parsed_args.shared
        else:
            # default to be ``shared`` if not specified
            attrs['shared'] = True
        attrs['network_type'] = parsed_args.network_type
        attrs['minimum'] = parsed_args.minimum
        attrs['maximum'] = parsed_args.maximum
        if parsed_args.name:
            attrs['name'] = parsed_args.name

        if parsed_args.project:
            project_id = identity_common.find_project(
                identity_client,
                parsed_args.project,
                parsed_args.project_domain,
            ).id
            if project_id:
                attrs['project_id'] = project_id
            else:
                msg = (_("Failed to create the network segment range for "
                         "project %(project_id)s") % parsed_args.project_id)
                raise exceptions.CommandError(msg)
        elif not attrs['shared']:
            # default to the current project if no project specified and shared
            # is not specified.
            # Get the project id from the current auth.
            attrs['project_id'] = self.app.client_manager.auth_ref.project_id

        if parsed_args.physical_network:
            attrs['physical_network'] = parsed_args.physical_network
        obj = network_client.create_network_segment_range(**attrs)
        display_columns, columns = _get_columns(obj)
        data = utils.get_item_properties(obj, columns)
        data = _update_additional_fields_from_props(columns, props=data)
        return (display_columns, data)
 def get_parser(self, prog_name):
     parser = super(ListUser, self).get_parser(prog_name)
     parser.add_argument(
         '--domain',
         metavar='<domain>',
         help=_('Filter users by <domain> (name or ID)'),
     )
     project_or_group = parser.add_mutually_exclusive_group()
     project_or_group.add_argument(
         '--group',
         metavar='<group>',
         help=_('Filter users by <group> membership (name or ID)'),
     )
     project_or_group.add_argument(
         '--project',
         metavar='<project>',
         help=_('Filter users by <project> (name or ID)'),
     )
     parser.add_argument(
         '--long',
         action='store_true',
         default=False,
         help=_('List additional fields in output'),
     )
     return parser
 def get_parser(self, prog_name):
     parser = super(CreateAccessToken, self).get_parser(prog_name)
     parser.add_argument(
         '--consumer-key',
         metavar='<consumer-key>',
         help=_('Consumer key (required)'),
         required=True
     )
     parser.add_argument(
         '--consumer-secret',
         metavar='<consumer-secret>',
         help=_('Consumer secret (required)'),
         required=True
     )
     parser.add_argument(
         '--request-key',
         metavar='<request-key>',
         help=_('Request token to exchange for access token (required)'),
         required=True
     )
     parser.add_argument(
         '--request-secret',
         metavar='<request-secret>',
         help=_('Secret associated with <request-key> (required)'),
         required=True
     )
     parser.add_argument(
         '--verifier',
         metavar='<verifier>',
         help=_('Verifier associated with <request-key> (required)'),
         required=True
     )
     return parser
    def take_action(self, parsed_args):
        network_client = self.app.client_manager.network
        try:
            # Verify that the extension exists.
            network_client.find_extension('network-segment-range',
                                          ignore_missing=False)
        except Exception as e:
            msg = (_('Network segment range delete not supported by '
                     'Network API: %(e)s') % {'e': e})
            raise exceptions.CommandError(msg)

        result = 0
        for network_segment_range in parsed_args.network_segment_range:
            try:
                obj = network_client.find_network_segment_range(
                    network_segment_range, ignore_missing=False)
                network_client.delete_network_segment_range(obj)
            except Exception as e:
                result += 1
                LOG.error(_("Failed to delete network segment range with "
                            "ID '%(network_segment_range)s': %(e)s"),
                          {'network_segment_range': network_segment_range,
                           'e': e})

        if result > 0:
            total = len(parsed_args.network_segment_range)
            msg = (_("%(result)s of %(total)s network segment ranges failed "
                     "to delete.") % {'result': result, 'total': total})
            raise exceptions.CommandError(msg)
 def get_parser(self, prog_name):
     parser = super(UpdateOvercloud, self).get_parser(prog_name)
     parser.add_argument('stack', nargs='?',
                         help=_('Name or ID of heat stack to scale '
                                '(default=Env: OVERCLOUD_STACK_NAME)'),
                         default=utils.env('OVERCLOUD_STACK_NAME'))
     parser.add_argument(
         '--templates', nargs='?', const=constants.TRIPLEO_HEAT_TEMPLATES,
         help=_("The directory containing the Heat templates to deploy"),
     )
     parser.add_argument('-i', '--interactive', dest='interactive',
                         action='store_true')
     parser.add_argument('-a', '--abort', dest='abort_update',
                         action='store_true')
     parser.add_argument(
         '-e', '--environment-file', metavar='<HEAT ENVIRONMENT FILE>',
         action='append', dest='environment_files',
         help=_('Environment files to be passed to the heat stack-create '
                'or heat stack-update command. (Can be specified more than '
                'once.)')
     )
     parser.add_argument(
         '--answers-file',
         help=_('Path to a YAML file with arguments and parameters.')
     )
     return parser
    def take_action(self, parsed_args):
        volume_client = self.app.client_manager.volume
        volume = utils.find_resource(volume_client.volumes, parsed_args.volume)

        if parsed_args.size:
            if volume.status != 'available':
                LOG.error(_("Volume is in %s state, it must be available "
                            "before size can be extended"), volume.status)
                return
            if parsed_args.size <= volume.size:
                LOG.error(_("New size must be greater than %s GB"),
                          volume.size)
                return
            volume_client.volumes.extend(volume.id, parsed_args.size)

        if parsed_args.property:
            volume_client.volumes.set_metadata(volume.id, parsed_args.property)
        if parsed_args.image_property:
            volume_client.volumes.set_image_metadata(
                volume.id, parsed_args.image_property)

        kwargs = {}
        if parsed_args.name:
            kwargs['display_name'] = parsed_args.name
        if parsed_args.description:
            kwargs['display_description'] = parsed_args.description
        if kwargs:
            volume_client.volumes.update(volume.id, **kwargs)
 def get_parser(self, prog_name):
     parser = super(CreateRequestToken, self).get_parser(prog_name)
     parser.add_argument(
         '--consumer-key',
         metavar='<consumer-key>',
         help=_('Consumer key (required)'),
         required=True
     )
     parser.add_argument(
         '--consumer-secret',
         metavar='<consumer-secret>',
         help=_('Consumer secret (required)'),
         required=True
     )
     parser.add_argument(
         '--project',
         metavar='<project>',
         help=_('Project that consumer wants to access (name or ID)'
                ' (required)'),
         required=True
     )
     parser.add_argument(
         '--domain',
         metavar='<domain>',
         help=_('Domain owning <project> (name or ID)'),
     )
     return parser
 def get_parser(self, prog_name):
     parser = super(SetNetworkQosPolicy, self).get_parser(prog_name)
     parser.add_argument(
         'policy',
         metavar="<qos-policy>",
         help=_("QoS policy to modify (name or ID)")
     )
     parser.add_argument(
         '--name',
         metavar="<name>",
         help=_('Set QoS policy name')
     )
     parser.add_argument(
         '--description',
         metavar='<description>',
         help=_("Description of the QoS policy")
     )
     enable_group = parser.add_mutually_exclusive_group()
     enable_group.add_argument(
         '--share',
         action='store_true',
         help=_('Make the QoS policy accessible by other projects'),
     )
     enable_group.add_argument(
         '--no-share',
         action='store_true',
         help=_('Make the QoS policy not accessible by other projects'),
     )
     return parser
 def get_parser(self, prog_name):
     parser = super(CreateNetworkQosPolicy, self).get_parser(prog_name)
     parser.add_argument(
         'name',
         metavar='<name>',
         help=_("Name of QoS policy to create")
     )
     parser.add_argument(
         '--description',
         metavar='<description>',
         help=_("Description of the QoS policy")
     )
     share_group = parser.add_mutually_exclusive_group()
     share_group.add_argument(
         '--share',
         action='store_true',
         default=None,
         help=_("Make the QoS policy accessible by other projects")
     )
     share_group.add_argument(
         '--no-share',
         action='store_true',
         help=_("Make the QoS policy not accessible by other projects "
                "(default)")
     )
     parser.add_argument(
         '--project',
         metavar='<project>',
         help=_("Owner's project (name or ID)")
     )
     identity_common.add_project_domain_option_to_parser(parser)
     return parser
Exemple #10
0
 def get_parser(self, prog_name):
     parser = super(SetDomain, self).get_parser(prog_name)
     parser.add_argument(
         'domain',
         metavar='<domain>',
         help=_('Domain to modify (name or ID)'),
     )
     parser.add_argument(
         '--name',
         metavar='<name>',
         help=_('New domain name'),
     )
     parser.add_argument(
         '--description',
         metavar='<description>',
         help=_('New domain description'),
     )
     enable_group = parser.add_mutually_exclusive_group()
     enable_group.add_argument(
         '--enable',
         action='store_true',
         help=_('Enable domain'),
     )
     enable_group.add_argument(
         '--disable',
         action='store_true',
         help=_('Disable domain'),
     )
     return parser
Exemple #11
0
 def get_parser(self, prog_name):
     parser = super(CreateDomain, self).get_parser(prog_name)
     parser.add_argument(
         'name',
         metavar='<domain-name>',
         help=_('New domain name'),
     )
     parser.add_argument(
         '--description',
         metavar='<description>',
         help=_('New domain description'),
     )
     enable_group = parser.add_mutually_exclusive_group()
     enable_group.add_argument(
         '--enable',
         action='store_true',
         help=_('Enable domain (default)'),
     )
     enable_group.add_argument(
         '--disable',
         action='store_true',
         help=_('Disable domain'),
     )
     parser.add_argument(
         '--or-show',
         action='store_true',
         help=_('Return existing domain'),
     )
     return parser
 def get_parser(self, prog_name):
     parser = super(CreateService, self).get_parser(prog_name)
     parser.add_argument(
         'type',
         metavar='<type>',
         help=_('New service type (compute, image, identity, volume, etc)'),
     )
     parser.add_argument(
         '--name',
         metavar='<name>',
         help=_('New service name'),
     )
     parser.add_argument(
         '--description',
         metavar='<description>',
         help=_('New service description'),
     )
     enable_group = parser.add_mutually_exclusive_group()
     enable_group.add_argument(
         '--enable',
         action='store_true',
         help=_('Enable service (default)'),
     )
     enable_group.add_argument(
         '--disable',
         action='store_true',
         help=_('Disable service'),
     )
     return parser
 def get_parser(self, prog_name):
     parser = super(ListVolumeBackup, self).get_parser(prog_name)
     parser.add_argument(
         '--long',
         action='store_true',
         default=False,
         help=_('List additional fields in output'),
     )
     parser.add_argument(
         "--name",
         metavar="<name>",
         help=_("Filters results by the backup name")
     )
     parser.add_argument(
         "--status",
         metavar="<status>",
         choices=['creating', 'available', 'deleting',
                  'error', 'restoring', 'error_restoring'],
         help=_("Filters results by the backup status "
                "('creating', 'available', 'deleting', "
                "'error', 'restoring' or 'error_restoring')")
     )
     parser.add_argument(
         "--volume",
         metavar="<volume>",
         help=_("Filters results by the volume which they "
                "backup (name or ID)")
     )
     parser.add_argument(
         '--all-projects',
         action='store_true',
         default=False,
         help=_('Include all projects (admin only)'),
     )
     return parser
 def get_parser(self, prog_name):
     parser = super(UpgradeOvercloud, self).get_parser(prog_name)
     parser.add_argument(
         'stage',
         metavar="<prepare|start|finish>",
         choices=['prepare', 'start', 'finish'],
         help=_('Stage of upgrade to perform.')
     )
     parser.add_argument(
         '--stack',
         dest='stack',
         help=_('Name or ID of heat stack to upgrade '
                '(default=Env: OVERCLOUD_STACK_NAME)'),
         default=utils.env('OVERCLOUD_STACK_NAME'))
     parser.add_argument(
         '-e', '--environment-file', metavar='<HEAT ENVIRONMENT FILE>',
         action='append', dest='environment_files',
         help=_('Environment files to be passed to the heat stack-update '
                'command. (Can be specified more than once.)')
     )
     template_group = parser.add_mutually_exclusive_group(required=True)
     template_group.add_argument(
         '--templates', nargs='?', const=constants.TRIPLEO_HEAT_TEMPLATES,
         help=_("The directory containing the Heat templates used for "
                "the upgraded deployment. Cannot be specified with "
                "--answers-file."),
     )
     template_group.add_argument(
         '--answers-file',
         help=_('Path to a YAML file with arguments and parameters. Cannot '
                'be used with --templates.')
     )
     return parser
    def take_action(self, parsed_args):
        ret = 0
        resources = getattr(parsed_args, self.resource, [])

        for r in resources:
            self.r = r
            try:
                if self.app.client_manager.is_network_endpoint_enabled():
                    self.take_action_network(self.app.client_manager.network,
                                             parsed_args)
                else:
                    self.take_action_compute(self.app.client_manager.compute,
                                             parsed_args)
            except Exception as e:
                msg = _("Failed to delete %(resource)s with name or ID "
                        "'%(name_or_id)s': %(e)s") % {
                            "resource": self.resource,
                            "name_or_id": r,
                            "e": e,
                }
                LOG.error(msg)
                ret += 1

        if ret:
            total = len(resources)
            msg = _("%(num)s of %(total)s %(resource)ss failed to delete.") % {
                "num": ret,
                "total": total,
                "resource": self.resource,
            }
            raise exceptions.CommandError(msg)
    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        domain = None
        if parsed_args.domain:
            domain = common.find_domain(identity_client, parsed_args.domain)
        errors = 0
        for user in parsed_args.users:
            try:
                if domain is not None:
                    user_obj = utils.find_resource(identity_client.users,
                                                   user,
                                                   domain_id=domain.id)
                else:
                    user_obj = utils.find_resource(identity_client.users,
                                                   user)
                identity_client.users.delete(user_obj.id)
            except Exception as e:
                errors += 1
                LOG.error(_("Failed to delete user with "
                          "name or ID '%(user)s': %(e)s"),
                          {'user': user, 'e': e})

        if errors > 0:
            total = len(parsed_args.users)
            msg = (_("%(errors)s of %(total)s users failed "
                   "to delete.") % {'errors': errors, 'total': total})
            raise exceptions.CommandError(msg)
Exemple #17
0
def add_deployment_plan_arguments(parser):
    """Add deployment plan arguments (flavors and scales) to a parser"""
    parser.add_argument('--control-scale', type=int,
                        help=_('New number of control nodes.'))
    parser.add_argument('--compute-scale', type=int,
                        help=_('New number of compute nodes.'))
    parser.add_argument('--ceph-storage-scale', type=int,
                        help=_('New number of ceph storage nodes.'))
    parser.add_argument('--block-storage-scale', type=int,
                        help=_('New number of cinder storage nodes.'))
    parser.add_argument('--swift-storage-scale', type=int,
                        help=_('New number of swift storage nodes.'))
    parser.add_argument('--control-flavor',
                        help=_("Nova flavor to use for control nodes."))
    parser.add_argument('--compute-flavor',
                        help=_("Nova flavor to use for compute nodes."))
    parser.add_argument('--ceph-storage-flavor',
                        help=_("Nova flavor to use for ceph storage "
                               "nodes."))
    parser.add_argument('--block-storage-flavor',
                        help=_("Nova flavor to use for cinder storage "
                               "nodes."))
    parser.add_argument('--swift-storage-flavor',
                        help=_("Nova flavor to use for swift storage "
                               "nodes."))
 def get_parser(self, prog_name):
     parser = super(ListPort, self).get_parser(prog_name)
     parser.add_argument(
         '--device-owner',
         metavar='<device-owner>',
         help=_("List only ports with the specified device owner. "
                "This is the entity that uses the port (for example, "
                "network:dhcp).")
     )
     parser.add_argument(
         '--network',
         metavar='<network>',
         help=_("List only ports connected to this network (name or ID)"))
     device_group = parser.add_mutually_exclusive_group()
     device_group.add_argument(
         '--router',
         metavar='<router>',
         dest='router',
         help=_("List only ports attached to this router (name or ID)")
     )
     device_group.add_argument(
         '--server',
         metavar='<server>',
         help=_("List only ports attached to this server (name or ID)"),
     )
     parser.add_argument(
         '--long',
         action='store_true',
         default=False,
         help=_("List additional fields in output")
     )
     return parser
    def get_parser(self, prog_name):
        parser = super(UnsetPort, self).get_parser(prog_name)
        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) which should be "
                   "removed from this port: subnet=<subnet>,"
                   "ip-address=<ip-address> (repeat option to unset multiple "
                   "fixed IP addresses)"))

        parser.add_argument(
            '--binding-profile',
            metavar='<binding-profile-key>',
            action='append',
            help=_("Desired key which should be removed from binding:profile"
                   "(repeat option to unset multiple binding:profile data)"))
        parser.add_argument(
            '--security-group',
            metavar='<security-group>',
            action='append',
            dest='security_groups',
            help=_("Security group which should be removed this port (name "
                   "or ID) (repeat option to unset multiple security groups)")
        )

        parser.add_argument(
            'port',
            metavar="<port>",
            help=_("Port to modify (name or ID)")
        )
        return parser
 def get_parser(self, prog_name):
     parser = super(SetQuota, self).get_parser(prog_name)
     parser.add_argument(
         'project',
         metavar='<project/class>',
         help=_('Set quotas for this project or class (name/ID)'),
     )
     parser.add_argument(
         '--class',
         dest='quota_class',
         action='store_true',
         default=False,
         help=_('Set quotas for <class>'),
     )
     for k, v in self._build_options_list():
         parser.add_argument(
             '--%s' % v,
             metavar='<%s>' % v,
             dest=k,
             type=int,
             help=_('New value for the %s quota') % v,
         )
     parser.add_argument(
         '--volume-type',
         metavar='<volume-type>',
         help=_('Set quotas for a specific <volume-type>'),
     )
     return parser
 def get_parser(self, prog_name):
     parser = super(ListPort, self).get_parser(prog_name)
     parser.add_argument(
         '--device-owner',
         metavar='<device-owner>',
         help=_("List only ports with the specified device owner. "
                "This is the entity that uses the port (for example, "
                "network:dhcp).")
     )
     parser.add_argument(
         '--network',
         metavar='<network>',
         help=_("List only ports connected to this network (name or ID)"))
     device_group = parser.add_mutually_exclusive_group()
     device_group.add_argument(
         '--router',
         metavar='<router>',
         dest='router',
         help=_("List only ports attached to this router (name or ID)")
     )
     device_group.add_argument(
         '--server',
         metavar='<server>',
         help=_("List only ports attached to this server (name or ID)"),
     )
     device_group.add_argument(
         '--device-id',
         metavar='<device-id>',
         help=_("List only ports with the specified device ID")
     )
     parser.add_argument(
         '--mac-address',
         metavar='<mac-address>',
         help=_("List only ports with this MAC address")
     )
     parser.add_argument(
         '--long',
         action='store_true',
         default=False,
         help=_("List additional fields in output")
     )
     parser.add_argument(
         '--project',
         metavar='<project>',
         help=_("List ports according to their project (name or ID)")
     )
     identity_common.add_project_domain_option_to_parser(parser)
     parser.add_argument(
         '--fixed-ip',
         metavar=('subnet=<subnet>,ip-address=<ip-address>,'
                  'ip-substring=<ip-substring>'),
         action=parseractions.MultiKeyValueAction,
         optional_keys=['subnet', 'ip-address', 'ip-substring'],
         help=_("Desired IP and/or subnet for filtering ports "
                "(name or ID): subnet=<subnet>,ip-address=<ip-address>,"
                "ip-substring=<ip-substring> "
                "(repeat option to set multiple fixed IP addresses)"),
     )
     _tag.add_tag_filtering_option_to_parser(parser, _('ports'))
     return parser
    def take_action(self, parsed_args):
        volume_client = self.app.client_manager.volume
        identity_client = self.app.client_manager.identity

        volume_type = utils.find_resource(
            volume_client.volume_types,
            parsed_args.volume_type,
        )

        result = 0
        if parsed_args.property:
            try:
                volume_type.unset_keys(parsed_args.property)
            except Exception as e:
                LOG.error(_("Failed to unset volume type property: %s"), e)
                result += 1

        if parsed_args.project:
            project_info = None
            try:
                project_info = identity_common.find_project(
                    identity_client,
                    parsed_args.project,
                    parsed_args.project_domain)

                volume_client.volume_type_access.remove_project_access(
                    volume_type.id, project_info.id)
            except Exception as e:
                LOG.error(_("Failed to remove volume type access from "
                            "project: %s"), e)
                result += 1

        if result > 0:
            raise exceptions.CommandError(_("Command Failed: One or more of"
                                          " the operations failed"))
 def update_parser_compute(self, parser):
     parser.add_argument(
         '--dst-port',
         metavar='<port-range>',
         default=(0, 0),
         action=parseractions.RangeAction,
         help=_("Destination port, may be a single port or a starting and "
                "ending port range: 137:139. Required for IP protocols TCP "
                "and UDP. Ignored for ICMP IP protocols.")
     )
     # NOTE(rtheis): Support either protocol option name for now.
     # However, consider deprecating and then removing --proto in
     # a future release.
     protocol_group = parser.add_mutually_exclusive_group()
     protocol_group.add_argument(
         '--protocol',
         metavar='<protocol>',
         choices=['icmp', 'tcp', 'udp'],
         type=_convert_to_lowercase,
         help=_("IP protocol (icmp, tcp, udp; default: tcp)")
     )
     protocol_group.add_argument(
         '--proto',
         metavar='<proto>',
         choices=['icmp', 'tcp', 'udp'],
         type=_convert_to_lowercase,
         help=argparse.SUPPRESS
     )
     return parser
    def get_parser(self, prog_name):
        parser = super(SetAddressScope, self).get_parser(prog_name)
        parser.add_argument(
            'address_scope',
            metavar="<address-scope>",
            help=_("Address scope to modify (name or ID)")
        )
        parser.add_argument(
            '--name',
            metavar="<name>",
            help=_('Set address scope name')
        )
        share_group = parser.add_mutually_exclusive_group()
        share_group.add_argument(
            '--share',
            action='store_true',
            help=_('Share the address scope between projects')
        )
        share_group.add_argument(
            '--no-share',
            action='store_true',
            help=_('Do not share the address scope between projects')
        )

        return parser
    def get_parser(self, prog_name):
        parser = super(CreateAddressScope, self).get_parser(prog_name)
        parser.add_argument(
            'name',
            metavar="<name>",
            help=_("New address scope name")
        )
        parser.add_argument(
            '--ip-version',
            type=int,
            default=4,
            choices=[4, 6],
            help=_("IP version (default is 4)")
        )
        parser.add_argument(
            '--project',
            metavar="<project>",
            help=_("Owner's project (name or ID)")
        )
        identity_common.add_project_domain_option_to_parser(parser)

        share_group = parser.add_mutually_exclusive_group()
        share_group.add_argument(
            '--share',
            action='store_true',
            help=_('Share the address scope between projects')
        )
        share_group.add_argument(
            '--no-share',
            action='store_true',
            help=_('Do not share the address scope between projects (default)')
        )

        return parser
 def get_parser(self, prog_name):
     parser = super(SetNetworkSegmentRange, self).get_parser(prog_name)
     parser.add_argument(
         'network_segment_range',
         metavar='<network-segment-range>',
         help=_('Network segment range to modify (name or ID)'),
     )
     parser.add_argument(
         '--name',
         metavar='<name>',
         help=_('Set network segment name'),
     )
     parser.add_argument(
         '--minimum',
         metavar='<minimum-segmentation-id>',
         type=int,
         help=_('Set network segment range minimum segment identifier'),
     )
     parser.add_argument(
         '--maximum',
         metavar='<maximum-segmentation-id>',
         type=int,
         help=_('Set network segment range maximum segment identifier'),
     )
     return parser
    def take_action(self, parsed_args):
        network_client = self.app.client_manager.network
        try:
            # Verify that the extension exists.
            network_client.find_extension('network-segment-range',
                                          ignore_missing=False)
        except Exception as e:
            msg = (_('Network segment range set not supported by '
                     'Network API: %(e)s') % {'e': e})
            raise exceptions.CommandError(msg)

        if (parsed_args.minimum and not parsed_args.maximum) or \
                (parsed_args.maximum and not parsed_args.minimum):
            msg = _("--minimum and --maximum are both required")
            raise exceptions.CommandError(msg)

        obj = network_client.find_network_segment_range(
            parsed_args.network_segment_range, ignore_missing=False)
        attrs = {}
        if parsed_args.name:
            attrs['name'] = parsed_args.name
        if parsed_args.minimum:
            attrs['minimum'] = parsed_args.minimum
        if parsed_args.maximum:
            attrs['maximum'] = parsed_args.maximum
        network_client.update_network_segment_range(obj, **attrs)
    def get_parser(self, prog_name):
        parser = super(SetVolumeType, self).get_parser(prog_name)
        parser.add_argument(
            'volume_type',
            metavar='<volume-type>',
            help=_('Volume type to modify (name or ID)'),
        )
        parser.add_argument(
            '--name',
            metavar='<name>',
            help=_('Set volume type name'),
        )
        parser.add_argument(
            '--description',
            metavar='<name>',
            help=_('Set volume type description'),
        )
        parser.add_argument(
            '--property',
            metavar='<key=value>',
            action=parseractions.KeyValueAction,
            help=_('Set a property on this volume type '
                   '(repeat option to set multiple properties)'),
        )
        parser.add_argument(
            '--project',
            metavar='<project>',
            help=_('Set volume type access to project (name or ID) '
                   '(admin only)'),
        )
        identity_common.add_project_domain_option_to_parser(parser)

        return parser
 def get_parser(self, prog_name):
     parser = super(ListNetworkSegmentRange, self).get_parser(prog_name)
     parser.add_argument(
         '--long',
         action='store_true',
         help=_('List additional fields in output'),
     )
     used_group = parser.add_mutually_exclusive_group()
     used_group.add_argument(
         '--used',
         action='store_true',
         help=_('List network segment ranges that have segments in use'),
     )
     used_group.add_argument(
         '--unused',
         action='store_true',
         help=_('List network segment ranges that have segments '
                'not in use'),
     )
     available_group = parser.add_mutually_exclusive_group()
     available_group.add_argument(
         '--available',
         action='store_true',
         help=_('List network segment ranges that have available segments'),
     )
     available_group.add_argument(
         '--unavailable',
         action='store_true',
         help=_('List network segment ranges without available segments'),
     )
     return parser
 def get_parser(self, prog_name):
     parser = super(CreateVolumeType, self).get_parser(prog_name)
     parser.add_argument(
         "name",
         metavar="<name>",
         help=_("Volume type name"),
     )
     parser.add_argument(
         "--description",
         metavar="<description>",
         help=_("Volume type description"),
     )
     public_group = parser.add_mutually_exclusive_group()
     public_group.add_argument(
         "--public",
         dest="public",
         action="store_true",
         default=False,
         help=_("Volume type is accessible to the public"),
     )
     public_group.add_argument(
         "--private",
         dest="private",
         action="store_true",
         default=False,
         help=_("Volume type is not accessible to the public"),
     )
     parser.add_argument(
         '--property',
         metavar='<key=value>',
         action=parseractions.KeyValueAction,
         help=_('Set a property on this volume type '
                '(repeat option to set multiple properties)'),
     )
     return parser
Exemple #31
0
 def update_parser_network(self, parser):
     admin_group = parser.add_mutually_exclusive_group()
     admin_group.add_argument('--enable',
                              action='store_true',
                              default=True,
                              help=_("Enable network (default)"))
     admin_group.add_argument('--disable',
                              action='store_true',
                              help=_("Disable network"))
     parser.add_argument('--project',
                         metavar='<project>',
                         help=_("Owner's project (name or ID)"))
     parser.add_argument('--description',
                         metavar='<description>',
                         help=_("Set network description"))
     identity_common.add_project_domain_option_to_parser(parser)
     parser.add_argument(
         '--availability-zone-hint',
         action='append',
         dest='availability_zone_hints',
         metavar='<availability-zone>',
         help=_("Availability Zone in which to create this network "
                "(Network Availability Zone extension required, "
                "repeat option to set multiple availability zones)"))
     port_security_group = parser.add_mutually_exclusive_group()
     port_security_group.add_argument(
         '--enable-port-security',
         action='store_true',
         help=_("Enable port security by default for ports created on "
                "this network (default)"))
     port_security_group.add_argument(
         '--disable-port-security',
         action='store_true',
         help=_("Disable port security by default for ports created on "
                "this network"))
     external_router_grp = parser.add_mutually_exclusive_group()
     external_router_grp.add_argument(
         '--external',
         action='store_true',
         help=_("Set this network as an external network "
                "(external-net extension required)"))
     external_router_grp.add_argument(
         '--internal',
         action='store_true',
         help=_("Set this network as an internal network (default)"))
     default_router_grp = parser.add_mutually_exclusive_group()
     default_router_grp.add_argument(
         '--default',
         action='store_true',
         help=_("Specify if this network should be used as "
                "the default external network"))
     default_router_grp.add_argument(
         '--no-default',
         action='store_true',
         help=_("Do not use the network as the default external network "
                "(default)"))
     parser.add_argument(
         '--qos-policy',
         metavar='<qos-policy>',
         help=_("QoS policy to attach to this network (name or ID)"))
     _add_additional_network_options(parser)
     return parser
 def get_parser(self, prog_name):
     parser = super(SetVolume, self).get_parser(prog_name)
     parser.add_argument(
         'volume',
         metavar='<volume>',
         help=_('Volume to modify (name or ID)'),
     )
     parser.add_argument(
         '--name',
         metavar='<name>',
         help=_('New volume name'),
     )
     parser.add_argument(
         '--size',
         metavar='<size>',
         type=int,
         help=_('Extend volume size in GB'),
     )
     parser.add_argument(
         '--description',
         metavar='<description>',
         help=_('New volume description'),
     )
     parser.add_argument(
         '--property',
         metavar='<key=value>',
         action=parseractions.KeyValueAction,
         help=_('Set a property on this volume '
                '(repeat option to set multiple properties)'),
     )
     parser.add_argument(
         '--image-property',
         metavar='<key=value>',
         action=parseractions.KeyValueAction,
         help=_('Set an image property on this volume '
                '(repeat option to set multiple image properties)'),
     )
     parser.add_argument(
         "--state",
         metavar="<state>",
         choices=['available', 'error', 'creating', 'deleting',
                  'in-use', 'attaching', 'detaching', 'error_deleting',
                  'maintenance'],
         help=_('New volume state ("available", "error", "creating", '
                '"deleting", "in-use", "attaching", "detaching", '
                '"error_deleting" or "maintenance") (admin only) '
                '(This option simply changes the state of the volume '
                'in the database with no regard to actual status, '
                'exercise caution when using)'),
     )
     bootable_group = parser.add_mutually_exclusive_group()
     bootable_group.add_argument(
         "--bootable",
         action="store_true",
         help=_("Mark volume as bootable")
     )
     bootable_group.add_argument(
         "--non-bootable",
         action="store_true",
         help=_("Mark volume as non-bootable")
     )
     return parser
Exemple #33
0
 def update_parser_common(self, parser):
     parser.add_argument('network',
                         metavar="<network>",
                         help=_("Network to display (name or ID)"))
     return parser
Exemple #34
0
 def get_parser(self, prog_name):
     parser = super(SetNetwork, self).get_parser(prog_name)
     parser.add_argument('network',
                         metavar="<network>",
                         help=_("Network to modify (name or ID)"))
     parser.add_argument('--name',
                         metavar='<name>',
                         help=_("Set network name"))
     admin_group = parser.add_mutually_exclusive_group()
     admin_group.add_argument('--enable',
                              action='store_true',
                              default=None,
                              help=_("Enable network"))
     admin_group.add_argument('--disable',
                              action='store_true',
                              help=_("Disable network"))
     share_group = parser.add_mutually_exclusive_group()
     share_group.add_argument('--share',
                              action='store_true',
                              default=None,
                              help=_("Share the network between projects"))
     share_group.add_argument(
         '--no-share',
         action='store_true',
         help=_("Do not share the network between projects"))
     parser.add_argument('--description',
                         metavar="<description",
                         help=_("Set network description"))
     port_security_group = parser.add_mutually_exclusive_group()
     port_security_group.add_argument(
         '--enable-port-security',
         action='store_true',
         help=_("Enable port security by default for ports created on "
                "this network"))
     port_security_group.add_argument(
         '--disable-port-security',
         action='store_true',
         help=_("Disable port security by default for ports created on "
                "this network"))
     external_router_grp = parser.add_mutually_exclusive_group()
     external_router_grp.add_argument(
         '--external',
         action='store_true',
         help=_("Set this network as an external network "
                "(external-net extension required)"))
     external_router_grp.add_argument(
         '--internal',
         action='store_true',
         help=_("Set this network as an internal network"))
     default_router_grp = parser.add_mutually_exclusive_group()
     default_router_grp.add_argument(
         '--default',
         action='store_true',
         help=_("Set the network as the default external network"))
     default_router_grp.add_argument(
         '--no-default',
         action='store_true',
         help=_("Do not use the network as the default external network"))
     qos_group = parser.add_mutually_exclusive_group()
     qos_group.add_argument(
         '--qos-policy',
         metavar='<qos-policy>',
         help=_("QoS policy to attach to this network (name or ID)"))
     qos_group.add_argument(
         '--no-qos-policy',
         action='store_true',
         help=_("Remove the QoS policy attached to this network"))
     _add_additional_network_options(parser)
     return parser
Exemple #35
0
class SetNetwork(command.Command):
    _description = _("Set network properties")

    def get_parser(self, prog_name):
        parser = super(SetNetwork, self).get_parser(prog_name)
        parser.add_argument('network',
                            metavar="<network>",
                            help=_("Network to modify (name or ID)"))
        parser.add_argument('--name',
                            metavar='<name>',
                            help=_("Set network name"))
        admin_group = parser.add_mutually_exclusive_group()
        admin_group.add_argument('--enable',
                                 action='store_true',
                                 default=None,
                                 help=_("Enable network"))
        admin_group.add_argument('--disable',
                                 action='store_true',
                                 help=_("Disable network"))
        share_group = parser.add_mutually_exclusive_group()
        share_group.add_argument('--share',
                                 action='store_true',
                                 default=None,
                                 help=_("Share the network between projects"))
        share_group.add_argument(
            '--no-share',
            action='store_true',
            help=_("Do not share the network between projects"))
        parser.add_argument('--description',
                            metavar="<description",
                            help=_("Set network description"))
        port_security_group = parser.add_mutually_exclusive_group()
        port_security_group.add_argument(
            '--enable-port-security',
            action='store_true',
            help=_("Enable port security by default for ports created on "
                   "this network"))
        port_security_group.add_argument(
            '--disable-port-security',
            action='store_true',
            help=_("Disable port security by default for ports created on "
                   "this network"))
        external_router_grp = parser.add_mutually_exclusive_group()
        external_router_grp.add_argument(
            '--external',
            action='store_true',
            help=_("Set this network as an external network "
                   "(external-net extension required)"))
        external_router_grp.add_argument(
            '--internal',
            action='store_true',
            help=_("Set this network as an internal network"))
        default_router_grp = parser.add_mutually_exclusive_group()
        default_router_grp.add_argument(
            '--default',
            action='store_true',
            help=_("Set the network as the default external network"))
        default_router_grp.add_argument(
            '--no-default',
            action='store_true',
            help=_("Do not use the network as the default external network"))
        qos_group = parser.add_mutually_exclusive_group()
        qos_group.add_argument(
            '--qos-policy',
            metavar='<qos-policy>',
            help=_("QoS policy to attach to this network (name or ID)"))
        qos_group.add_argument(
            '--no-qos-policy',
            action='store_true',
            help=_("Remove the QoS policy attached to this network"))
        _add_additional_network_options(parser)
        return parser

    def take_action(self, parsed_args):
        client = self.app.client_manager.network
        obj = client.find_network(parsed_args.network, ignore_missing=False)

        attrs = _get_attrs_network(self.app.client_manager, parsed_args)
        client.update_network(obj, **attrs)
Exemple #36
0
 def update_parser_network(self, parser):
     router_ext_group = parser.add_mutually_exclusive_group()
     router_ext_group.add_argument('--external',
                                   action='store_true',
                                   help=_("List external networks"))
     router_ext_group.add_argument('--internal',
                                   action='store_true',
                                   help=_("List internal networks"))
     parser.add_argument('--long',
                         action='store_true',
                         help=_("List additional fields in output"))
     parser.add_argument('--name',
                         metavar='<name>',
                         help=_("List networks according to their name"))
     admin_state_group = parser.add_mutually_exclusive_group()
     admin_state_group.add_argument('--enable',
                                    action='store_true',
                                    help=_("List enabled networks"))
     admin_state_group.add_argument('--disable',
                                    action='store_true',
                                    help=_("List disabled networks"))
     parser.add_argument(
         '--project',
         metavar='<project>',
         help=_("List networks according to their project (name or ID)"))
     identity_common.add_project_domain_option_to_parser(parser)
     shared_group = parser.add_mutually_exclusive_group()
     shared_group.add_argument(
         '--share',
         action='store_true',
         help=_("List networks shared between projects"))
     shared_group.add_argument(
         '--no-share',
         action='store_true',
         help=_("List networks not shared between projects"))
     parser.add_argument('--status',
                         metavar='<status>',
                         choices=['ACTIVE', 'BUILD', 'DOWN', 'ERROR'],
                         help=_("List networks according to their status "
                                "('ACTIVE', 'BUILD', 'DOWN', 'ERROR')"))
     parser.add_argument(
         '--provider-network-type',
         metavar='<provider-network-type>',
         choices=['flat', 'geneve', 'gre', 'local', 'vlan', 'vxlan'],
         help=_("List networks according to their physical mechanisms. "
                "The supported options are: flat, geneve, gre, local, "
                "vlan, vxlan."))
     parser.add_argument(
         '--provider-physical-network',
         metavar='<provider-physical-network>',
         dest='physical_network',
         help=_("List networks according to name of the physical network"))
     parser.add_argument(
         '--provider-segment',
         metavar='<provider-segment>',
         dest='segmentation_id',
         help=_("List networks according to VLAN ID for VLAN networks "
                "or Tunnel ID for GENEVE/GRE/VXLAN networks"))
     parser.add_argument('--agent',
                         metavar='<agent-id>',
                         dest='agent_id',
                         help=_('List networks hosted by agent (ID only)'))
     return parser
Exemple #37
0
class ListNetwork(common.NetworkAndComputeLister):
    _description = _("List networks")

    def update_parser_network(self, parser):
        router_ext_group = parser.add_mutually_exclusive_group()
        router_ext_group.add_argument('--external',
                                      action='store_true',
                                      help=_("List external networks"))
        router_ext_group.add_argument('--internal',
                                      action='store_true',
                                      help=_("List internal networks"))
        parser.add_argument('--long',
                            action='store_true',
                            help=_("List additional fields in output"))
        parser.add_argument('--name',
                            metavar='<name>',
                            help=_("List networks according to their name"))
        admin_state_group = parser.add_mutually_exclusive_group()
        admin_state_group.add_argument('--enable',
                                       action='store_true',
                                       help=_("List enabled networks"))
        admin_state_group.add_argument('--disable',
                                       action='store_true',
                                       help=_("List disabled networks"))
        parser.add_argument(
            '--project',
            metavar='<project>',
            help=_("List networks according to their project (name or ID)"))
        identity_common.add_project_domain_option_to_parser(parser)
        shared_group = parser.add_mutually_exclusive_group()
        shared_group.add_argument(
            '--share',
            action='store_true',
            help=_("List networks shared between projects"))
        shared_group.add_argument(
            '--no-share',
            action='store_true',
            help=_("List networks not shared between projects"))
        parser.add_argument('--status',
                            metavar='<status>',
                            choices=['ACTIVE', 'BUILD', 'DOWN', 'ERROR'],
                            help=_("List networks according to their status "
                                   "('ACTIVE', 'BUILD', 'DOWN', 'ERROR')"))
        parser.add_argument(
            '--provider-network-type',
            metavar='<provider-network-type>',
            choices=['flat', 'geneve', 'gre', 'local', 'vlan', 'vxlan'],
            help=_("List networks according to their physical mechanisms. "
                   "The supported options are: flat, geneve, gre, local, "
                   "vlan, vxlan."))
        parser.add_argument(
            '--provider-physical-network',
            metavar='<provider-physical-network>',
            dest='physical_network',
            help=_("List networks according to name of the physical network"))
        parser.add_argument(
            '--provider-segment',
            metavar='<provider-segment>',
            dest='segmentation_id',
            help=_("List networks according to VLAN ID for VLAN networks "
                   "or Tunnel ID for GENEVE/GRE/VXLAN networks"))
        parser.add_argument('--agent',
                            metavar='<agent-id>',
                            dest='agent_id',
                            help=_('List networks hosted by agent (ID only)'))
        return parser

    def take_action_network(self, client, parsed_args):
        identity_client = self.app.client_manager.identity
        if parsed_args.long:
            columns = (
                'id',
                'name',
                'status',
                'project_id',
                'is_admin_state_up',
                'is_shared',
                'subnet_ids',
                'provider_network_type',
                'is_router_external',
                'availability_zones',
            )
            column_headers = (
                'ID',
                'Name',
                'Status',
                'Project',
                'State',
                'Shared',
                'Subnets',
                'Network Type',
                'Router Type',
                'Availability Zones',
            )
        elif parsed_args.agent_id:
            columns = ('id', 'name', 'subnet_ids')
            column_headers = (
                'ID',
                'Name',
                'Subnets',
            )
            client = self.app.client_manager.network
            dhcp_agent = client.get_agent(parsed_args.agent_id)
            data = client.dhcp_agent_hosting_networks(dhcp_agent)

            return (column_headers, (utils.get_item_properties(
                s,
                columns,
                formatters=_formatters,
            ) for s in data))
        else:
            columns = ('id', 'name', 'subnet_ids')
            column_headers = (
                'ID',
                'Name',
                'Subnets',
            )

        args = {}

        if parsed_args.external:
            args['router:external'] = True
            args['is_router_external'] = True
        elif parsed_args.internal:
            args['router:external'] = False
            args['is_router_external'] = False

        if parsed_args.name is not None:
            args['name'] = parsed_args.name

        if parsed_args.enable:
            args['admin_state_up'] = True
            args['is_admin_state_up'] = True
        elif parsed_args.disable:
            args['admin_state_up'] = False
            args['is_admin_state_up'] = False

        if parsed_args.project:
            project = identity_common.find_project(
                identity_client,
                parsed_args.project,
                parsed_args.project_domain,
            )
            args['tenant_id'] = project.id
            args['project_id'] = project.id

        if parsed_args.share:
            args['shared'] = True
            args['is_shared'] = True
        elif parsed_args.no_share:
            args['shared'] = False
            args['is_shared'] = False

        if parsed_args.status:
            args['status'] = parsed_args.status

        if parsed_args.provider_network_type:
            args['provider:network_type'] = parsed_args.provider_network_type
            args['provider_network_type'] = parsed_args.provider_network_type
        if parsed_args.physical_network:
            args['provider:physical_network'] = parsed_args.physical_network
            args['provider_physical_network'] = parsed_args.physical_network
        if parsed_args.segmentation_id:
            args['provider:segmentation_id'] = parsed_args.segmentation_id
            args['provider_segmentation_id'] = parsed_args.segmentation_id

        data = client.networks(**args)

        return (column_headers, (utils.get_item_properties(
            s,
            columns,
            formatters=_formatters,
        ) for s in data))

    def take_action_compute(self, client, parsed_args):
        columns = (
            'id',
            'label',
            'cidr',
        )
        column_headers = (
            'ID',
            'Name',
            'Subnet',
        )

        data = client.api.network_list()

        return (column_headers, (utils.get_dict_properties(
            s,
            columns,
            formatters=_formatters,
        ) for s in data))
 def get_parser(self, prog_name):
     parser = super(ShowNetworkAgent, self).get_parser(prog_name)
     parser.add_argument('network_agent',
                         metavar="<network-agent>",
                         help=(_("Network agent to display (ID only)")))
     return parser
Exemple #39
0
 def get_parser(self, prog_name):
     parser = super(ShowMeterRule, self).get_parser(prog_name)
     parser.add_argument('meter_rule_id',
                         metavar='<meter-rule-id>',
                         help=_('Meter rule (ID only)'))
     return parser
Exemple #40
0
class CreateNetwork(common.NetworkAndComputeShowOne):
    _description = _("Create new network")

    def update_parser_common(self, parser):
        parser.add_argument('name',
                            metavar='<name>',
                            help=_("New network name"))
        share_group = parser.add_mutually_exclusive_group()
        share_group.add_argument('--share',
                                 action='store_true',
                                 default=None,
                                 help=_("Share the network between projects"))
        share_group.add_argument(
            '--no-share',
            action='store_true',
            help=_("Do not share the network between projects"))
        return parser

    def update_parser_network(self, parser):
        admin_group = parser.add_mutually_exclusive_group()
        admin_group.add_argument('--enable',
                                 action='store_true',
                                 default=True,
                                 help=_("Enable network (default)"))
        admin_group.add_argument('--disable',
                                 action='store_true',
                                 help=_("Disable network"))
        parser.add_argument('--project',
                            metavar='<project>',
                            help=_("Owner's project (name or ID)"))
        parser.add_argument('--description',
                            metavar='<description>',
                            help=_("Set network description"))
        identity_common.add_project_domain_option_to_parser(parser)
        parser.add_argument(
            '--availability-zone-hint',
            action='append',
            dest='availability_zone_hints',
            metavar='<availability-zone>',
            help=_("Availability Zone in which to create this network "
                   "(Network Availability Zone extension required, "
                   "repeat option to set multiple availability zones)"))
        port_security_group = parser.add_mutually_exclusive_group()
        port_security_group.add_argument(
            '--enable-port-security',
            action='store_true',
            help=_("Enable port security by default for ports created on "
                   "this network (default)"))
        port_security_group.add_argument(
            '--disable-port-security',
            action='store_true',
            help=_("Disable port security by default for ports created on "
                   "this network"))
        external_router_grp = parser.add_mutually_exclusive_group()
        external_router_grp.add_argument(
            '--external',
            action='store_true',
            help=_("Set this network as an external network "
                   "(external-net extension required)"))
        external_router_grp.add_argument(
            '--internal',
            action='store_true',
            help=_("Set this network as an internal network (default)"))
        default_router_grp = parser.add_mutually_exclusive_group()
        default_router_grp.add_argument(
            '--default',
            action='store_true',
            help=_("Specify if this network should be used as "
                   "the default external network"))
        default_router_grp.add_argument(
            '--no-default',
            action='store_true',
            help=_("Do not use the network as the default external network "
                   "(default)"))
        parser.add_argument(
            '--qos-policy',
            metavar='<qos-policy>',
            help=_("QoS policy to attach to this network (name or ID)"))
        _add_additional_network_options(parser)
        return parser

    def update_parser_compute(self, parser):
        parser.add_argument(
            '--subnet',
            metavar='<subnet>',
            required=True,
            help=_("IPv4 subnet for fixed IPs (in CIDR notation)"))
        return parser

    def take_action_network(self, client, parsed_args):
        attrs = _get_attrs_network(self.app.client_manager, parsed_args)
        obj = client.create_network(**attrs)
        display_columns, columns = _get_columns_network(obj)
        data = utils.get_item_properties(obj, columns, formatters=_formatters)
        return (display_columns, data)

    def take_action_compute(self, client, parsed_args):
        attrs = _get_attrs_compute(self.app.client_manager, parsed_args)
        obj = client.api.network_create(**attrs)
        display_columns, columns = _get_columns_compute(obj)
        data = utils.get_dict_properties(obj, columns)
        return (display_columns, data)
Exemple #41
0
class ListContainer(command.Lister):
    _description = _("List containers")

    def get_parser(self, prog_name):
        parser = super(ListContainer, self).get_parser(prog_name)
        parser.add_argument(
            "--prefix",
            metavar="<prefix>",
            help=_("Filter list using <prefix>"),
        )
        parser.add_argument(
            "--marker",
            metavar="<marker>",
            help=_("Anchor for paging"),
        )
        parser.add_argument(
            "--end-marker",
            metavar="<end-marker>",
            help=_("End anchor for paging"),
        )
        parser.add_argument(
            "--limit",
            metavar="<num-containers>",
            type=int,
            help=_("Limit the number of containers returned"),
        )
        parser.add_argument(
            '--long',
            action='store_true',
            default=False,
            help=_('List additional fields in output'),
        )
        parser.add_argument(
            '--all',
            action='store_true',
            default=False,
            help=_('List all containers (default is 10000)'),
        )
        return parser

    def take_action(self, parsed_args):

        if parsed_args.long:
            columns = ('Name', 'Bytes', 'Count')
        else:
            columns = ('Name', )

        kwargs = {}
        if parsed_args.prefix:
            kwargs['prefix'] = parsed_args.prefix
        if parsed_args.marker:
            kwargs['marker'] = parsed_args.marker
        if parsed_args.end_marker:
            kwargs['end_marker'] = parsed_args.end_marker
        if parsed_args.limit:
            kwargs['limit'] = parsed_args.limit
        if parsed_args.all:
            kwargs['full_listing'] = True

        data = self.app.client_manager.object_store.container_list(**kwargs)

        return (columns, (utils.get_dict_properties(
            s,
            columns,
            formatters={},
        ) for s in data))
class ListNetworkAgent(command.Lister):
    _description = _("List network agents")

    def get_parser(self, prog_name):
        parser = super(ListNetworkAgent, self).get_parser(prog_name)
        parser.add_argument(
            '--agent-type',
            metavar='<agent-type>',
            choices=[
                "bgp", "dhcp", "open-vswitch", "linux-bridge", "ofa", "l3",
                "loadbalancer", "metering", "metadata", "macvtap", "nic"
            ],
            help=_("List only agents with the specified agent type. "
                   "The supported agent types are: bgp, dhcp, open-vswitch, "
                   "linux-bridge, ofa, l3, loadbalancer, metering, "
                   "metadata, macvtap, nic."))
        parser.add_argument(
            '--host',
            metavar='<host>',
            help=_("List only agents running on the specified host"))
        agent_type_group = parser.add_mutually_exclusive_group()
        agent_type_group.add_argument(
            '--network',
            metavar='<network>',
            help=_('List agents hosting a network (name or ID)'))
        agent_type_group.add_argument(
            '--router',
            metavar='<router>',
            help=_('List agents hosting this router (name or ID)'))
        parser.add_argument('--long',
                            action='store_true',
                            default=False,
                            help=_("List additional fields in output"))

        return parser

    def take_action(self, parsed_args):
        client = self.app.client_manager.network
        columns = ('id', 'agent_type', 'host', 'availability_zone', 'is_alive',
                   'is_admin_state_up', 'binary')
        column_headers = ('ID', 'Agent Type', 'Host', 'Availability Zone',
                          'Alive', 'State', 'Binary')

        key_value = {
            'bgp': 'BGP dynamic routing agent',
            'dhcp': 'DHCP agent',
            'open-vswitch': 'Open vSwitch agent',
            'linux-bridge': 'Linux bridge agent',
            'ofa': 'OFA driver agent',
            'l3': 'L3 agent',
            'loadbalancer': 'Loadbalancer agent',
            'metering': 'Metering agent',
            'metadata': 'Metadata agent',
            'macvtap': 'Macvtap agent',
            'nic': 'NIC Switch agent'
        }

        filters = {}

        if parsed_args.network is not None:
            network = client.find_network(parsed_args.network,
                                          ignore_missing=False)
            data = client.network_hosting_dhcp_agents(network)
        elif parsed_args.router is not None:
            if parsed_args.long:
                columns += ('ha_state', )
                column_headers += ('HA State', )
            router = client.find_router(parsed_args.router,
                                        ignore_missing=False)
            data = client.routers_hosting_l3_agents(router)
        else:
            if parsed_args.agent_type is not None:
                filters['agent_type'] = key_value[parsed_args.agent_type]
            if parsed_args.host is not None:
                filters['host'] = parsed_args.host

            data = client.agents(**filters)
        return (column_headers, (utils.get_item_properties(
            s,
            columns,
            formatters=_formatters,
        ) for s in data))
Exemple #43
0
    def take_action(self, parsed_args):
        compute_client = self.app.client_manager.sdk_connection.compute
        identity_client = self.app.client_manager.identity

        kwargs = {'name': parsed_args.name}

        public_key = parsed_args.public_key
        if public_key:
            try:
                with io.open(os.path.expanduser(parsed_args.public_key)) as p:
                    public_key = p.read()
            except IOError as e:
                msg = _("Key file %(public_key)s not found: %(exception)s")
                raise exceptions.CommandError(msg % {
                    "public_key": parsed_args.public_key,
                    "exception": e
                })

            kwargs['public_key'] = public_key

        if parsed_args.type:
            if not sdk_utils.supports_microversion(compute_client, '2.2'):
                msg = _(
                    '--os-compute-api-version 2.2 or greater is required to '
                    'support the --type option')
                raise exceptions.CommandError(msg)

            kwargs['key_type'] = parsed_args.type

        if parsed_args.user:
            if not sdk_utils.supports_microversion(compute_client, '2.10'):
                msg = _(
                    '--os-compute-api-version 2.10 or greater is required to '
                    'support the --user option')
                raise exceptions.CommandError(msg)

            kwargs['user_id'] = identity_common.find_user(
                identity_client,
                parsed_args.user,
                parsed_args.user_domain,
            ).id

        keypair = compute_client.create_keypair(**kwargs)

        private_key = parsed_args.private_key
        # Save private key into specified file
        if private_key:
            try:
                with io.open(os.path.expanduser(parsed_args.private_key),
                             'w+') as p:
                    p.write(keypair.private_key)
            except IOError as e:
                msg = _("Key file %(private_key)s can not be saved: "
                        "%(exception)s")
                raise exceptions.CommandError(msg % {
                    "private_key": parsed_args.private_key,
                    "exception": e
                })
        # NOTE(dtroyer): how do we want to handle the display of the private
        #                key when it needs to be communicated back to the user
        #                For now, duplicate nova keypair-add command output
        if public_key or private_key:
            display_columns, columns = _get_keypair_columns(keypair,
                                                            hide_pub_key=True,
                                                            hide_priv_key=True)
            data = utils.get_item_properties(keypair, columns)

            return (display_columns, data)
        else:
            sys.stdout.write(keypair.private_key)
            return ({}, {})
class ListExtension(command.Lister):
    _description = _("List API extensions")

    def get_parser(self, prog_name):
        parser = super(ListExtension, self).get_parser(prog_name)
        parser.add_argument(
            '--compute',
            action='store_true',
            default=False,
            help=_('List extensions for the Compute API'),
        )
        parser.add_argument(
            '--identity',
            action='store_true',
            default=False,
            help=_('List extensions for the Identity API'),
        )
        parser.add_argument(
            '--network',
            action='store_true',
            default=False,
            help=_('List extensions for the Network API'),
        )
        parser.add_argument(
            '--volume',
            action='store_true',
            default=False,
            help=_('List extensions for the Block Storage API'),
        )
        parser.add_argument(
            '--long',
            action='store_true',
            default=False,
            help=_('List additional fields in output'),
        )
        return parser

    def take_action(self, parsed_args):
        if parsed_args.long:
            columns = ('Name', 'Alias', 'Description', 'Namespace', 'Updated',
                       'Links')
        else:
            columns = ('Name', 'Alias', 'Description')

        data = []

        # by default we want to show everything, unless the
        # user specifies one or more of the APIs to show
        # for now, only identity and compute are supported.
        show_all = (not parsed_args.identity and not parsed_args.compute
                    and not parsed_args.volume and not parsed_args.network)

        if parsed_args.identity or show_all:
            identity_client = self.app.client_manager.identity
            try:
                data += identity_client.extensions.list()
            except Exception:
                message = _("Extensions list not supported by Identity API")
                LOG.warning(message)

        if parsed_args.compute or show_all:
            compute_client = self.app.client_manager.compute
            try:
                data += compute_client.list_extensions.show_all()
            except Exception:
                message = _("Extensions list not supported by Compute API")
                LOG.warning(message)

        if parsed_args.volume or show_all:
            volume_client = self.app.client_manager.volume
            try:
                data += volume_client.list_extensions.show_all()
            except Exception:
                message = _("Extensions list not supported by "
                            "Block Storage API")
                LOG.warning(message)

        if parsed_args.network or show_all:
            network_client = self.app.client_manager.network
            try:
                data += network_client.extensions()
            except Exception:
                message = _("Failed to retrieve extensions list "
                            "from Network API")
                LOG.warning(message)

        extension_tuples = (utils.get_item_properties(
            s,
            columns,
        ) for s in data)

        return (columns, extension_tuples)
Exemple #45
0
    def take_action(self, parsed_args):
        compute_client = self.app.client_manager.sdk_connection.compute
        identity_client = self.app.client_manager.identity

        kwargs = {}

        if parsed_args.marker:
            if not sdk_utils.supports_microversion(compute_client, '2.35'):
                msg = _('--os-compute-api-version 2.35 or greater is required '
                        'to support the --marker option')
                raise exceptions.CommandError(msg)

            kwargs['marker'] = parsed_args.marker

        if parsed_args.limit:
            if not sdk_utils.supports_microversion(compute_client, '2.35'):
                msg = _('--os-compute-api-version 2.35 or greater is required '
                        'to support the --limit option')
                raise exceptions.CommandError(msg)

            kwargs['limit'] = parsed_args.limit

        if parsed_args.project:
            if not sdk_utils.supports_microversion(compute_client, '2.10'):
                msg = _(
                    '--os-compute-api-version 2.10 or greater is required to '
                    'support the --project option')
                raise exceptions.CommandError(msg)

            if parsed_args.marker:
                # NOTE(stephenfin): Because we're doing this client-side, we
                # can't really rely on the marker, because we don't know what
                # user the marker is associated with
                msg = _('--project is not compatible with --marker')

            # NOTE(stephenfin): This is done client side because nova doesn't
            # currently support doing so server-side. If this is slow, we can
            # think about spinning up a threadpool or similar.
            project = identity_common.find_project(
                identity_client,
                parsed_args.project,
                parsed_args.project_domain,
            ).id
            users = identity_client.users.list(tenant_id=project)

            data = []
            for user in users:
                kwargs['user_id'] = user.id
                data.extend(compute_client.keypairs(**kwargs))
        elif parsed_args.user:
            if not sdk_utils.supports_microversion(compute_client, '2.10'):
                msg = _(
                    '--os-compute-api-version 2.10 or greater is required to '
                    'support the --user option')
                raise exceptions.CommandError(msg)

            user = identity_common.find_user(
                identity_client,
                parsed_args.user,
                parsed_args.user_domain,
            )
            kwargs['user_id'] = user.id

            data = compute_client.keypairs(**kwargs)
        else:
            data = compute_client.keypairs(**kwargs)

        columns = ("Name", "Fingerprint")

        if sdk_utils.supports_microversion(compute_client, '2.2'):
            columns += ("Type", )

        return (
            columns,
            (utils.get_item_properties(s, columns) for s in data),
        )
 def get_parser(self, prog_name):
     parser = super(ShowPort, self).get_parser(prog_name)
     parser.add_argument('port',
                         metavar="<port>",
                         help=_("Port to display (name or ID)"))
     return parser
Exemple #47
0
class CreateApplicationCredential(command.ShowOne):
    _description = _("Create new application credential")

    def get_parser(self, prog_name):
        parser = super(CreateApplicationCredential, self).get_parser(prog_name)
        parser.add_argument(
            'name',
            metavar='<name>',
            help=_('Name of the application credential'),
        )
        parser.add_argument(
            '--secret',
            metavar='<secret>',
            help=_('Secret to use for authentication (if not provided, one'
                   ' will be generated)'),
        )
        parser.add_argument(
            '--role',
            metavar='<role>',
            action='append',
            default=[],
            help=_('Roles to authorize (name or ID) (repeat option to set'
                   ' multiple values)'),
        )
        parser.add_argument(
            '--expiration',
            metavar='<expiration>',
            help=_('Sets an expiration date for the application credential,'
                   ' format of YYYY-mm-ddTHH:MM:SS (if not provided, the'
                   ' application credential will not expire)'),
        )
        parser.add_argument(
            '--description',
            metavar='<description>',
            help=_('Application credential description'),
        )
        parser.add_argument(
            '--unrestricted',
            action="store_true",
            help=_('Enable application credential to create and delete other'
                   ' application credentials and trusts (this is potentially'
                   ' dangerous behavior and is disabled by default)'),
        )
        parser.add_argument(
            '--restricted',
            action="store_true",
            help=_('Prohibit application credential from creating and deleting'
                   ' other application credentials and trusts (this is the'
                   ' default behavior)'),
        )
        parser.add_argument(
            '--access-rules',
            metavar='<access-rules>',
            help=_('Either a string or file path containing a JSON-formatted '
                   'list of access rules, each containing a request method, '
                   'path, and service, for example '
                   '\'[{"method": "GET", '
                   '"path": "/v2.1/servers", '
                   '"service": "compute"}]\''),
        )
        return parser

    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity

        role_ids = []
        for role in parsed_args.role:
            # A user can only create an application credential for themself,
            # not for another user even as an admin, and only on the project to
            # which they are currently scoped with a subset of the role
            # assignments they have on that project. Don't bother trying to
            # look up roles via keystone, just introspect the token.
            role_id = common._get_token_resource(identity_client, "roles",
                                                 role)
            role_ids.append(role_id)

        expires_at = None
        if parsed_args.expiration:
            expires_at = datetime.datetime.strptime(parsed_args.expiration,
                                                    '%Y-%m-%dT%H:%M:%S')

        if parsed_args.restricted:
            unrestricted = False
        else:
            unrestricted = parsed_args.unrestricted

        if parsed_args.access_rules:
            try:
                access_rules = json.loads(parsed_args.access_rules)
            except ValueError:
                try:
                    with open(parsed_args.access_rules) as f:
                        access_rules = json.load(f)
                except IOError:
                    raise exceptions.CommandError(
                        _("Access rules is not valid JSON string or file does"
                          " not exist."))
        else:
            access_rules = None

        app_cred_manager = identity_client.application_credentials
        application_credential = app_cred_manager.create(
            parsed_args.name,
            roles=role_ids,
            expires_at=expires_at,
            description=parsed_args.description,
            secret=parsed_args.secret,
            unrestricted=unrestricted,
            access_rules=access_rules,
        )

        application_credential._info.pop('links', None)

        # Format roles into something sensible
        roles = application_credential._info.pop('roles')
        msg = ' '.join(r['name'] for r in roles)
        application_credential._info['roles'] = msg

        return zip(*sorted(application_credential._info.items()))
Exemple #48
0
class CreateKeypair(command.ShowOne):
    _description = _("Create new public or private key for server ssh access")

    def get_parser(self, prog_name):
        parser = super(CreateKeypair, self).get_parser(prog_name)
        parser.add_argument('name',
                            metavar='<name>',
                            help=_("New public or private key name"))
        key_group = parser.add_mutually_exclusive_group()
        key_group.add_argument(
            '--public-key',
            metavar='<file>',
            help=_("Filename for public key to add. If not used, "
                   "creates a private key."))
        key_group.add_argument(
            '--private-key',
            metavar='<file>',
            help=_("Filename for private key to save. If not used, "
                   "print private key in console."))
        parser.add_argument(
            '--type',
            metavar='<type>',
            choices=['ssh', 'x509'],
            help=_("Keypair type. Can be ssh or x509. "
                   "(Supported by API versions '2.2' - '2.latest')"),
        )
        parser.add_argument(
            '--user',
            metavar='<user>',
            help=_('The owner of the keypair. (admin only) (name or ID). '
                   'Requires ``--os-compute-api-version`` 2.10 or greater.'),
        )
        identity_common.add_user_domain_option_to_parser(parser)
        return parser

    def take_action(self, parsed_args):
        compute_client = self.app.client_manager.sdk_connection.compute
        identity_client = self.app.client_manager.identity

        kwargs = {'name': parsed_args.name}

        public_key = parsed_args.public_key
        if public_key:
            try:
                with io.open(os.path.expanduser(parsed_args.public_key)) as p:
                    public_key = p.read()
            except IOError as e:
                msg = _("Key file %(public_key)s not found: %(exception)s")
                raise exceptions.CommandError(msg % {
                    "public_key": parsed_args.public_key,
                    "exception": e
                })

            kwargs['public_key'] = public_key

        if parsed_args.type:
            if not sdk_utils.supports_microversion(compute_client, '2.2'):
                msg = _(
                    '--os-compute-api-version 2.2 or greater is required to '
                    'support the --type option')
                raise exceptions.CommandError(msg)

            kwargs['key_type'] = parsed_args.type

        if parsed_args.user:
            if not sdk_utils.supports_microversion(compute_client, '2.10'):
                msg = _(
                    '--os-compute-api-version 2.10 or greater is required to '
                    'support the --user option')
                raise exceptions.CommandError(msg)

            kwargs['user_id'] = identity_common.find_user(
                identity_client,
                parsed_args.user,
                parsed_args.user_domain,
            ).id

        keypair = compute_client.create_keypair(**kwargs)

        private_key = parsed_args.private_key
        # Save private key into specified file
        if private_key:
            try:
                with io.open(os.path.expanduser(parsed_args.private_key),
                             'w+') as p:
                    p.write(keypair.private_key)
            except IOError as e:
                msg = _("Key file %(private_key)s can not be saved: "
                        "%(exception)s")
                raise exceptions.CommandError(msg % {
                    "private_key": parsed_args.private_key,
                    "exception": e
                })
        # NOTE(dtroyer): how do we want to handle the display of the private
        #                key when it needs to be communicated back to the user
        #                For now, duplicate nova keypair-add command output
        if public_key or private_key:
            display_columns, columns = _get_keypair_columns(keypair,
                                                            hide_pub_key=True,
                                                            hide_priv_key=True)
            data = utils.get_item_properties(keypair, columns)

            return (display_columns, data)
        else:
            sys.stdout.write(keypair.private_key)
            return ({}, {})
class ListSubnetPool(command.Lister):
    _description = _("List subnet pools")

    def get_parser(self, prog_name):
        parser = super(ListSubnetPool, self).get_parser(prog_name)
        parser.add_argument('--long',
                            action='store_true',
                            default=False,
                            help=_("List additional fields in output"))
        shared_group = parser.add_mutually_exclusive_group()
        shared_group.add_argument(
            '--share',
            action='store_true',
            help=_("List subnet pools shared between projects"),
        )
        shared_group.add_argument(
            '--no-share',
            action='store_true',
            help=_("List subnet pools not shared between projects"),
        )
        default_group = parser.add_mutually_exclusive_group()
        default_group.add_argument(
            '--default',
            action='store_true',
            help=_("List subnet pools used as the default external "
                   "subnet pool"),
        )
        default_group.add_argument(
            '--no-default',
            action='store_true',
            help=_("List subnet pools not used as the default external "
                   "subnet pool"))
        parser.add_argument(
            '--project',
            metavar='<project>',
            help=_(
                "List subnet pools according to their project (name or ID)"))
        identity_common.add_project_domain_option_to_parser(parser)
        parser.add_argument(
            '--name',
            metavar='<name>',
            help=_("List only subnet pools of given name in output"))
        parser.add_argument(
            '--address-scope',
            metavar='<address-scope>',
            help=_("List only subnet pools of given address scope "
                   "in output (name or ID)"))
        _tag.add_tag_filtering_option_to_parser(parser, _('subnet pools'))
        return parser

    def take_action(self, parsed_args):
        identity_client = self.app.client_manager.identity
        network_client = self.app.client_manager.network
        filters = {}
        if parsed_args.share:
            filters['shared'] = True
            filters['is_shared'] = True
        elif parsed_args.no_share:
            filters['shared'] = False
            filters['is_shared'] = False
        if parsed_args.default:
            filters['is_default'] = True
        elif parsed_args.no_default:
            filters['is_default'] = False
        if parsed_args.project:
            project_id = identity_common.find_project(
                identity_client,
                parsed_args.project,
                parsed_args.project_domain,
            ).id
            filters['tenant_id'] = project_id
            filters['project_id'] = project_id
        if parsed_args.name is not None:
            filters['name'] = parsed_args.name
        if parsed_args.address_scope:
            address_scope = network_client.find_address_scope(
                parsed_args.address_scope, ignore_missing=False)
            filters['address_scope_id'] = address_scope.id
        _tag.get_tag_filtering_args(parsed_args, filters)
        data = network_client.subnet_pools(**filters)

        headers = ('ID', 'Name', 'Prefixes')
        columns = ('id', 'name', 'prefixes')
        if parsed_args.long:
            headers += ('Default Prefix Length', 'Address Scope',
                        'Default Subnet Pool', 'Shared', 'Tags')
            columns += ('default_prefix_length', 'address_scope_id',
                        'is_default', 'is_shared', 'tags')

        return (headers, (utils.get_item_properties(
            s,
            columns,
            formatters=_formatters,
        ) for s in data))
Exemple #50
0
class ListKeypair(command.Lister):
    _description = _("List key fingerprints")

    def get_parser(self, prog_name):
        parser = super().get_parser(prog_name)
        user_group = parser.add_mutually_exclusive_group()
        user_group.add_argument(
            '--user',
            metavar='<user>',
            help=_('Show keypairs for another user (admin only) (name or ID). '
                   'Requires ``--os-compute-api-version`` 2.10 or greater.'),
        )
        identity_common.add_user_domain_option_to_parser(parser)
        user_group.add_argument(
            '--project',
            metavar='<project>',
            help=_('Show keypairs for all users associated with project '
                   '(admin only) (name or ID). '
                   'Requires ``--os-compute-api-version`` 2.10 or greater.'),
        )
        identity_common.add_project_domain_option_to_parser(parser)
        parser.add_argument(
            '--marker',
            help=_('The last keypair ID of the previous page'),
        )
        parser.add_argument(
            '--limit',
            type=int,
            help=_('Maximum number of keypairs to display'),
        )
        return parser

    def take_action(self, parsed_args):
        compute_client = self.app.client_manager.sdk_connection.compute
        identity_client = self.app.client_manager.identity

        kwargs = {}

        if parsed_args.marker:
            if not sdk_utils.supports_microversion(compute_client, '2.35'):
                msg = _('--os-compute-api-version 2.35 or greater is required '
                        'to support the --marker option')
                raise exceptions.CommandError(msg)

            kwargs['marker'] = parsed_args.marker

        if parsed_args.limit:
            if not sdk_utils.supports_microversion(compute_client, '2.35'):
                msg = _('--os-compute-api-version 2.35 or greater is required '
                        'to support the --limit option')
                raise exceptions.CommandError(msg)

            kwargs['limit'] = parsed_args.limit

        if parsed_args.project:
            if not sdk_utils.supports_microversion(compute_client, '2.10'):
                msg = _(
                    '--os-compute-api-version 2.10 or greater is required to '
                    'support the --project option')
                raise exceptions.CommandError(msg)

            if parsed_args.marker:
                # NOTE(stephenfin): Because we're doing this client-side, we
                # can't really rely on the marker, because we don't know what
                # user the marker is associated with
                msg = _('--project is not compatible with --marker')

            # NOTE(stephenfin): This is done client side because nova doesn't
            # currently support doing so server-side. If this is slow, we can
            # think about spinning up a threadpool or similar.
            project = identity_common.find_project(
                identity_client,
                parsed_args.project,
                parsed_args.project_domain,
            ).id
            users = identity_client.users.list(tenant_id=project)

            data = []
            for user in users:
                kwargs['user_id'] = user.id
                data.extend(compute_client.keypairs(**kwargs))
        elif parsed_args.user:
            if not sdk_utils.supports_microversion(compute_client, '2.10'):
                msg = _(
                    '--os-compute-api-version 2.10 or greater is required to '
                    'support the --user option')
                raise exceptions.CommandError(msg)

            user = identity_common.find_user(
                identity_client,
                parsed_args.user,
                parsed_args.user_domain,
            )
            kwargs['user_id'] = user.id

            data = compute_client.keypairs(**kwargs)
        else:
            data = compute_client.keypairs(**kwargs)

        columns = ("Name", "Fingerprint")

        if sdk_utils.supports_microversion(compute_client, '2.2'):
            columns += ("Type", )

        return (
            columns,
            (utils.get_item_properties(s, columns) for s in data),
        )
    def take_action_network(self, client, parsed_args):
        # Get the security group ID to hold the rule.
        security_group_id = client.find_security_group(
            parsed_args.group,
            ignore_missing=False
        ).id

        # Build the create attributes.
        attrs = {}
        attrs['protocol'] = self._get_protocol(parsed_args)

        if parsed_args.description is not None:
            attrs['description'] = parsed_args.description

        # NOTE(rtheis): A direction must be specified and ingress
        # is the default.
        if parsed_args.ingress or not parsed_args.egress:
            attrs['direction'] = 'ingress'
        if parsed_args.egress:
            attrs['direction'] = 'egress'

        # NOTE(rtheis): Use ethertype specified else default based
        # on IP protocol.
        attrs['ethertype'] = self._get_ethertype(parsed_args,
                                                 attrs['protocol'])

        # NOTE(rtheis): Validate the port range and ICMP type and code.
        # It would be ideal if argparse could do this.
        if parsed_args.dst_port and (parsed_args.icmp_type or
                                     parsed_args.icmp_code):
            msg = _('Argument --dst-port not allowed with arguments '
                    '--icmp-type and --icmp-code')
            raise exceptions.CommandError(msg)
        if parsed_args.icmp_type is None and parsed_args.icmp_code is not None:
            msg = _('Argument --icmp-type required with argument --icmp-code')
            raise exceptions.CommandError(msg)
        is_icmp_protocol = _is_icmp_protocol(attrs['protocol'])
        if not is_icmp_protocol and (parsed_args.icmp_type or
                                     parsed_args.icmp_code):
            msg = _('ICMP IP protocol required with arguments '
                    '--icmp-type and --icmp-code')
            raise exceptions.CommandError(msg)
        # NOTE(rtheis): For backwards compatibility, continue ignoring
        # the destination port range when an ICMP IP protocol is specified.
        if parsed_args.dst_port and not is_icmp_protocol:
            attrs['port_range_min'] = parsed_args.dst_port[0]
            attrs['port_range_max'] = parsed_args.dst_port[1]
        if parsed_args.icmp_type is not None and parsed_args.icmp_type >= 0:
            attrs['port_range_min'] = parsed_args.icmp_type
        if parsed_args.icmp_code is not None and parsed_args.icmp_code >= 0:
            attrs['port_range_max'] = parsed_args.icmp_code

        if parsed_args.remote_group is not None:
            attrs['remote_group_id'] = client.find_security_group(
                parsed_args.remote_group,
                ignore_missing=False
            ).id
        elif parsed_args.remote_ip is not None:
            attrs['remote_ip_prefix'] = parsed_args.remote_ip
        elif attrs['ethertype'] == 'IPv4':
            attrs['remote_ip_prefix'] = '0.0.0.0/0'
        elif attrs['ethertype'] == 'IPv6':
            attrs['remote_ip_prefix'] = '::/0'
        attrs['security_group_id'] = security_group_id
        if parsed_args.project is not None:
            identity_client = self.app.client_manager.identity
            project_id = identity_common.find_project(
                identity_client,
                parsed_args.project,
                parsed_args.project_domain,
            ).id
            attrs['tenant_id'] = project_id

        # Create and show the security group rule.
        obj = client.create_security_group_rule(**attrs)
        display_columns, columns = _get_columns(obj)
        data = utils.get_item_properties(obj, columns)
        return (display_columns, data)
 def get_parser(self, prog_name):
     parser = super(ShowSubnetPool, self).get_parser(prog_name)
     parser.add_argument('subnet_pool',
                         metavar='<subnet-pool>',
                         help=_("Subnet pool to display (name or ID)"))
     return parser
class CreateSecurityGroupRule(common.NetworkAndComputeShowOne):
    _description = _("Create a new security group rule")

    def update_parser_common(self, parser):
        parser.add_argument(
            'group',
            metavar='<group>',
            help=_("Create rule in this security group (name or ID)")
        )
        remote_group = parser.add_mutually_exclusive_group()
        remote_group.add_argument(
            "--remote-ip",
            metavar="<ip-address>",
            help=_("Remote IP address block (may use CIDR notation; "
                   "default for IPv4 rule: 0.0.0.0/0, "
                   "default for IPv6 rule: ::/0)"),
        )
        remote_group.add_argument(
            "--remote-group",
            metavar="<group>",
            help=_("Remote security group (name or ID)"),
        )
        return parser

    def update_parser_network(self, parser):
        parser.add_argument(
            '--description',
            metavar='<description>',
            help=_("Set security group rule description")
        )
        parser.add_argument(
            '--dst-port',
            metavar='<port-range>',
            action=parseractions.RangeAction,
            help=_("Destination port, may be a single port or a starting and "
                   "ending port range: 137:139. Required for IP protocols TCP "
                   "and UDP. Ignored for ICMP IP protocols.")
        )
        parser.add_argument(
            '--icmp-type',
            metavar='<icmp-type>',
            type=int,
            help=_("ICMP type for ICMP IP protocols")
        )
        parser.add_argument(
            '--icmp-code',
            metavar='<icmp-code>',
            type=int,
            help=_("ICMP code for ICMP IP protocols")
        )
        # NOTE(rtheis): Support either protocol option name for now.
        # However, consider deprecating and then removing --proto in
        # a future release.
        protocol_group = parser.add_mutually_exclusive_group()
        protocol_group.add_argument(
            '--protocol',
            metavar='<protocol>',
            type=_convert_to_lowercase,
            help=_("IP protocol (ah, dccp, egp, esp, gre, icmp, igmp, "
                   "ipv6-encap, ipv6-frag, ipv6-icmp, ipv6-nonxt, "
                   "ipv6-opts, ipv6-route, ospf, pgm, rsvp, sctp, tcp, "
                   "udp, udplite, vrrp and integer representations [0-255] "
                   "or any; default: any (all protocols))")
        )
        protocol_group.add_argument(
            '--proto',
            metavar='<proto>',
            type=_convert_to_lowercase,
            help=argparse.SUPPRESS
        )
        direction_group = parser.add_mutually_exclusive_group()
        direction_group.add_argument(
            '--ingress',
            action='store_true',
            help=_("Rule applies to incoming network traffic (default)")
        )
        direction_group.add_argument(
            '--egress',
            action='store_true',
            help=_("Rule applies to outgoing network traffic")
        )
        parser.add_argument(
            '--ethertype',
            metavar='<ethertype>',
            choices=['IPv4', 'IPv6'],
            type=_convert_ipvx_case,
            help=_("Ethertype of network traffic "
                   "(IPv4, IPv6; default: based on IP protocol)")
        )
        parser.add_argument(
            '--project',
            metavar='<project>',
            help=_("Owner's project (name or ID)")
        )
        identity_common.add_project_domain_option_to_parser(parser)
        return parser

    def update_parser_compute(self, parser):
        parser.add_argument(
            '--dst-port',
            metavar='<port-range>',
            default=(0, 0),
            action=parseractions.RangeAction,
            help=_("Destination port, may be a single port or a starting and "
                   "ending port range: 137:139. Required for IP protocols TCP "
                   "and UDP. Ignored for ICMP IP protocols.")
        )
        # NOTE(rtheis): Support either protocol option name for now.
        # However, consider deprecating and then removing --proto in
        # a future release.
        protocol_group = parser.add_mutually_exclusive_group()
        protocol_group.add_argument(
            '--protocol',
            metavar='<protocol>',
            choices=['icmp', 'tcp', 'udp'],
            type=_convert_to_lowercase,
            help=_("IP protocol (icmp, tcp, udp; default: tcp)")
        )
        protocol_group.add_argument(
            '--proto',
            metavar='<proto>',
            choices=['icmp', 'tcp', 'udp'],
            type=_convert_to_lowercase,
            help=argparse.SUPPRESS
        )
        return parser

    def _get_protocol(self, parsed_args, default_protocol='any'):
        protocol = default_protocol
        if parsed_args.protocol is not None:
            protocol = parsed_args.protocol
        if parsed_args.proto is not None:
            protocol = parsed_args.proto
        if protocol == 'any':
            protocol = None
        return protocol

    def _get_ethertype(self, parsed_args, protocol):
        ethertype = 'IPv4'
        if parsed_args.ethertype is not None:
            ethertype = parsed_args.ethertype
        elif self._is_ipv6_protocol(protocol):
            ethertype = 'IPv6'
        return ethertype

    def _is_ipv6_protocol(self, protocol):
        # NOTE(rtheis): Neutron has deprecated protocol icmpv6.
        # However, while the OSC CLI doesn't document the protocol,
        # the code must still handle it. In addition, handle both
        # protocol names and numbers.
        if (protocol is not None and protocol.startswith('ipv6-') or
                protocol in ['icmpv6', '41', '43', '44', '58', '59', '60']):
            return True
        else:
            return False

    def take_action_network(self, client, parsed_args):
        # Get the security group ID to hold the rule.
        security_group_id = client.find_security_group(
            parsed_args.group,
            ignore_missing=False
        ).id

        # Build the create attributes.
        attrs = {}
        attrs['protocol'] = self._get_protocol(parsed_args)

        if parsed_args.description is not None:
            attrs['description'] = parsed_args.description

        # NOTE(rtheis): A direction must be specified and ingress
        # is the default.
        if parsed_args.ingress or not parsed_args.egress:
            attrs['direction'] = 'ingress'
        if parsed_args.egress:
            attrs['direction'] = 'egress'

        # NOTE(rtheis): Use ethertype specified else default based
        # on IP protocol.
        attrs['ethertype'] = self._get_ethertype(parsed_args,
                                                 attrs['protocol'])

        # NOTE(rtheis): Validate the port range and ICMP type and code.
        # It would be ideal if argparse could do this.
        if parsed_args.dst_port and (parsed_args.icmp_type or
                                     parsed_args.icmp_code):
            msg = _('Argument --dst-port not allowed with arguments '
                    '--icmp-type and --icmp-code')
            raise exceptions.CommandError(msg)
        if parsed_args.icmp_type is None and parsed_args.icmp_code is not None:
            msg = _('Argument --icmp-type required with argument --icmp-code')
            raise exceptions.CommandError(msg)
        is_icmp_protocol = _is_icmp_protocol(attrs['protocol'])
        if not is_icmp_protocol and (parsed_args.icmp_type or
                                     parsed_args.icmp_code):
            msg = _('ICMP IP protocol required with arguments '
                    '--icmp-type and --icmp-code')
            raise exceptions.CommandError(msg)
        # NOTE(rtheis): For backwards compatibility, continue ignoring
        # the destination port range when an ICMP IP protocol is specified.
        if parsed_args.dst_port and not is_icmp_protocol:
            attrs['port_range_min'] = parsed_args.dst_port[0]
            attrs['port_range_max'] = parsed_args.dst_port[1]
        if parsed_args.icmp_type is not None and parsed_args.icmp_type >= 0:
            attrs['port_range_min'] = parsed_args.icmp_type
        if parsed_args.icmp_code is not None and parsed_args.icmp_code >= 0:
            attrs['port_range_max'] = parsed_args.icmp_code

        if parsed_args.remote_group is not None:
            attrs['remote_group_id'] = client.find_security_group(
                parsed_args.remote_group,
                ignore_missing=False
            ).id
        elif parsed_args.remote_ip is not None:
            attrs['remote_ip_prefix'] = parsed_args.remote_ip
        elif attrs['ethertype'] == 'IPv4':
            attrs['remote_ip_prefix'] = '0.0.0.0/0'
        elif attrs['ethertype'] == 'IPv6':
            attrs['remote_ip_prefix'] = '::/0'
        attrs['security_group_id'] = security_group_id
        if parsed_args.project is not None:
            identity_client = self.app.client_manager.identity
            project_id = identity_common.find_project(
                identity_client,
                parsed_args.project,
                parsed_args.project_domain,
            ).id
            attrs['tenant_id'] = project_id

        # Create and show the security group rule.
        obj = client.create_security_group_rule(**attrs)
        display_columns, columns = _get_columns(obj)
        data = utils.get_item_properties(obj, columns)
        return (display_columns, data)

    def take_action_compute(self, client, parsed_args):
        group = client.api.security_group_find(parsed_args.group)
        protocol = self._get_protocol(parsed_args, default_protocol='tcp')
        if protocol == 'icmp':
            from_port, to_port = -1, -1
        else:
            from_port, to_port = parsed_args.dst_port

        remote_ip = None
        if parsed_args.remote_group is not None:
            parsed_args.remote_group = client.api.security_group_find(
                parsed_args.remote_group,
            )['id']
        if parsed_args.remote_ip is not None:
            remote_ip = parsed_args.remote_ip
        else:
            remote_ip = '0.0.0.0/0'

        obj = client.api.security_group_rule_create(
            security_group_id=group['id'],
            ip_protocol=protocol,
            from_port=from_port,
            to_port=to_port,
            remote_ip=remote_ip,
            remote_group=parsed_args.remote_group,
        )
        return _format_security_group_rule_show(obj)
class ListSecurityGroupRule(common.NetworkAndComputeLister):
    _description = _("List security group rules")

    def _format_network_security_group_rule(self, rule):
        """Transform the SDK SecurityGroupRule object to a dict

        The SDK object gets in the way of reformatting columns...
        Create port_range column from port_range_min and port_range_max
        """
        rule = rule.to_dict()
        rule['port_range'] = _format_network_port_range(rule)
        rule['remote_ip_prefix'] = _format_remote_ip_prefix(rule)
        return rule

    def update_parser_common(self, parser):
        parser.add_argument(
            'group',
            metavar='<group>',
            nargs='?',
            help=_("List all rules in this security group (name or ID)")
        )
        return parser

    def update_parser_network(self, parser):
        # Accept but hide the argument for consistency with compute.
        # Network will always return all projects for an admin.
        parser.add_argument(
            '--all-projects',
            action='store_true',
            default=False,
            help=argparse.SUPPRESS
        )
        parser.add_argument(
            '--protocol',
            metavar='<protocol>',
            type=_convert_to_lowercase,
            help=_("List rules by the IP protocol ("
                   "ah, dhcp, egp, esp, gre, icmp, igmp, "
                   "ipv6-encap, ipv6-frag, ipv6-icmp, ipv6-nonxt, "
                   "ipv6-opts, ipv6-route, ospf, pgm, rsvp, sctp, tcp, "
                   "udp, udplite, vrrp and integer representations [0-255] "
                   "or any; default: any (all protocols))")
        )
        parser.add_argument(
            '--ethertype',
            metavar='<ethertype>',
            type=_convert_to_lowercase,
            help=_("List rules by the Ethertype (IPv4 or IPv6)")
        )
        direction_group = parser.add_mutually_exclusive_group()
        direction_group.add_argument(
            '--ingress',
            action='store_true',
            help=_("List rules applied to incoming network traffic")
        )
        direction_group.add_argument(
            '--egress',
            action='store_true',
            help=_("List rules applied to outgoing network traffic")
        )
        parser.add_argument(
            '--long',
            action='store_true',
            default=False,
            help=_("List additional fields in output")
        )
        return parser

    def update_parser_compute(self, parser):
        parser.add_argument(
            '--all-projects',
            action='store_true',
            default=False,
            help=_("Display information from all projects (admin only)")
        )
        # Accept but hide the argument for consistency with network.
        # There are no additional fields to display at this time.
        parser.add_argument(
            '--long',
            action='store_false',
            default=False,
            help=argparse.SUPPRESS
        )
        return parser

    def _get_column_headers(self, parsed_args):
        column_headers = (
            'ID',
            'IP Protocol',
            'Ethertype',
            'IP Range',
            'Port Range',
        )
        if parsed_args.long:
            column_headers = column_headers + ('Direction',)
        column_headers = column_headers + ('Remote Security Group',)
        if parsed_args.group is None:
            column_headers = column_headers + ('Security Group',)
        return column_headers

    def take_action_network(self, client, parsed_args):
        column_headers = self._get_column_headers(parsed_args)
        columns = (
            'id',
            'protocol',
            'ether_type',
            'remote_ip_prefix',
            'port_range',
        )
        if parsed_args.long:
            columns = columns + ('direction',)
        columns = columns + ('remote_group_id',)

        # Get the security group rules using the requested query.
        query = {}
        if parsed_args.group is not None:
            # NOTE(rtheis): Unfortunately, the security group resource
            # does not contain security group rules resources. So use
            # the security group ID in a query to get the resources.
            security_group_id = client.find_security_group(
                parsed_args.group,
                ignore_missing=False
            ).id
            query = {'security_group_id': security_group_id}
        else:
            columns = columns + ('security_group_id',)

        if parsed_args.ingress:
            query['direction'] = 'ingress'
        if parsed_args.egress:
            query['direction'] = 'egress'
        if parsed_args.protocol is not None:
            query['protocol'] = parsed_args.protocol

        rules = [
            self._format_network_security_group_rule(r)
            for r in client.security_group_rules(**query)
        ]

        return (column_headers,
                (utils.get_dict_properties(
                    s, columns,
                ) for s in rules))

    def take_action_compute(self, client, parsed_args):
        column_headers = self._get_column_headers(parsed_args)
        columns = (
            "ID",
            "IP Protocol",
            "Ethertype",
            "IP Range",
            "Port Range",
            "Remote Security Group",
        )

        rules_to_list = []
        if parsed_args.group is not None:
            group = client.api.security_group_find(
                parsed_args.group,
            )
            rules_to_list = group['rules']
        else:
            columns = columns + ('parent_group_id',)
            search = {'all_tenants': parsed_args.all_projects}
            for group in client.api.security_group_list(search_opts=search):
                rules_to_list.extend(group['rules'])

        # NOTE(rtheis): Turn the raw rules into resources.
        rules = []
        for rule in rules_to_list:
            rules.append(
                network_utils.transform_compute_security_group_rule(rule),
            )
            # rules.append(compute_secgroup_rules.SecurityGroupRule(
            #     client.security_group_rules,
            #     network_utils.transform_compute_security_group_rule(rule),
            # ))

        return (column_headers,
                (utils.get_dict_properties(
                    s, columns,
                ) for s in rules))
class SetVolumeSnapshot(command.Command):
    _description = _("Set volume snapshot properties")

    def get_parser(self, prog_name):
        parser = super(SetVolumeSnapshot, self).get_parser(prog_name)
        parser.add_argument(
            'snapshot',
            metavar='<snapshot>',
            help=_('Snapshot to modify (name or ID)')
        )
        parser.add_argument(
            '--name',
            metavar='<name>',
            help=_('New snapshot name')
        )
        parser.add_argument(
            '--description',
            metavar='<description>',
            help=_('New snapshot description')
        )
        parser.add_argument(
            "--no-property",
            dest="no_property",
            action="store_true",
            help=_("Remove all properties from <snapshot> "
                   "(specify both --no-property and --property to "
                   "remove the current properties before setting "
                   "new properties.)"),
        )
        parser.add_argument(
            '--property',
            metavar='<key=value>',
            action=parseractions.KeyValueAction,
            help=_('Property to add/change for this snapshot '
                   '(repeat option to set multiple properties)'),
        )
        parser.add_argument(
            '--state',
            metavar='<state>',
            choices=['available', 'error', 'creating', 'deleting',
                     'error-deleting'],
            help=_('New snapshot state. ("available", "error", "creating", '
                   '"deleting", or "error_deleting") (admin only) '
                   '(This option simply changes the state of the snapshot '
                   'in the database with no regard to actual status, '
                   'exercise caution when using)'),
        )
        return parser

    def take_action(self, parsed_args):
        volume_client = self.app.client_manager.volume
        snapshot = utils.find_resource(volume_client.volume_snapshots,
                                       parsed_args.snapshot)

        result = 0
        if parsed_args.no_property:
            try:
                key_list = snapshot.metadata.keys()
                volume_client.volume_snapshots.delete_metadata(
                    snapshot.id,
                    list(key_list),
                )
            except Exception as e:
                LOG.error(_("Failed to clean snapshot properties: %s"), e)
                result += 1

        if parsed_args.property:
            try:
                volume_client.volume_snapshots.set_metadata(
                    snapshot.id, parsed_args.property)
            except Exception as e:
                LOG.error(_("Failed to set snapshot property: %s"), e)
                result += 1

        if parsed_args.state:
            try:
                volume_client.volume_snapshots.reset_state(
                    snapshot.id, parsed_args.state)
            except Exception as e:
                LOG.error(_("Failed to set snapshot state: %s"), e)
                result += 1

        kwargs = {}
        if parsed_args.name:
            kwargs['name'] = parsed_args.name
        if parsed_args.description:
            kwargs['description'] = parsed_args.description
        if kwargs:
            try:
                volume_client.volume_snapshots.update(
                    snapshot.id, **kwargs)
            except Exception as e:
                LOG.error(_("Failed to update snapshot name "
                          "or description: %s"), e)
                result += 1

        if result > 0:
            raise exceptions.CommandError(_("One or more of the "
                                          "set operations failed"))
 def update_parser_network(self, parser):
     parser.add_argument(
         '--description',
         metavar='<description>',
         help=_("Set security group rule description")
     )
     parser.add_argument(
         '--dst-port',
         metavar='<port-range>',
         action=parseractions.RangeAction,
         help=_("Destination port, may be a single port or a starting and "
                "ending port range: 137:139. Required for IP protocols TCP "
                "and UDP. Ignored for ICMP IP protocols.")
     )
     parser.add_argument(
         '--icmp-type',
         metavar='<icmp-type>',
         type=int,
         help=_("ICMP type for ICMP IP protocols")
     )
     parser.add_argument(
         '--icmp-code',
         metavar='<icmp-code>',
         type=int,
         help=_("ICMP code for ICMP IP protocols")
     )
     # NOTE(rtheis): Support either protocol option name for now.
     # However, consider deprecating and then removing --proto in
     # a future release.
     protocol_group = parser.add_mutually_exclusive_group()
     protocol_group.add_argument(
         '--protocol',
         metavar='<protocol>',
         type=_convert_to_lowercase,
         help=_("IP protocol (ah, dccp, egp, esp, gre, icmp, igmp, "
                "ipv6-encap, ipv6-frag, ipv6-icmp, ipv6-nonxt, "
                "ipv6-opts, ipv6-route, ospf, pgm, rsvp, sctp, tcp, "
                "udp, udplite, vrrp and integer representations [0-255] "
                "or any; default: any (all protocols))")
     )
     protocol_group.add_argument(
         '--proto',
         metavar='<proto>',
         type=_convert_to_lowercase,
         help=argparse.SUPPRESS
     )
     direction_group = parser.add_mutually_exclusive_group()
     direction_group.add_argument(
         '--ingress',
         action='store_true',
         help=_("Rule applies to incoming network traffic (default)")
     )
     direction_group.add_argument(
         '--egress',
         action='store_true',
         help=_("Rule applies to outgoing network traffic")
     )
     parser.add_argument(
         '--ethertype',
         metavar='<ethertype>',
         choices=['IPv4', 'IPv6'],
         type=_convert_ipvx_case,
         help=_("Ethertype of network traffic "
                "(IPv4, IPv6; default: based on IP protocol)")
     )
     parser.add_argument(
         '--project',
         metavar='<project>',
         help=_("Owner's project (name or ID)")
     )
     identity_common.add_project_domain_option_to_parser(parser)
     return parser
 def get_parser(self, prog_name):
     parser = super(ShowProject, self).get_parser(prog_name)
     parser.add_argument('project',
                         metavar='<project>',
                         help=_('Project to display (name or ID)'))
     return parser
class CreateVolumeSnapshot(command.ShowOne):
    _description = _("Create new volume snapshot")

    def get_parser(self, prog_name):
        parser = super(CreateVolumeSnapshot, self).get_parser(prog_name)
        parser.add_argument(
            "snapshot_name",
            metavar="<snapshot-name>",
            help=_("Name of the new snapshot"),
        )
        parser.add_argument(
            "--volume",
            metavar="<volume>",
            help=_("Volume to snapshot (name or ID) "
                   "(default is <snapshot-name>)")
        )
        parser.add_argument(
            "--description",
            metavar="<description>",
            help=_("Description of the snapshot")
        )
        parser.add_argument(
            "--force",
            action="store_true",
            default=False,
            help=_("Create a snapshot attached to an instance. "
                   "Default is False")
        )
        parser.add_argument(
            "--property",
            metavar="<key=value>",
            action=parseractions.KeyValueAction,
            help=_("Set a property to this snapshot "
                   "(repeat option to set multiple properties)"),
        )
        parser.add_argument(
            "--remote-source",
            metavar="<key=value>",
            action=parseractions.KeyValueAction,
            help=_("The attribute(s) of the exsiting remote volume snapshot "
                   "(admin required) (repeat option to specify multiple "
                   "attributes) e.g.: '--remote-source source-name=test_name "
                   "--remote-source source-id=test_id'"),
        )
        return parser

    def take_action(self, parsed_args):
        volume_client = self.app.client_manager.volume
        volume = parsed_args.volume
        if not parsed_args.volume:
            volume = parsed_args.snapshot_name
        volume_id = utils.find_resource(
            volume_client.volumes, volume).id
        if parsed_args.remote_source:
            # Create a new snapshot from an existing remote snapshot source
            if parsed_args.force:
                msg = (_("'--force' option will not work when you create "
                         "new volume snapshot from an existing remote "
                         "volume snapshot"))
                LOG.warning(msg)
            snapshot = volume_client.volume_snapshots.manage(
                volume_id=volume_id,
                ref=parsed_args.remote_source,
                name=parsed_args.snapshot_name,
                description=parsed_args.description,
                metadata=parsed_args.property,
            )
        else:
            # create a new snapshot from scratch
            snapshot = volume_client.volume_snapshots.create(
                volume_id,
                force=parsed_args.force,
                name=parsed_args.snapshot_name,
                description=parsed_args.description,
                metadata=parsed_args.property,
            )
        snapshot._info.update(
            {'properties':
             format_columns.DictColumn(snapshot._info.pop('metadata'))}
        )
        return zip(*sorted(six.iteritems(snapshot._info)))
 def get_parser(self, prog_name):
     parser = super(DeleteRole, self).get_parser(prog_name)
     parser.add_argument('role',
                         metavar='<role>',
                         help=_('Name or ID of role to delete'))
     return parser
class ListVolumeSnapshot(command.Lister):
    _description = _("List volume snapshots")

    def get_parser(self, prog_name):
        parser = super(ListVolumeSnapshot, self).get_parser(prog_name)
        parser.add_argument(
            '--all-projects',
            action='store_true',
            default=False,
            help=_('Include all projects (admin only)'),
        )
        parser.add_argument(
            '--project',
            metavar='<project>',
            help=_('Filter results by project (name or ID) (admin only)')
        )
        identity_common.add_project_domain_option_to_parser(parser)
        parser.add_argument(
            '--long',
            action='store_true',
            default=False,
            help=_('List additional fields in output'),
        )
        parser.add_argument(
            '--marker',
            metavar='<volume-snapshot>',
            help=_('The last snapshot ID of the previous page'),
        )
        parser.add_argument(
            '--limit',
            type=int,
            action=parseractions.NonNegativeAction,
            metavar='<num-snapshots>',
            help=_('Maximum number of snapshots to display'),
        )
        parser.add_argument(
            '--name',
            metavar='<name>',
            default=None,
            help=_('Filters results by a name.')
        )
        parser.add_argument(
            '--status',
            metavar='<status>',
            choices=['available', 'error', 'creating', 'deleting',
                     'error-deleting'],
            help=_("Filters results by a status. "
                   "('available', 'error', 'creating', 'deleting'"
                   " or 'error-deleting')")
        )
        parser.add_argument(
            '--volume',
            metavar='<volume>',
            default=None,
            help=_('Filters results by a volume (name or ID).')
        )
        return parser

    def take_action(self, parsed_args):
        volume_client = self.app.client_manager.volume
        identity_client = self.app.client_manager.identity

        if parsed_args.long:
            columns = ['ID', 'Name', 'Description', 'Status',
                       'Size', 'Created At', 'Volume ID', 'Metadata']
            column_headers = copy.deepcopy(columns)
            column_headers[6] = 'Volume'
            column_headers[7] = 'Properties'
        else:
            columns = ['ID', 'Name', 'Description', 'Status', 'Size']
            column_headers = copy.deepcopy(columns)

        # Cache the volume list
        volume_cache = {}
        try:
            for s in volume_client.volumes.list():
                volume_cache[s.id] = s
        except Exception:
            # Just forget it if there's any trouble
            pass
        _VolumeIdColumn = functools.partial(VolumeIdColumn,
                                            volume_cache=volume_cache)

        volume_id = None
        if parsed_args.volume:
            volume_id = utils.find_resource(
                volume_client.volumes, parsed_args.volume).id

        project_id = None
        if parsed_args.project:
            project_id = identity_common.find_project(
                identity_client,
                parsed_args.project,
                parsed_args.project_domain).id

        # set value of 'all_tenants' when using project option
        all_projects = True if parsed_args.project else \
            parsed_args.all_projects

        search_opts = {
            'all_tenants': all_projects,
            'project_id': project_id,
            'name': parsed_args.name,
            'status': parsed_args.status,
            'volume_id': volume_id,
        }

        data = volume_client.volume_snapshots.list(
            search_opts=search_opts,
            marker=parsed_args.marker,
            limit=parsed_args.limit,
        )
        return (column_headers,
                (utils.get_item_properties(
                    s, columns,
                    formatters={'Metadata': format_columns.DictColumn,
                                'Volume ID': _VolumeIdColumn},
                ) for s in data))