def get_parser(self, prog_name):
        parser = super(ListNodeGroup, self).get_parser(prog_name)

        parser.add_argument(
            'cluster',
            metavar='<cluster>',
            help=_('ID or name of the cluster where the nodegroup belongs.'))
        parser.add_argument(
            '--limit',
            metavar='<limit>',
            type=int,
            help=_('Maximum number of nodegroups to return'))
        parser.add_argument(
            '--sort-key',
            metavar='<sort-key>',
            help=_('Column to sort results by'))
        parser.add_argument(
            '--sort-dir',
            metavar='<sort-dir>',
            choices=['desc', 'asc'],
            help=_('Direction to sort. "asc" or "desc".'))
        parser.add_argument(
            '--role',
            metavar='<role>',
            help=_('List the nodegroups in the cluster with this role'))

        return parser
 def get_parser(self, prog_name):
     parser = super(ListTemplateCluster, self).get_parser(prog_name)
     parser.add_argument(
         '--limit',
         metavar='<limit>',
         type=int,
         help=_('Maximum number of cluster templates to return'))
     parser.add_argument(
         '--sort-key',
         metavar='<sort-key>',
         help=_('Column to sort results by'))
     parser.add_argument(
         '--sort-dir',
         metavar='<sort-dir>',
         choices=['desc', 'asc'],
         help=_('Direction to sort. "asc" or "desc".'))
     parser.add_argument(
         '--fields',
         default=None,
         metavar='<fields>',
         help=_('Comma-separated list of fields to display. '
                'Available fields: uuid, name, coe, image_id, public, '
                'link, apiserver_port, server_type, tls_disabled, '
                'registry_enabled'
                )
         )
     return parser
 def get_parser(self, prog_name):
     parser = super(ShowNodeGroup, self).get_parser(prog_name)
     parser.add_argument(
         'cluster',
         metavar='<cluster>',
         help=_('ID or name of the cluster where the nodegroup belongs.'))
     parser.add_argument(
         'nodegroup',
         metavar='<nodegroup>',
         help=_('ID or name of the nodegroup to show.')
         )
     return parser
Example #4
0
def format_labels(lbls, parse_comma=True):
    '''Reformat labels into dict of format expected by the API.'''

    if not lbls:
        return {}

    if parse_comma:
        # expect multiple invocations of --labels but fall back
        # to either , or ; delimited if only one --labels is specified
        if len(lbls) == 1:
            lbls = lbls[0].replace(';', ',').split(',')

    labels = {}
    for l in lbls:
        try:
            (k, v) = l.split(('='), 1)
        except ValueError:
            raise exc.CommandError(_('labels must be a list of KEY=VALUE '
                                     'not %s') % l)
        if k not in labels:
            labels[k] = v
        else:
            if not isinstance(labels[k], list):
                labels[k] = [labels[k]]
            labels[k].append(v)

    return labels
Example #5
0
    def _check_version(self, api_version):
        if api_version == 'latest':
            return LATEST_API_VERSION
        else:
            try:
                versions = tuple(int(i) for i in api_version.split('.'))
            except ValueError:
                versions = ()
            if len(versions) == 1:
                # Default value of magnum_api_version is '1'.
                # If user not specify the value of api version, not passing
                # headers at all.
                magnum_api_version = None
            elif len(versions) == 2:
                magnum_api_version = api_version
                # In the case of '1.0'
                if versions[1] == 0:
                    magnum_api_version = None
            else:
                msg = _("The requested API version %(ver)s is an unexpected "
                        "format. Acceptable formats are 'X', 'X.Y', or the "
                        "literal string '%(latest)s'."
                        ) % {'ver': api_version, 'latest': 'latest'}
                raise exc.CommandError(msg)

            api_major_version = versions[0]
            return (api_major_version, magnum_api_version)
Example #6
0
    def find(self, base_url=None, **kwargs):
        """Find a single item with attributes matching ``**kwargs``.

        :param base_url: if provided, the generated URL will be appended to it
        """
        kwargs = self._filter_kwargs(kwargs)

        rl = self._list(
            '%(base_url)s%(query)s' % {
                'base_url': self.build_url(base_url=base_url, **kwargs),
                'query': '?%s' % parse.urlencode(kwargs) if kwargs else '',
            },
            self.collection_key)
        num = len(rl)

        if num == 0:
            msg = _("No %(name)s matching %(args)s.") % {
                'name': self.resource_class.__name__,
                'args': kwargs
            }
            raise exceptions.NotFound(msg)
        elif num > 1:
            raise exceptions.NoUniqueMatch
        else:
            return rl[0]
    def get_parser(self, prog_name):
        parser = super(ShowClusterTemplate, self).get_parser(prog_name)
        parser.add_argument(
            'cluster-template',
            metavar='<cluster-template>',
            help=_('ID or name of the cluster template to show.'))

        return parser
    def get_parser(self, prog_name):
        parser = super(DeleteClusterTemplate, self).get_parser(prog_name)
        parser.add_argument(
            'cluster-templates',
            metavar='<cluster-templates>',
            nargs='+',
            help=_('ID or name of the (cluster template)s to delete.'))

        return parser
Example #9
0
def handle_json_from_file(json_arg):
    """Attempts to read JSON file by the file url.

    :param json_arg: May be a file name containing the JSON.
    :returns: A list or dictionary parsed from JSON.
    """

    try:
        with open(json_arg, 'r') as f:
            json_arg = f.read().strip()
            json_arg = jsonutils.loads(json_arg)
    except IOError as e:
        err = _("Cannot get JSON from file '%(file)s'. "
                "Error: %(err)s") % {'err': e, 'file': json_arg}
        raise exc.InvalidAttribute(err)
    except ValueError as e:
        err = (_("For JSON: '%(string)s', error: '%(err)s'") %
               {'err': e, 'string': json_arg})
        raise exc.InvalidAttribute(err)

    return json_arg
    def get_parser(self, prog_name):
        parser = super(UpdateClusterTemplate, self).get_parser(prog_name)
        parser.add_argument(
            'cluster-template',
            metavar='<cluster-template>',
            help=_('The name or UUID of cluster template to update'))

        parser.add_argument(
            'op',
            metavar='<op>',
            choices=['add', 'replace', 'remove'],
            help=_("Operations: one of 'add', 'replace' or 'remove'"))

        parser.add_argument(
            'attributes',
            metavar='<path=value>',
            nargs='+',
            action='append',
            default=[],
            help=_(
                "Attributes to add/replace or remove (only PATH is necessary "
                "on remove)"))

        return parser
Example #11
0
def args_array_to_patch(op, attributes):
    patch = []
    for attr in attributes:
        # Sanitize
        if not attr.startswith('/'):
            attr = '/' + attr
        if op in ['add', 'replace']:
            path, value = split_and_deserialize(attr)
            patch.append({'op': op, 'path': path, 'value': value})

        elif op == "remove":
            # For remove only the key is needed
            patch.append({'op': op, 'path': attr})
        else:
            raise exc.CommandError(_('Unknown PATCH operation: %s') % op)
    return patch
Example #12
0
    def find(self, **kwargs):
        """Find a single item with attributes matching ``**kwargs``.

        This isn't very efficient: it loads the entire list then filters on
        the Python side.
        """
        matches = self.findall(**kwargs)
        num_matches = len(matches)
        if num_matches == 0:
            msg = _("No %(name)s matching %(args)s.") % {
                'name': self.resource_class.__name__,
                'args': kwargs
            }
            raise exceptions.NotFound(msg)
        elif num_matches > 1:
            raise exceptions.NoUniqueMatch()
        else:
            return matches[0]
Example #13
0
def split_and_deserialize(string):
    """Split and try to JSON deserialize a string.

    Gets a string with the KEY=VALUE format, split it (using '=' as the
    separator) and try to JSON deserialize the VALUE.
    :returns: A tuple of (key, value).
    """
    try:
        key, value = string.split("=", 1)
    except ValueError:
        raise exc.CommandError(_('Attributes must be a list of '
                                 'PATH=VALUE not "%s"') % string)
    try:
        value = json.loads(value)
    except ValueError:
        pass

    return (key, value)
Example #14
0
class ListStats(command.Command):
    _description = _("Show stats for the given project_id")

    def get_parser(self, prog_name):
        parser = super(ListStats, self).get_parser(prog_name)
        parser.add_argument('project_id',
                            metavar='<project>',
                            help='Project ID')
        return parser

    def take_action(self, parsed_args):
        mag_client = self.app.client_manager.container_infra
        opts = {'project_id': parsed_args.project_id}

        stats = mag_client.stats.list(**opts)
        try:
            utils.print_dict(stats._info)
        except AttributeError:
            return None
class DeleteCluster(command.Command):
    _description = _("Delete a cluster")

    def get_parser(self, prog_name):
        parser = super(DeleteCluster, self).get_parser(prog_name)
        parser.add_argument('cluster',
                            nargs='+',
                            metavar='<cluster>',
                            help='ID or name of the cluster(s) to delete.')

        return parser

    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)

        mag_client = self.app.client_manager.container_infra
        for cluster in parsed_args.cluster:
            mag_client.clusters.delete(cluster)
            print("Request to delete cluster %s has been accepted." % cluster)
class ShowCluster(command.ShowOne):
    _description = _("Show a Cluster")

    def get_parser(self, prog_name):
        parser = super(ShowCluster, self).get_parser(prog_name)
        parser.add_argument('cluster',
                            metavar='<cluster>',
                            help=_('ID or name of the cluster to show.'))
        return parser

    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)

        columns = CLUSTER_ATTRIBUTES

        mag_client = self.app.client_manager.container_infra
        cluster = mag_client.clusters.get(parsed_args.cluster)

        return (columns, utils.get_item_properties(cluster, columns))
Example #17
0
def split_and_deserialize(string):
    """Split and try to JSON deserialize a string.

    Gets a string with the KEY=VALUE format, split it (using '=' as the
    separator) and try to JSON deserialize the VALUE.
    :returns: A tuple of (key, value).
    """
    try:
        key, value = string.split("=", 1)
    except ValueError:
        raise exc.CommandError(
            _('Attributes must be a list of '
              'PATH=VALUE not "%s"') % string)
    try:
        value = json.loads(value)
    except ValueError:
        pass

    return (key, value)
Example #18
0
class UpdateQuotas(command.Command):
    _description = _("Update information about the given "
                     "project resource quota.")

    def get_parser(self, prog_name):
        parser = super(UpdateQuotas, self).get_parser(prog_name)
        parser.add_argument('--project-id',
                            required=True,
                            metavar='<project-id>',
                            help='Project ID')
        parser.add_argument('--resource',
                            required=True,
                            metavar='<resource>',
                            help='Resource name.')
        parser.add_argument('--hard-limit',
                            metavar='<hard-limit>',
                            type=int,
                            default=1,
                            help='Max resource limit (default: hard-limit=1)')
        return parser

    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)

        mag_client = self.app.client_manager.container_infra

        opts = {
            'project_id': parsed_args.project_id,
            'resource': parsed_args.resource,
            'hard_limit': parsed_args.hard_limit
        }
        try:
            quota = mag_client.quotas.update(parsed_args.project_id,
                                             parsed_args.resource, opts)
            _show_quota(quota)
        except Exception as e:
            print("Update quota for project_id %(id)s resource %(res)s failed:"
                  " %(e)s" % {
                      'id': parsed_args.project_id,
                      'res': parsed_args.resource,
                      'e': e
                  })
Example #19
0
class ListQuotas(command.Command):
    _description = _("Print a list of available quotas.")

    def get_parser(self, prog_name):
        parser = super(ListQuotas, self).get_parser(prog_name)
        parser.add_argument('--marker',
                            metavar='<marker>',
                            default=None,
                            help=_('The last quota UUID of the previous page; '
                                   'displays list of quotas after "marker".'))
        parser.add_argument('--limit',
                            metavar='<limit>',
                            type=int,
                            help='Maximum number of quotas to return.')
        parser.add_argument('--sort-key',
                            metavar='<sort-key>',
                            help='Column to sort results by.')
        parser.add_argument('--sort-dir',
                            metavar='<sort-dir>',
                            choices=['desc', 'asc'],
                            help='Direction to sort. "asc" or "desc".')
        parser.add_argument('--all-tenants',
                            action='store_true',
                            default=False,
                            help='Flag to indicate list all tenant quotas.')
        return parser

    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)

        mag_client = self.app.client_manager.container_infra

        quotas = mag_client.quotas.list(marker=parsed_args.marker,
                                        limit=parsed_args.limit,
                                        sort_key=parsed_args.sort_key,
                                        sort_dir=parsed_args.sort_dir,
                                        all_tenants=parsed_args.all_tenants)
        columns = ['project_id', 'resource', 'hard_limit']
        utils.print_list(
            quotas,
            columns, {'versions': magnum_utils.print_list_field('versions')},
            sortby_index=None)
class ListTemplateCluster(command.Lister):
    """List Cluster Templates."""
    _description = _("List Cluster Templates.")

    log = logging.getLogger(__name__ + ".ListTemplateCluster")

    def get_parser(self, prog_name):
        parser = super(ListTemplateCluster, self).get_parser(prog_name)
        parser.add_argument(
            '--limit',
            metavar='<limit>',
            type=int,
            help=_('Maximum number of cluster templates to return'))
        parser.add_argument('--sort-key',
                            metavar='<sort-key>',
                            help=_('Column to sort results by'))
        parser.add_argument('--sort-dir',
                            metavar='<sort-dir>',
                            choices=['desc', 'asc'],
                            help=_('Direction to sort. "asc" or "desc".'))
        parser.add_argument(
            '--fields',
            default=None,
            metavar='<fields>',
            help=_('Comma-separated list of fields to display. '
                   'Available fields: uuid, name, coe, image_id, public, '
                   'link, apiserver_port, server_type, tls_disabled, '
                   'registry_enabled'))
        return parser

    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)

        mag_client = self.app.client_manager.container_infra
        columns = ['uuid', 'name']
        cts = mag_client.cluster_templates.list(limit=parsed_args.limit,
                                                sort_key=parsed_args.sort_key,
                                                sort_dir=parsed_args.sort_dir)
        return (columns, (osc_utils.get_item_properties(ct, columns)
                          for ct in cts))
Example #21
0
def args_array_to_patch(op, attributes):
    patch = []
    for attr in attributes:
        # Sanitize
        if not attr.startswith('/'):
            attr = '/' + attr
        if op in ['add', 'replace']:
            path, value = split_and_deserialize(attr)
            if path == "/labels":
                a = []
                a.append(value)
                value = str(handle_labels(a))
                patch.append({'op': op, 'path': path, 'value': value})
            else:
                patch.append({'op': op, 'path': path, 'value': value})

        elif op == "remove":
            # For remove only the key is needed
            patch.append({'op': op, 'path': attr})
        else:
            raise exc.CommandError(_('Unknown PATCH operation: %s') % op)
    return patch
class ResizeCluster(command.Command):
    _description = _("Resize a Cluster")

    def get_parser(self, prog_name):
        parser = super(ResizeCluster, self).get_parser(prog_name)
        parser.add_argument('cluster',
                            metavar='<cluster>',
                            help=_('The name or UUID of cluster to update'))

        parser.add_argument('node_count',
                            type=int,
                            help=_("Desired node count of the cluser."))

        parser.add_argument(
            '--nodes-to-remove',
            metavar='<Server UUID>',
            action='append',
            help=_("Server ID of the nodes to be removed. Repeat to add"
                   "more server ID"))

        parser.add_argument(
            '--nodegroup',
            metavar='<nodegroup>',
            help=_('The name or UUID of the nodegroup of current cluster.'))

        return parser

    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)

        mag_client = self.app.client_manager.container_infra
        cluster = mag_client.clusters.get(parsed_args.cluster)

        mag_client.clusters.resize(cluster.uuid, parsed_args.node_count,
                                   parsed_args.nodes_to_remove,
                                   parsed_args.nodegroup)
        print("Request to resize cluster %s has been accepted." %
              parsed_args.cluster)
class UpgradeCluster(command.Command):
    _description = _("Upgrade a Cluster")

    def get_parser(self, prog_name):
        parser = super(UpgradeCluster, self).get_parser(prog_name)
        parser.add_argument('cluster',
                            metavar='<cluster>',
                            help=_('The name or UUID of cluster to update'))

        parser.add_argument(
            'cluster_template',
            help=_("The new cluster template ID will be upgraded to."))

        parser.add_argument(
            '--max-batch-size',
            metavar='<max_batch_size>',
            type=int,
            default=1,
            help=_("The max batch size for upgrading each time."))

        parser.add_argument(
            '--nodegroup',
            metavar='<nodegroup>',
            help=_('The name or UUID of the nodegroup of current cluster.'))

        return parser

    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)

        mag_client = self.app.client_manager.container_infra
        cluster = mag_client.clusters.get(parsed_args.cluster)

        mag_client.clusters.upgrade(cluster.uuid, parsed_args.cluster_template,
                                    parsed_args.max_batch_size,
                                    parsed_args.nodegroup)
        print("Request to upgrade cluster %s has been accepted." %
              parsed_args.cluster)
Example #24
0
 def get_parser(self, prog_name):
     parser = super(ListQuotas, self).get_parser(prog_name)
     parser.add_argument('--marker',
                         metavar='<marker>',
                         default=None,
                         help=_('The last quota UUID of the previous page; '
                                'displays list of quotas after "marker".'))
     parser.add_argument('--limit',
                         metavar='<limit>',
                         type=int,
                         help='Maximum number of quotas to return.')
     parser.add_argument('--sort-key',
                         metavar='<sort-key>',
                         help='Column to sort results by.')
     parser.add_argument('--sort-dir',
                         metavar='<sort-dir>',
                         choices=['desc', 'asc'],
                         help='Direction to sort. "asc" or "desc".')
     parser.add_argument('--all-tenants',
                         action='store_true',
                         default=False,
                         help='Flag to indicate list all tenant quotas.')
     return parser
class ShowClusterTemplate(command.ShowOne):
    """Show a Cluster Template."""
    _description = _("Show a Cluster Template.")

    log = logging.getLogger(__name__ + ".ShowClusterTemplate")

    def get_parser(self, prog_name):
        parser = super(ShowClusterTemplate, self).get_parser(prog_name)
        parser.add_argument(
            'cluster-template',
            metavar='<cluster-template>',
            help=_('ID or name of the cluster template to show.'))

        return parser

    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)

        mag_client = self.app.client_manager.container_infra
        ct = getattr(parsed_args, 'cluster-template', None)
        cluster_template = mag_client.cluster_templates.get(ct)

        return _show_cluster_template(cluster_template)
Example #26
0
 def get_parser(self, prog_name):
     parser = super(ListQuotas, self).get_parser(prog_name)
     parser.add_argument('--marker',
                         metavar='<marker>',
                         default=None,
                         help=_('The last quota UUID of the previous page; '
                                'displays list of quotas after "marker".'))
     parser.add_argument('--limit',
                         metavar='<limit>',
                         type=int,
                         help='Maximum number of quotas to return.')
     parser.add_argument('--sort-key',
                         metavar='<sort-key>',
                         help='Column to sort results by.')
     parser.add_argument('--sort-dir',
                         metavar='<sort-dir>',
                         choices=['desc', 'asc'],
                         help='Direction to sort. "asc" or "desc".')
     parser.add_argument('--all-tenants',
                         action='store_true',
                         default=False,
                         help='Flag to indicate list all tenant quotas.')
     return parser
Example #27
0
class ShowQuotas(command.Command):
    _description = _("Show details about the given project resource quota.")

    def get_parser(self, prog_name):
        parser = super(ShowQuotas, self).get_parser(prog_name)
        parser.add_argument('--project-id',
                            required=True,
                            metavar='<project-id>',
                            help='Project ID')
        parser.add_argument('--resource',
                            required=True,
                            metavar='<resource>',
                            help='Resource name.')
        return parser

    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)

        mag_client = self.app.client_manager.container_infra
        project_id = parsed_args.project_id
        resource = parsed_args.resource
        quota = mag_client.quotas.get(project_id, resource)
        _show_quota(quota)
class HttpError(ClientException):
    """The base exception class for all HTTP exceptions."""
    http_status = 0
    message = _("HTTP Error")

    def __init__(self,
                 message=None,
                 details=None,
                 response=None,
                 request_id=None,
                 url=None,
                 method=None,
                 http_status=None):
        self.http_status = http_status or self.http_status
        self.message = message or self.message
        self.details = details
        self.request_id = request_id
        self.response = response
        self.url = url
        self.method = method
        formatted_string = "%s (HTTP %s)" % (self.message, self.http_status)
        if request_id:
            formatted_string += " (Request-ID: %s)" % request_id
        super(HttpError, self).__init__(formatted_string)
Example #29
0
    def find(self, base_url=None, **kwargs):
        """Find a single item with attributes matching ``**kwargs``.

        :param base_url: if provided, the generated URL will be appended to it
        """
        kwargs = self._filter_kwargs(kwargs)

        rl = self._list(
            '%(base_url)s%(query)s' % {
                'base_url': self.build_url(base_url=base_url, **kwargs),
                'query': '?%s' % parse.urlencode(kwargs) if kwargs else '',
            }, self.collection_key)
        num = len(rl)

        if num == 0:
            msg = _("No %(name)s matching %(args)s.") % {
                'name': self.resource_class.__name__,
                'args': kwargs
            }
            raise exceptions.NotFound(msg)
        elif num > 1:
            raise exceptions.NoUniqueMatch
        else:
            return rl[0]
Example #30
0
class ListCluster(command.Lister):
    _description = _("List clusters")

    def get_parser(self, prog_name):
        parser = super(ListCluster, self).get_parser(prog_name)

        parser.add_argument(
            '--limit',
            metavar='<limit>',
            type=int,
            help=_('Maximum number of clusters to return'))
        parser.add_argument(
            '--sort-key',
            metavar='<sort-key>',
            help=_('Column to sort results by'))
        parser.add_argument(
            '--sort-dir',
            metavar='<sort-dir>',
            choices=['desc', 'asc'],
            help=_('Direction to sort. "asc" or "desc".'))

        return parser

    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)

        mag_client = self.app.client_manager.container_infra
        columns = [
            'uuid', 'name', 'keypair', 'node_count', 'master_count', 'status']
        clusters = mag_client.clusters.list(limit=parsed_args.limit,
                                            sort_key=parsed_args.sort_key,
                                            sort_dir=parsed_args.sort_dir)
        return (
            columns,
            (utils.get_item_properties(c, columns) for c in clusters)
        )
@utils.arg('--limit',
           metavar='<limit>',
           type=int,
           help='Maximum number of baymodels to return')
@utils.arg('--sort-key',
           metavar='<sort-key>',
           help='Column to sort results by')
@utils.arg('--sort-dir',
           metavar='<sort-dir>',
           choices=['desc', 'asc'],
           help='Direction to sort. "asc" or "desc".')
@utils.arg('--fields',
           default=None,
           metavar='<fields>',
           help=_('Comma-separated list of fields to display. '
                  'Available fields: uuid, name, coe, image_id, public, link, '
                  'apiserver_port, server_type, tls_disabled, registry_enabled'
                  )
           )
def do_baymodel_list(cs, args):
    """Print a list of baymodels."""
    nodes = cs.baymodels.list(limit=args.limit,
                              sort_key=args.sort_key,
                              sort_dir=args.sort_dir)
    columns = ['uuid', 'name']
    columns += utils._get_list_table_columns_and_formatters(
        args.fields, nodes,
        exclude_fields=(c.lower() for c in columns))[0]
    utils.print_list(nodes, columns,
                     {'versions': magnum_utils.print_list_field('versions')},
                     sortby_index=None)
@utils.arg('--limit',
           metavar='<limit>',
           type=int,
           help='Maximum number of baymodels to return')
@utils.arg('--sort-key',
           metavar='<sort-key>',
           help='Column to sort results by')
@utils.arg('--sort-dir',
           metavar='<sort-dir>',
           choices=['desc', 'asc'],
           help='Direction to sort. "asc" or "desc".')
@utils.arg('--fields',
           default=None,
           metavar='<fields>',
           help=_('Comma-separated list of fields to display. '
                  'Available fields: uuid, name, coe, image_id, public, link, '
                  'apiserver_port, server_type, tls_disabled, registry_enabled'
                  )
           )
@utils.deprecated(DEPRECATION_MESSAGE)
def do_baymodel_list(cs, args):
    """Print a list of baymodels."""
    nodes = cs.baymodels.list(limit=args.limit,
                              sort_key=args.sort_key,
                              sort_dir=args.sort_dir)
    columns = ['uuid', 'name']
    columns += utils._get_list_table_columns_and_formatters(
        args.fields, nodes,
        exclude_fields=(c.lower() for c in columns))[0]
    utils.print_list(nodes, columns,
                     {'versions': magnum_utils.print_list_field('versions')},
                     sortby_index=None)
 def __init__(self, opt_names):
     super(AuthPluginOptionsMissing, self).__init__(
         _("Authentication failed. Missing options: %s") %
         ", ".join(opt_names))
     self.opt_names = opt_names
 def __init__(self, auth_system):
     super(AuthSystemNotFound,
           self).__init__(_("AuthSystemNotFound: %r") % auth_system)
     self.auth_system = auth_system
Example #35
0
    def get_parser(self, prog_name):
        parser = super(CreateCluster, self).get_parser(prog_name)
        # NOTE: All arguments are positional and, if not provided
        # with a default, required.
        parser.add_argument('--cluster-template',
                            dest='cluster_template',
                            required=True,
                            metavar='<cluster-template>',
                            help='ID or name of the cluster template.')
        parser.add_argument('--discovery-url',
                            dest='discovery_url',
                            metavar='<discovery-url>',
                            help=('Specifies custom delivery url for '
                                  'node discovery.'))
        parser.add_argument('--docker-volume-size',
                            dest='docker_volume_size',
                            type=int,
                            metavar='<docker-volume-size>',
                            help=('The size in GB for the docker volume to '
                                  'use.'))
        parser.add_argument('--labels',
                            metavar='<KEY1=VALUE1,KEY2=VALUE2;KEY3=VALUE3...>',
                            action='append',
                            help=_('Arbitrary labels in the form of key=value'
                                   'pairs to associate with a cluster '
                                   'template. May be used multiple times.'))
        parser.add_argument('--keypair',
                            default=None,
                            metavar='<keypair>',
                            help='UUID or name of the keypair to use.')
        parser.add_argument('--master-count',
                            dest='master_count',
                            type=int,
                            default=1,
                            metavar='<master-count>',
                            help='The number of master nodes for the cluster.')
        parser.add_argument('name',
                            metavar='<name>',
                            help='Name of the cluster to create.')
        parser.add_argument('--node-count',
                            dest='node_count',
                            type=int,
                            default=1,
                            metavar='<node-count>',
                            help='The cluster node count.')
        parser.add_argument('--timeout',
                            type=int,
                            default=60,
                            metavar='<timeout>',
                            help=('The timeout for cluster creation time. The '
                                  'default is 60 minutes.'))
        parser.add_argument(
            '--master-flavor',
            dest='master_flavor',
            metavar='<master-flavor>',
            help=_('The nova flavor name or UUID to use when launching the '
                   'master node of the Cluster.'))
        parser.add_argument(
            '--flavor',
            metavar='<flavor>',
            help=_('The nova flavor name or UUID to use when launching the '
                   'Cluster.'))

        return parser
    def get_parser(self, prog_name):
        parser = super(CreateClusterTemplate, self).get_parser(prog_name)

        parser.add_argument(
            'name',
            metavar='<name>',
            help=_('Name of the cluster template to create.'))
        parser.add_argument(
            '--coe',
            required=True,
            metavar='<coe>',
            help=_('Specify the Container Orchestration Engine to use.'))
        parser.add_argument(
            '--image',
            required=True,
            metavar='<image>',
            help=_('The name or UUID of the base image to customize for the '
                   'Cluster.'))
        parser.add_argument(
            '--external-network',
            dest='external_network',
            required=True,
            metavar='<external-network>',
            help=_('The external Neutron network name or UUID to connect to '
                   'this Cluster Template.'))
        parser.add_argument(
            '--keypair',
            metavar='<keypair>',
            help=_('The name or UUID of the SSH keypair to load into the '
                   'Cluster nodes.'))
        parser.add_argument(
            '--fixed-network',
            dest='fixed_network',
            metavar='<fixed-network>',
            help=_('The private Neutron network name to connect to this '
                   'Cluster model.'))
        parser.add_argument(
            '--fixed-subnet',
            dest='fixed_subnet',
            metavar='<fixed-subnet>',
            help=_('The private Neutron subnet name to connect to Cluster.'))
        parser.add_argument(
            '--network-driver',
            dest='network_driver',
            metavar='<network-driver>',
            help=_('The network driver name for instantiating container '
                   'networks.'))
        parser.add_argument(
            '--volume-driver',
            dest='volume_driver',
            metavar='<volume-driver>',
            help=_('The volume driver name for instantiating container '
                   'volume.'))
        parser.add_argument(
            '--dns-nameserver',
            dest='dns_nameserver',
            metavar='<dns-nameserver>',
            default='8.8.8.8',
            help=_('The DNS nameserver to use for this cluster template.'))
        parser.add_argument(
            '--flavor',
            metavar='<flavor>',
            default='m1.medium',
            help=_('The nova flavor name or UUID to use when launching the '
                   'Cluster.'))
        parser.add_argument(
            '--master-flavor',
            dest='master_flavor',
            metavar='<master-flavor>',
            help=_('The nova flavor name or UUID to use when launching the '
                   'master node of the Cluster.'))
        parser.add_argument(
            '--docker-volume-size',
            dest='docker_volume_size',
            metavar='<docker-volume-size>',
            type=int,
            help=_('Specify the number of size in GB for the docker volume '
                   'to use.'))
        parser.add_argument(
            '--docker-storage-driver',
            dest='docker_storage_driver',
            metavar='<docker-storage-driver>',
            default='devicemapper',
            help=_('Select a docker storage driver. Supported: devicemapper, '
                   'overlay. Default: devicemapper'))
        parser.add_argument(
            '--http-proxy',
            dest='http_proxy',
            metavar='<http-proxy>',
            help=_('The http_proxy address to use for nodes in Cluster.'))
        parser.add_argument(
            '--https-proxy',
            dest='https_proxy',
            metavar='<https-proxy>',
            help=_('The https_proxy address to use for nodes in Cluster.'))
        parser.add_argument(
            '--no-proxy',
            dest='no_proxy',
            metavar='<no-proxy>',
            help=_('The no_proxy address to use for nodes in Cluster.'))
        parser.add_argument(
            '--labels',
            metavar='<KEY1=VALUE1,KEY2=VALUE2;KEY3=VALUE3...>',
            action='append',
            default=[],
            help=_('Arbitrary labels in the form of key=value pairs to '
                   'associate with a cluster template. May be used multiple '
                   'times.'))
        parser.add_argument(
            '--tls-disabled',
            dest='tls_disabled',
            action='store_true',
            default=False,
            help=_('Disable TLS in the Cluster.'))
        parser.add_argument(
            '--public',
            action='store_true',
            default=False,
            help=_('Make cluster template public.'))
        parser.add_argument(
            '--registry-enabled',
            dest='registry_enabled',
            action='store_true',
            default=False,
            help=_('Enable docker registry in the Cluster'))
        parser.add_argument(
            '--server-type',
            dest='server_type',
            metavar='<server-type>',
            default='vm',
            help=_('Specify the server type to be used for example vm. '
                   'For this release default server type will be vm.'))
        parser.add_argument(
            '--master-lb-enabled',
            dest='master_lb_enabled',
            action='store_true',
            default=False,
            help=_('Indicates whether created Clusters should have a load '
                   'balancer for master nodes or not.'))
        parser.add_argument(
            '--floating-ip-enabled',
            dest='floating_ip_enabled',
            default=[],
            action='append_const',
            const=True,
            help=_('Indicates whether created Clusters should have a '
                   'floating ip.'))
        parser.add_argument(
            '--floating-ip-disabled',
            dest='floating_ip_enabled',
            action='append_const',
            const=False,
            help=_('Disables floating ip creation on the new Cluster'))
        parser.add_argument(
            '--hidden',
            dest='hidden',
            action='store_true',
            default=False,
            help=_('Indicates the cluster template should be hidden.'))
        parser.add_argument(
            '--visible',
            dest='hidden',
            action='store_false',
            help=_('Indicates the cluster template should be visible.'))

        return parser
 def __init__(self, endpoints=None):
     super(AmbiguousEndpoints,
           self).__init__(_("AmbiguousEndpoints: %r") % endpoints)
     self.endpoints = endpoints
@utils.arg('--limit',
           metavar='<limit>',
           type=int,
           help='Maximum number of bays to return.')
@utils.arg('--sort-key',
           metavar='<sort-key>',
           help='Column to sort results by.')
@utils.arg('--sort-dir',
           metavar='<sort-dir>',
           choices=['desc', 'asc'],
           help='Direction to sort. "asc" or "desc".')
@utils.arg('--fields',
           default=None,
           metavar='<fields>',
           help=_('Comma-separated list of fields to display. '
                  'Available fields: uuid, name, baymodel_id, stack_id, '
                  'status, master_count, node_count, links, bay_create_timeout'
                  )
           )
def do_bay_list(cs, args):
    """Print a list of available bays."""
    bays = cs.bays.list(marker=args.marker, limit=args.limit,
                        sort_key=args.sort_key,
                        sort_dir=args.sort_dir)
    columns = ['uuid', 'name', 'node_count', 'master_count', 'status']
    columns += utils._get_list_table_columns_and_formatters(
        args.fields, bays,
        exclude_fields=(c.lower() for c in columns))[0]
    utils.print_list(bays, columns,
                     {'versions': magnum_utils.print_list_field('versions')},
                     sortby_index=None)

DEPRECATION_MESSAGE = (
    'WARNING: Bay commands are deprecated and will be removed in a future '
    'release.\nUse cluster commands to avoid seeing this message.')


def _show_bay(bay):
    del bay._info['links']
    utils.print_dict(bay._info)


@utils.arg('--marker',
           metavar='<marker>',
           default=None,
           help=_('The last bay UUID of the previous page; '
                  'displays list of bays after "marker".'))
@utils.arg('--limit',
           metavar='<limit>',
           type=int,
           help=_('Maximum number of bays to return.'))
@utils.arg('--sort-key',
           metavar='<sort-key>',
           help=_('Column to sort results by.'))
@utils.arg('--sort-dir',
           metavar='<sort-dir>',
           choices=['desc', 'asc'],
           help=_('Direction to sort. "asc" or "desc".'))
@utils.arg('--fields',
           default=None,
           metavar='<fields>',
           help=_('Comma-separated list of fields to display. '
Example #40
0
    def get_base_parser(self):
        parser = MagnumClientArgumentParser(
            prog='magnum',
            description=__doc__.strip(),
            epilog='See "magnum help COMMAND" '
                   'for help on a specific command.',
            add_help=False,
            formatter_class=OpenStackHelpFormatter,
        )

        # Global arguments
        parser.add_argument('-h', '--help',
                            action='store_true',
                            help=argparse.SUPPRESS)

        parser.add_argument('--version',
                            action='version',
                            version=version.version_info.version_string())

        parser.add_argument('--debug',
                            default=False,
                            action='store_true',
                            help=_("Print debugging output."))

        parser.add_argument('--os-cache',
                            default=strutils.bool_from_string(
                                cliutils.env('OS_CACHE', default=False)),
                            action='store_true',
                            help=_("Use the auth token cache. Defaults to "
                                   "False if env[OS_CACHE] is not set."))

        parser.add_argument('--os-region-name',
                            metavar='<region-name>',
                            default=os.environ.get('OS_REGION_NAME'),
                            help=_('Region name. '
                                   'Default=env[OS_REGION_NAME].'))


# TODO(mattf) - add get_timings support to Client
#        parser.add_argument('--timings',
#            default=False,
#            action='store_true',
#            help="Print call timing info")

# TODO(mattf) - use timeout
#        parser.add_argument('--timeout',
#            default=600,
#            metavar='<seconds>',
#            type=positive_non_zero_float,
#            help="Set HTTP call timeout (in seconds)")

        parser.add_argument('--os-auth-url',
                            metavar='<auth-auth-url>',
                            default=cliutils.env('OS_AUTH_URL', default=None),
                            help=_('Defaults to env[OS_AUTH_URL].'))

        parser.add_argument('--os-user-id',
                            metavar='<auth-user-id>',
                            default=cliutils.env('OS_USER_ID', default=None),
                            help=_('Defaults to env[OS_USER_ID].'))

        parser.add_argument('--os-username',
                            metavar='<auth-username>',
                            default=cliutils.env('OS_USERNAME', default=None),
                            help=_('Defaults to env[OS_USERNAME].'))

        parser.add_argument('--os-user-domain-id',
                            metavar='<auth-user-domain-id>',
                            default=cliutils.env('OS_USER_DOMAIN_ID',
                                                 default=None),
                            help=_('Defaults to env[OS_USER_DOMAIN_ID].'))

        parser.add_argument('--os-user-domain-name',
                            metavar='<auth-user-domain-name>',
                            default=cliutils.env('OS_USER_DOMAIN_NAME',
                                                 default=None),
                            help=_('Defaults to env[OS_USER_DOMAIN_NAME].'))

        parser.add_argument('--os-project-id',
                            metavar='<auth-project-id>',
                            default=cliutils.env('OS_PROJECT_ID',
                                                 default=None),
                            help=_('Defaults to env[OS_PROJECT_ID].'))

        parser.add_argument('--os-project-name',
                            metavar='<auth-project-name>',
                            default=cliutils.env('OS_PROJECT_NAME',
                                                 default=None),
                            help=_('Defaults to env[OS_PROJECT_NAME].'))

        parser.add_argument('--os-tenant-id',
                            metavar='<auth-tenant-id>',
                            default=cliutils.env('OS_TENANT_ID',
                                                 default=None),
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-tenant-name',
                            metavar='<auth-tenant-name>',
                            default=cliutils.env('OS_TENANT_NAME',
                                                 default=None),
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-project-domain-id',
                            metavar='<auth-project-domain-id>',
                            default=cliutils.env('OS_PROJECT_DOMAIN_ID',
                                                 default=None),
                            help=_('Defaults to env[OS_PROJECT_DOMAIN_ID].'))

        parser.add_argument('--os-project-domain-name',
                            metavar='<auth-project-domain-name>',
                            default=cliutils.env('OS_PROJECT_DOMAIN_NAME',
                                                 default=None),
                            help=_('Defaults to '
                                   'env[OS_PROJECT_DOMAIN_NAME].'))

        parser.add_argument('--os-token',
                            metavar='<auth-token>',
                            default=cliutils.env('OS_TOKEN', default=None),
                            help=_('Defaults to env[OS_TOKEN].'))

        parser.add_argument('--os-password',
                            metavar='<auth-password>',
                            default=cliutils.env('OS_PASSWORD',
                                                 default=None),
                            help=_('Defaults to env[OS_PASSWORD].'))

        parser.add_argument('--service-type',
                            metavar='<service-type>',
                            help=_('Defaults to container-infra for all '
                                   'actions.'))
        parser.add_argument('--service_type',
                            help=argparse.SUPPRESS)

        parser.add_argument('--endpoint-type',
                            metavar='<endpoint-type>',
                            default=cliutils.env('OS_ENDPOINT_TYPE',
                                                 default=None),
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-endpoint-type',
                            metavar='<os-endpoint-type>',
                            default=cliutils.env('OS_ENDPOINT_TYPE',
                                                 default=None),
                            help=_('Defaults to env[OS_ENDPOINT_TYPE]'))

        parser.add_argument('--os-interface',
                            metavar='<os-interface>',
                            default=cliutils.env(
                                'OS_INTERFACE',
                                default=DEFAULT_INTERFACE),
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-cloud',
                            metavar='<auth-cloud>',
                            default=cliutils.env('OS_CLOUD', default=None),
                            help=_('Defaults to env[OS_CLOUD].'))

        # NOTE(dtroyer): We can't add --endpoint_type here due to argparse
        #                thinking usage-list --end is ambiguous; but it
        #                works fine with only --endpoint-type present
        #                Go figure.  I'm leaving this here for doc purposes.
        # parser.add_argument('--endpoint_type',
        #    help=argparse.SUPPRESS)

        parser.add_argument('--magnum-api-version',
                            metavar='<magnum-api-ver>',
                            default=cliutils.env(
                                'MAGNUM_API_VERSION',
                                default='latest'),
                            help=_('Accepts "api", '
                                   'defaults to env[MAGNUM_API_VERSION].'))
        parser.add_argument('--magnum_api_version',
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-cacert',
                            metavar='<ca-certificate>',
                            default=cliutils.env('OS_CACERT', default=None),
                            help=_('Specify a CA bundle file to use in '
                                   'verifying a TLS (https) server '
                                   'certificate. Defaults to env[OS_CACERT].'))

        parser.add_argument('--os-endpoint-override',
                            metavar='<endpoint-override>',
                            default=cliutils.env('OS_ENDPOINT_OVERRIDE',
                                                 default=None),
                            help=_("Use this API endpoint instead of the "
                                   "Service Catalog."))
        parser.add_argument('--bypass-url',
                            metavar='<bypass-url>',
                            default=cliutils.env('BYPASS_URL', default=None),
                            dest='bypass_url',
                            help=argparse.SUPPRESS)
        parser.add_argument('--bypass_url',
                            help=argparse.SUPPRESS)

        parser.add_argument('--insecure',
                            default=cliutils.env('MAGNUMCLIENT_INSECURE',
                                                 default=False),
                            action='store_true',
                            help=_("Do not verify https connections"))

        if profiler:
            parser.add_argument('--profile',
                                metavar='HMAC_KEY',
                                default=cliutils.env('OS_PROFILE',
                                                     default=None),
                                help='HMAC key to use for encrypting context '
                                'data for performance profiling of operation. '
                                'This key should be the value of the HMAC key '
                                'configured for the OSprofiler middleware in '
                                'magnum; it is specified in the Magnum '
                                'configuration file at '
                                '"/etc/magnum/magnum.conf". '
                                'Without the key, profiling will not be '
                                'triggered even if OSprofiler is enabled on '
                                'the server side.')

        return parser
Example #41
0
    def get_base_parser(self):
        parser = MagnumClientArgumentParser(
            prog='magnum',
            description=__doc__.strip(),
            epilog='See "magnum help COMMAND" '
            'for help on a specific command.',
            add_help=False,
            formatter_class=OpenStackHelpFormatter,
        )

        # Global arguments
        parser.add_argument('-h',
                            '--help',
                            action='store_true',
                            help=argparse.SUPPRESS)

        parser.add_argument('--version',
                            action='version',
                            version=version.version_info.version_string())

        parser.add_argument('--debug',
                            default=False,
                            action='store_true',
                            help=_("Print debugging output."))

        parser.add_argument('--os-cache',
                            default=strutils.bool_from_string(
                                cliutils.env('OS_CACHE', default=False)),
                            action='store_true',
                            help=_("Use the auth token cache. Defaults to "
                                   "False if env[OS_CACHE] is not set."))

        parser.add_argument('--os-region-name',
                            metavar='<region-name>',
                            default=os.environ.get('OS_REGION_NAME'),
                            help=_('Region name. '
                                   'Default=env[OS_REGION_NAME].'))

        # TODO(mattf) - add get_timings support to Client
        #        parser.add_argument('--timings',
        #            default=False,
        #            action='store_true',
        #            help="Print call timing info")

        # TODO(mattf) - use timeout
        #        parser.add_argument('--timeout',
        #            default=600,
        #            metavar='<seconds>',
        #            type=positive_non_zero_float,
        #            help="Set HTTP call timeout (in seconds)")

        parser.add_argument('--os-auth-url',
                            metavar='<auth-auth-url>',
                            default=cliutils.env('OS_AUTH_URL', default=None),
                            help=_('Defaults to env[OS_AUTH_URL].'))

        parser.add_argument('--os-user-id',
                            metavar='<auth-user-id>',
                            default=cliutils.env('OS_USER_ID', default=None),
                            help=_('Defaults to env[OS_USER_ID].'))

        parser.add_argument('--os-username',
                            metavar='<auth-username>',
                            default=cliutils.env('OS_USERNAME', default=None),
                            help=_('Defaults to env[OS_USERNAME].'))

        parser.add_argument('--os-user-domain-id',
                            metavar='<auth-user-domain-id>',
                            default=cliutils.env('OS_USER_DOMAIN_ID',
                                                 default=None),
                            help=_('Defaults to env[OS_USER_DOMAIN_ID].'))

        parser.add_argument('--os-user-domain-name',
                            metavar='<auth-user-domain-name>',
                            default=cliutils.env('OS_USER_DOMAIN_NAME',
                                                 default=None),
                            help=_('Defaults to env[OS_USER_DOMAIN_NAME].'))

        parser.add_argument('--os-project-id',
                            metavar='<auth-project-id>',
                            default=cliutils.env('OS_PROJECT_ID',
                                                 default=None),
                            help=_('Defaults to env[OS_PROJECT_ID].'))

        parser.add_argument('--os-project-name',
                            metavar='<auth-project-name>',
                            default=cliutils.env('OS_PROJECT_NAME',
                                                 default=None),
                            help=_('Defaults to env[OS_PROJECT_NAME].'))

        parser.add_argument('--os-tenant-id',
                            metavar='<auth-tenant-id>',
                            default=cliutils.env('OS_TENANT_ID', default=None),
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-tenant-name',
                            metavar='<auth-tenant-name>',
                            default=cliutils.env('OS_TENANT_NAME',
                                                 default=None),
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-project-domain-id',
                            metavar='<auth-project-domain-id>',
                            default=cliutils.env('OS_PROJECT_DOMAIN_ID',
                                                 default=None),
                            help=_('Defaults to env[OS_PROJECT_DOMAIN_ID].'))

        parser.add_argument('--os-project-domain-name',
                            metavar='<auth-project-domain-name>',
                            default=cliutils.env('OS_PROJECT_DOMAIN_NAME',
                                                 default=None),
                            help=_('Defaults to '
                                   'env[OS_PROJECT_DOMAIN_NAME].'))

        parser.add_argument('--os-token',
                            metavar='<auth-token>',
                            default=cliutils.env('OS_TOKEN', default=None),
                            help=_('Defaults to env[OS_TOKEN].'))

        parser.add_argument('--os-password',
                            metavar='<auth-password>',
                            default=cliutils.env('OS_PASSWORD', default=None),
                            help=_('Defaults to env[OS_PASSWORD].'))

        parser.add_argument('--service-type',
                            metavar='<service-type>',
                            help=_('Defaults to container-infra for all '
                                   'actions.'))
        parser.add_argument('--service_type', help=argparse.SUPPRESS)

        parser.add_argument('--endpoint-type',
                            metavar='<endpoint-type>',
                            default=cliutils.env('OS_ENDPOINT_TYPE',
                                                 default=None),
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-endpoint-type',
                            metavar='<os-endpoint-type>',
                            default=cliutils.env('OS_ENDPOINT_TYPE',
                                                 default=None),
                            help=_('Defaults to env[OS_ENDPOINT_TYPE]'))

        parser.add_argument('--os-interface',
                            metavar='<os-interface>',
                            default=cliutils.env('OS_INTERFACE',
                                                 default=DEFAULT_INTERFACE),
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-cloud',
                            metavar='<auth-cloud>',
                            default=cliutils.env('OS_CLOUD', default=None),
                            help=_('Defaults to env[OS_CLOUD].'))

        # NOTE(dtroyer): We can't add --endpoint_type here due to argparse
        #                thinking usage-list --end is ambiguous; but it
        #                works fine with only --endpoint-type present
        #                Go figure.  I'm leaving this here for doc purposes.
        # parser.add_argument('--endpoint_type',
        #    help=argparse.SUPPRESS)

        parser.add_argument('--magnum-api-version',
                            metavar='<magnum-api-ver>',
                            default=cliutils.env('MAGNUM_API_VERSION',
                                                 default='latest'),
                            help=_('Accepts "api", '
                                   'defaults to env[MAGNUM_API_VERSION].'))
        parser.add_argument('--magnum_api_version', help=argparse.SUPPRESS)

        parser.add_argument('--os-cacert',
                            metavar='<ca-certificate>',
                            default=cliutils.env('OS_CACERT', default=None),
                            help=_('Specify a CA bundle file to use in '
                                   'verifying a TLS (https) server '
                                   'certificate. Defaults to env[OS_CACERT].'))

        parser.add_argument('--os-endpoint-override',
                            metavar='<endpoint-override>',
                            default=cliutils.env('OS_ENDPOINT_OVERRIDE',
                                                 default=None),
                            help=_("Use this API endpoint instead of the "
                                   "Service Catalog."))
        parser.add_argument('--bypass-url',
                            metavar='<bypass-url>',
                            default=cliutils.env('BYPASS_URL', default=None),
                            dest='bypass_url',
                            help=argparse.SUPPRESS)
        parser.add_argument('--bypass_url', help=argparse.SUPPRESS)

        parser.add_argument('--insecure',
                            default=cliutils.env('MAGNUMCLIENT_INSECURE',
                                                 default=False),
                            action='store_true',
                            help=_("Do not verify https connections"))

        if profiler:
            parser.add_argument('--profile',
                                metavar='HMAC_KEY',
                                help='HMAC key to use for encrypting context '
                                'data for performance profiling of operation. '
                                'This key should be the value of the HMAC key '
                                'configured for the OSprofiler middleware in '
                                'nova; it is specified in the Nova '
                                'configuration file at "/etc/nova/nova.conf". '
                                'Without the key, profiling will not be '
                                'triggered even if OSprofiler is enabled on '
                                'the server side.')

        return parser
Example #42
0
class OpenStackMagnumShell(object):
    def get_base_parser(self):
        parser = MagnumClientArgumentParser(
            prog='magnum',
            description=__doc__.strip(),
            epilog='See "magnum help COMMAND" '
            'for help on a specific command.',
            add_help=False,
            formatter_class=OpenStackHelpFormatter,
        )

        # Global arguments
        parser.add_argument('-h',
                            '--help',
                            action='store_true',
                            help=argparse.SUPPRESS)

        parser.add_argument('--version',
                            action='version',
                            version=version.version_info.version_string())

        parser.add_argument('--debug',
                            default=False,
                            action='store_true',
                            help=_("Print debugging output."))

        parser.add_argument('--os-cache',
                            default=strutils.bool_from_string(
                                cliutils.env('OS_CACHE', default=False)),
                            action='store_true',
                            help=_("Use the auth token cache. Defaults to "
                                   "False if env[OS_CACHE] is not set."))

        parser.add_argument('--os-region-name',
                            metavar='<region-name>',
                            default=os.environ.get('OS_REGION_NAME'),
                            help=_('Region name. '
                                   'Default=env[OS_REGION_NAME].'))

        # TODO(mattf) - add get_timings support to Client
        #        parser.add_argument('--timings',
        #            default=False,
        #            action='store_true',
        #            help="Print call timing info")

        # TODO(mattf) - use timeout
        #        parser.add_argument('--timeout',
        #            default=600,
        #            metavar='<seconds>',
        #            type=positive_non_zero_float,
        #            help="Set HTTP call timeout (in seconds)")

        parser.add_argument('--os-auth-url',
                            metavar='<auth-auth-url>',
                            default=cliutils.env('OS_AUTH_URL', default=None),
                            help=_('Defaults to env[OS_AUTH_URL].'))

        parser.add_argument('--os-user-id',
                            metavar='<auth-user-id>',
                            default=cliutils.env('OS_USER_ID', default=None),
                            help=_('Defaults to env[OS_USER_ID].'))

        parser.add_argument('--os-username',
                            metavar='<auth-username>',
                            default=cliutils.env('OS_USERNAME', default=None),
                            help=_('Defaults to env[OS_USERNAME].'))

        parser.add_argument('--os-user-domain-id',
                            metavar='<auth-user-domain-id>',
                            default=cliutils.env('OS_USER_DOMAIN_ID',
                                                 default=None),
                            help=_('Defaults to env[OS_USER_DOMAIN_ID].'))

        parser.add_argument('--os-user-domain-name',
                            metavar='<auth-user-domain-name>',
                            default=cliutils.env('OS_USER_DOMAIN_NAME',
                                                 default=None),
                            help=_('Defaults to env[OS_USER_DOMAIN_NAME].'))

        parser.add_argument('--os-project-id',
                            metavar='<auth-project-id>',
                            default=cliutils.env('OS_PROJECT_ID',
                                                 default=None),
                            help=_('Defaults to env[OS_PROJECT_ID].'))

        parser.add_argument('--os-project-name',
                            metavar='<auth-project-name>',
                            default=cliutils.env('OS_PROJECT_NAME',
                                                 default=None),
                            help=_('Defaults to env[OS_PROJECT_NAME].'))

        parser.add_argument('--os-tenant-id',
                            metavar='<auth-tenant-id>',
                            default=cliutils.env('OS_TENANT_ID', default=None),
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-tenant-name',
                            metavar='<auth-tenant-name>',
                            default=cliutils.env('OS_TENANT_NAME',
                                                 default=None),
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-project-domain-id',
                            metavar='<auth-project-domain-id>',
                            default=cliutils.env('OS_PROJECT_DOMAIN_ID',
                                                 default=None),
                            help=_('Defaults to env[OS_PROJECT_DOMAIN_ID].'))

        parser.add_argument('--os-project-domain-name',
                            metavar='<auth-project-domain-name>',
                            default=cliutils.env('OS_PROJECT_DOMAIN_NAME',
                                                 default=None),
                            help=_('Defaults to '
                                   'env[OS_PROJECT_DOMAIN_NAME].'))

        parser.add_argument('--os-token',
                            metavar='<auth-token>',
                            default=cliutils.env('OS_TOKEN', default=None),
                            help=_('Defaults to env[OS_TOKEN].'))

        parser.add_argument('--os-password',
                            metavar='<auth-password>',
                            default=cliutils.env('OS_PASSWORD', default=None),
                            help=_('Defaults to env[OS_PASSWORD].'))

        parser.add_argument('--service-type',
                            metavar='<service-type>',
                            help=_('Defaults to container-infra for all '
                                   'actions.'))
        parser.add_argument('--service_type', help=argparse.SUPPRESS)

        parser.add_argument('--endpoint-type',
                            metavar='<endpoint-type>',
                            default=cliutils.env('OS_ENDPOINT_TYPE',
                                                 default=None),
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-endpoint-type',
                            metavar='<os-endpoint-type>',
                            default=cliutils.env('OS_ENDPOINT_TYPE',
                                                 default=None),
                            help=_('Defaults to env[OS_ENDPOINT_TYPE]'))

        parser.add_argument('--os-interface',
                            metavar='<os-interface>',
                            default=cliutils.env('OS_INTERFACE',
                                                 default=DEFAULT_INTERFACE),
                            help=argparse.SUPPRESS)

        parser.add_argument('--os-cloud',
                            metavar='<auth-cloud>',
                            default=cliutils.env('OS_CLOUD', default=None),
                            help=_('Defaults to env[OS_CLOUD].'))

        # NOTE(dtroyer): We can't add --endpoint_type here due to argparse
        #                thinking usage-list --end is ambiguous; but it
        #                works fine with only --endpoint-type present
        #                Go figure.  I'm leaving this here for doc purposes.
        # parser.add_argument('--endpoint_type',
        #    help=argparse.SUPPRESS)

        parser.add_argument('--magnum-api-version',
                            metavar='<magnum-api-ver>',
                            default=cliutils.env('MAGNUM_API_VERSION',
                                                 default='latest'),
                            help=_('Accepts "api", '
                                   'defaults to env[MAGNUM_API_VERSION].'))
        parser.add_argument('--magnum_api_version', help=argparse.SUPPRESS)

        parser.add_argument('--os-cacert',
                            metavar='<ca-certificate>',
                            default=cliutils.env('OS_CACERT', default=None),
                            help=_('Specify a CA bundle file to use in '
                                   'verifying a TLS (https) server '
                                   'certificate. Defaults to env[OS_CACERT].'))

        parser.add_argument('--os-endpoint-override',
                            metavar='<endpoint-override>',
                            default=cliutils.env('OS_ENDPOINT_OVERRIDE',
                                                 default=None),
                            help=_("Use this API endpoint instead of the "
                                   "Service Catalog."))
        parser.add_argument('--bypass-url',
                            metavar='<bypass-url>',
                            default=cliutils.env('BYPASS_URL', default=None),
                            dest='bypass_url',
                            help=argparse.SUPPRESS)
        parser.add_argument('--bypass_url', help=argparse.SUPPRESS)

        parser.add_argument('--insecure',
                            default=cliutils.env('MAGNUMCLIENT_INSECURE',
                                                 default=False),
                            action='store_true',
                            help=_("Do not verify https connections"))

        if profiler:
            parser.add_argument('--profile',
                                metavar='HMAC_KEY',
                                help='HMAC key to use for encrypting context '
                                'data for performance profiling of operation. '
                                'This key should be the value of the HMAC key '
                                'configured for the OSprofiler middleware in '
                                'nova; it is specified in the Nova '
                                'configuration file at "/etc/nova/nova.conf". '
                                'Without the key, profiling will not be '
                                'triggered even if OSprofiler is enabled on '
                                'the server side.')

        return parser

    def get_subcommand_parser(self, version):
        parser = self.get_base_parser()

        self.subcommands = {}
        subparsers = parser.add_subparsers(metavar='<subcommand>')

        try:
            actions_modules = {'1': shell_v1.COMMAND_MODULES}[version]
        except KeyError:
            actions_modules = shell_v1.COMMAND_MODULES

        for actions_module in actions_modules:
            self._find_actions(subparsers, actions_module)
        self._find_actions(subparsers, self)

        self._add_bash_completion_subparser(subparsers)

        return parser

    def _add_bash_completion_subparser(self, subparsers):
        subparser = (subparsers.add_parser(
            'bash_completion',
            add_help=False,
            formatter_class=OpenStackHelpFormatter))
        self.subcommands['bash_completion'] = subparser
        subparser.set_defaults(func=self.do_bash_completion)

    def _find_actions(self, subparsers, actions_module):
        for attr in (a for a in dir(actions_module) if a.startswith('do_')):
            # I prefer to be hyphen-separated instead of underscores.
            command = attr[3:].replace('_', '-')
            callback = getattr(actions_module, attr)
            desc = callback.__doc__ or ''
            action_help = desc.strip()
            arguments = getattr(callback, 'arguments', [])
            group_args = getattr(callback, 'deprecated_groups', [])

            subparser = (subparsers.add_parser(
                command,
                help=action_help,
                description=desc,
                add_help=False,
                formatter_class=OpenStackHelpFormatter))
            subparser.add_argument(
                '-h',
                '--help',
                action='help',
                help=argparse.SUPPRESS,
            )
            self.subcommands[command] = subparser

            for (old_info, new_info, req) in group_args:
                group = subparser.add_mutually_exclusive_group(required=req)
                group.add_argument(*old_info[0], **old_info[1])
                group.add_argument(*new_info[0], **new_info[1])

            for (args, kwargs) in arguments:
                subparser.add_argument(*args, **kwargs)
            subparser.set_defaults(func=callback)

    def setup_debugging(self, debug):
        if debug:
            streamformat = "%(levelname)s (%(module)s:%(lineno)d) %(message)s"
            # Set up the root logger to debug so that the submodules can
            # print debug messages
            logging.basicConfig(level=logging.DEBUG, format=streamformat)
        else:
            streamformat = "%(levelname)s %(message)s"
            logging.basicConfig(level=logging.CRITICAL, format=streamformat)

    def _check_version(self, api_version):
        if api_version == 'latest':
            return LATEST_API_VERSION
        else:
            try:
                versions = tuple(int(i) for i in api_version.split('.'))
            except ValueError:
                versions = ()
            if len(versions) == 1:
                # Default value of magnum_api_version is '1'.
                # If user not specify the value of api version, not passing
                # headers at all.
                magnum_api_version = None
            elif len(versions) == 2:
                magnum_api_version = api_version
                # In the case of '1.0'
                if versions[1] == 0:
                    magnum_api_version = None
            else:
                msg = _("The requested API version %(ver)s is an unexpected "
                        "format. Acceptable formats are 'X', 'X.Y', or the "
                        "literal string '%(latest)s'.") % {
                            'ver': api_version,
                            'latest': 'latest'
                        }
                raise exc.CommandError(msg)

            api_major_version = versions[0]
            return (api_major_version, magnum_api_version)

    def main(self, argv):

        # NOTE(Christoph Jansen): With Python 3.4 argv somehow becomes a Map.
        #                         This hack fixes it.
        argv = list(argv)

        # Parse args once to find version and debug settings
        parser = self.get_base_parser()
        (options, args) = parser.parse_known_args(argv)
        self.setup_debugging(options.debug)

        # NOTE(dtroyer): Hackery to handle --endpoint_type due to argparse
        #                thinking usage-list --end is ambiguous; but it
        #                works fine with only --endpoint-type present
        #                Go figure.
        if '--endpoint_type' in argv:
            spot = argv.index('--endpoint_type')
            argv[spot] = '--endpoint-type'

        # build available subcommands based on version
        (api_major_version, magnum_api_version) = (self._check_version(
            options.magnum_api_version))

        subcommand_parser = (self.get_subcommand_parser(api_major_version))
        self.parser = subcommand_parser

        if options.help or not argv:
            subcommand_parser.print_help()
            return 0

        args = subcommand_parser.parse_args(argv)

        # Short-circuit and deal with help right away.
        # NOTE(jamespage): args.func is not guaranteed with python >= 3.4
        if not hasattr(args, 'func') or args.func == self.do_help:
            self.do_help(args)
            return 0
        elif args.func == self.do_bash_completion:
            self.do_bash_completion(args)
            return 0

        if not args.service_type:
            args.service_type = DEFAULT_SERVICE_TYPE

        if args.bypass_url:
            args.os_endpoint_override = args.bypass_url

        args.os_project_id = (args.os_project_id or args.os_tenant_id)
        args.os_project_name = (args.os_project_name or args.os_tenant_name)

        if not cliutils.isunauthenticated(args.func):
            if (not (args.os_token and
                     (args.os_auth_url or args.os_endpoint_override))
                    and not args.os_cloud):

                if not (args.os_username or args.os_user_id):
                    raise exc.CommandError(
                        "You must provide a username via either --os-username "
                        "or via env[OS_USERNAME]")
                if not args.os_password:
                    raise exc.CommandError(
                        "You must provide a password via either "
                        "--os-password, env[OS_PASSWORD], or prompted "
                        "response")
                if (not args.os_project_name and not args.os_project_id):
                    raise exc.CommandError(
                        "You must provide a project name or project id via "
                        "--os-project-name, --os-project-id, "
                        "env[OS_PROJECT_NAME] or env[OS_PROJECT_ID]")
                if not args.os_auth_url:
                    raise exc.CommandError(
                        "You must provide an auth url via either "
                        "--os-auth-url or via env[OS_AUTH_URL]")
        try:
            client = {
                '1': client_v1,
            }[api_major_version]
        except KeyError:
            client = client_v1

        args.os_endpoint_type = (args.os_endpoint_type or args.endpoint_type)
        if args.os_endpoint_type:
            args.os_interface = args.os_endpoint_type

        if args.os_interface.endswith('URL'):
            args.os_interface = args.os_interface[:-3]

        kwargs = {}
        if profiler:
            kwargs["profile"] = args.profile

        self.cs = client.Client(
            cloud=args.os_cloud,
            user_id=args.os_user_id,
            username=args.os_username,
            password=args.os_password,
            auth_token=args.os_token,
            project_id=args.os_project_id,
            project_name=args.os_project_name,
            user_domain_id=args.os_user_domain_id,
            user_domain_name=args.os_user_domain_name,
            project_domain_id=args.os_project_domain_id,
            project_domain_name=args.os_project_domain_name,
            auth_url=args.os_auth_url,
            service_type=args.service_type,
            region_name=args.os_region_name,
            magnum_url=args.os_endpoint_override,
            interface=args.os_interface,
            insecure=args.insecure,
            api_version=args.magnum_api_version,
            **kwargs)

        self._check_deprecation(args.func, argv)
        args.func(self.cs, args)

        if profiler and args.profile:
            trace_id = profiler.get().get_base_id()
            print("To display trace use the command:\n\n"
                  "  osprofiler trace show --html %s " % trace_id)

    def _check_deprecation(self, func, argv):
        if not hasattr(func, 'deprecated_groups'):
            return

        for (old_info, new_info, required) in func.deprecated_groups:
            old_param = old_info[0][0]
            new_param = new_info[0][0]
            old_value, new_value = None, None
            for i in range(len(argv)):
                cur_arg = argv[i]
                if cur_arg == old_param:
                    old_value = argv[i + 1]
                elif cur_arg == new_param[0]:
                    new_value = argv[i + 1]

            if old_value and not new_value:
                print('WARNING: The %s parameter is deprecated and will be '
                      'removed in a future release. Use the %s parameter to '
                      'avoid seeing this message.' % (old_param, new_param))

    def _dump_timings(self, timings):
        class Tyme(object):
            def __init__(self, url, seconds):
                self.url = url
                self.seconds = seconds

        results = [Tyme(url, end - start) for url, start, end in timings]
        total = 0.0
        for tyme in results:
            total += tyme.seconds
        results.append(Tyme("Total", total))
        cliutils.print_list(results, ["url", "seconds"], sortby_index=None)

    def do_bash_completion(self, _args):
        """Prints arguments for bash-completion.

        Prints all of the commands and options to stdout so that the
        magnum.bash_completion script doesn't have to hard code them.
        """
        commands = set()
        options = set()
        for sc_str, sc in self.subcommands.items():
            commands.add(sc_str)
            for option in sc._optionals._option_string_actions.keys():
                options.add(option)

        commands.remove('bash-completion')
        commands.remove('bash_completion')
        print(' '.join(commands | options))

    @cliutils.arg('command',
                  metavar='<subcommand>',
                  nargs='?',
                  help=_('Display help for <subcommand>.'))
    def do_help(self, args):
        """Display help about this program or one of its subcommands."""
        # NOTE(jamespage): args.command is not guaranteed with python >= 3.4
        command = getattr(args, 'command', '')

        if command:
            if args.command in self.subcommands:
                self.subcommands[args.command].print_help()
            else:
                raise exc.CommandError("'%s' is not a valid subcommand" %
                                       args.command)
        else:
            self.parser.print_help()
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

from magnumclient.common import cliutils as utils
from magnumclient.i18n import _


@utils.arg('--project-id',
           required=False,
           metavar='<project-id>',
           help=_('Project ID'))
@utils.deprecated(utils.MAGNUM_CLIENT_DEPRECATION_WARNING)
def do_stats_list(cs, args):
    """Show stats for the given project_id"""
    opts = {
        'project_id': args.project_id
    }

    stats = cs.stats.list(**opts)
    utils.print_dict(stats._info)
Example #44
0
class ConfigCluster(command.Command):
    _description = _("Get Configuration for a Cluster")

    def get_parser(self, prog_name):
        parser = super(ConfigCluster, self).get_parser(prog_name)
        parser.add_argument(
            'cluster',
            metavar='<cluster>',
            help=_('The name or UUID of cluster to update'))
        parser.add_argument(
            '--dir',
            metavar='<dir>',
            default='.',
            help=_('Directory to save the certificate and config files.'))
        parser.add_argument(
            '--force',
            action='store_true',
            dest='force',
            default=False,
            help=_('Overwrite files if existing.'))

        return parser

    def take_action(self, parsed_args):
        """Configure native client to access cluster.

        You can source the output of this command to get the native client of
        the corresponding COE configured to access the cluster.

        """
        self.log.debug("take_action(%s)", parsed_args)

        mag_client = self.app.client_manager.container_infra

        parsed_args.dir = os.path.abspath(parsed_args.dir)
        cluster = mag_client.clusters.get(parsed_args.cluster)
        if cluster.status not in ('CREATE_COMPLETE', 'UPDATE_COMPLETE',
                                  'ROLLBACK_COMPLETE'):
            raise exceptions.CommandError("cluster in status %s" %
                                          cluster.status)
        cluster_template = mag_client.cluster_templates.get(
            cluster.cluster_template_id)
        opts = {
            'cluster_uuid': cluster.uuid,
        }

        if not cluster_template.tls_disabled:
            tls = magnum_utils.generate_csr_and_key()
            tls['ca'] = mag_client.certificates.get(**opts).pem
            opts['csr'] = tls['csr']
            tls['cert'] = mag_client.certificates.create(**opts).pem
            for k in ('key', 'cert', 'ca'):
                fname = "%s/%s.pem" % (parsed_args.dir, k)
                if os.path.exists(fname) and not parsed_args.force:
                    raise Exception("File %s exists, aborting." % fname)
                else:
                    f = open(fname, "w")
                    f.write(tls[k])
                    f.close()

        print(magnum_utils.config_cluster(cluster,
                                          cluster_template,
                                          parsed_args.dir,
                                          force=parsed_args.force))
@utils.arg('--limit',
           metavar='<limit>',
           type=int,
           help='Maximum number of clusters to return.')
@utils.arg('--sort-key',
           metavar='<sort-key>',
           help='Column to sort results by.')
@utils.arg('--sort-dir',
           metavar='<sort-dir>',
           choices=['desc', 'asc'],
           help='Direction to sort. "asc" or "desc".')
@utils.arg('--fields',
           default=None,
           metavar='<fields>',
           help=_('Comma-separated list of fields to display. '
                  'Available fields: uuid, name, cluster_template_id, '
                  'stack_id, status, master_count, node_count, links, '
                  'create_timeout'))
def do_cluster_list(cs, args):
    """Print a list of available clusters."""
    clusters = cs.clusters.list(marker=args.marker,
                                limit=args.limit,
                                sort_key=args.sort_key,
                                sort_dir=args.sort_dir)
    columns = [
        'uuid', 'name', 'keypair', 'node_count', 'master_count', 'status'
    ]
    columns += utils._get_list_table_columns_and_formatters(
        args.fields, clusters, exclude_fields=(c.lower() for c in columns))[0]

    labels = columns[:]
    labels[2] = 'keypair_id'
Example #46
0
class CreateCluster(command.Command):
    _description = _("Create a cluster")

    def get_parser(self, prog_name):
        parser = super(CreateCluster, self).get_parser(prog_name)
        # NOTE: All arguments are positional and, if not provided
        # with a default, required.
        parser.add_argument('--cluster-template',
                            dest='cluster_template',
                            required=True,
                            metavar='<cluster-template>',
                            help='ID or name of the cluster template.')
        parser.add_argument('--discovery-url',
                            dest='discovery_url',
                            metavar='<discovery-url>',
                            help=('Specifies custom delivery url for '
                                  'node discovery.'))
        parser.add_argument('--docker-volume-size',
                            dest='docker_volume_size',
                            type=int,
                            metavar='<docker-volume-size>',
                            help=('The size in GB for the docker volume to '
                                  'use.'))
        parser.add_argument('--labels',
                            metavar='<KEY1=VALUE1,KEY2=VALUE2;KEY3=VALUE3...>',
                            action='append',
                            help=_('Arbitrary labels in the form of key=value'
                                   'pairs to associate with a cluster '
                                   'template. May be used multiple times.'))
        parser.add_argument('--keypair',
                            default=None,
                            metavar='<keypair>',
                            help='UUID or name of the keypair to use.')
        parser.add_argument('--master-count',
                            dest='master_count',
                            type=int,
                            default=1,
                            metavar='<master-count>',
                            help='The number of master nodes for the cluster.')
        parser.add_argument('name',
                            metavar='<name>',
                            help='Name of the cluster to create.')
        parser.add_argument('--node-count',
                            dest='node_count',
                            type=int,
                            default=1,
                            metavar='<node-count>',
                            help='The cluster node count.')
        parser.add_argument('--timeout',
                            type=int,
                            default=60,
                            metavar='<timeout>',
                            help=('The timeout for cluster creation time. The '
                                  'default is 60 minutes.'))
        parser.add_argument(
            '--master-flavor',
            dest='master_flavor',
            metavar='<master-flavor>',
            help=_('The nova flavor name or UUID to use when launching the '
                   'master node of the Cluster.'))
        parser.add_argument(
            '--flavor',
            metavar='<flavor>',
            help=_('The nova flavor name or UUID to use when launching the '
                   'Cluster.'))

        return parser

    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)

        mag_client = self.app.client_manager.container_infra
        args = {
            'cluster_template_id': parsed_args.cluster_template,
            'create_timeout': parsed_args.timeout,
            'discovery_url': parsed_args.discovery_url,
            'docker_volume_size': parsed_args.docker_volume_size,
            'keypair': parsed_args.keypair,
            'master_count': parsed_args.master_count,
            'name': parsed_args.name,
            'node_count': parsed_args.node_count,
            'master_flavor_id': parsed_args.master_flavor,
            'flavor_id': parsed_args.flavor,
        }

        if parsed_args.labels is not None:
            args['labels'] = magnum_utils.handle_labels(parsed_args.labels)

        cluster = mag_client.clusters.create(**args)
        print("Request to create cluster %s accepted"
              % cluster.uuid)
class HTTPClientError(HttpError):
    """Client-side HTTP error.

    Exception for cases in which the client seems to have erred.
    """
    message = _("HTTP Client Error")
class HTTPRedirection(HttpError):
    """HTTP Redirection."""
    message = _("HTTP Redirection")
from magnumclient.v1 import basemodels


DEPRECATION_MESSAGE = (
    'WARNING: Baymodel commands are deprecated and will be removed in a future'
    ' release.\nUse cluster commands to avoid seeing this message.')


def _show_baymodel(baymodel):
    del baymodel._info['links']
    utils.print_dict(baymodel._info)


@utils.arg('--name',
           metavar='<name>',
           help=_('Name of the baymodel to create.'))
@utils.arg('--image-id',
           required=True,
           metavar='<image-id>',
           help=_('The name or UUID of the base image to customize for'
                  ' the bay.'))
@utils.arg('--keypair-id',
           required=True,
           metavar='<keypair-id>',
           help=_('The name of the SSH keypair to load into the'
                  ' Bay nodes.'))
@utils.arg('--external-network-id',
           required=True,
           metavar='<external-network-id>',
           help=_('The external Neutron network ID to connect to this bay'
                  ' model.'))
 def __init__(self, endpoints=None):
     super(AmbiguousEndpoints, self).__init__(
         _("AmbiguousEndpoints: %r") % endpoints)
     self.endpoints = endpoints
class CreateClusterTemplate(command.ShowOne):
    """Create a Cluster Template."""
    _description = _("Create a Cluster Template.")

    def get_parser(self, prog_name):
        parser = super(CreateClusterTemplate, self).get_parser(prog_name)

        parser.add_argument('name',
                            metavar='<name>',
                            help=_('Name of the cluster template to create.'))
        parser.add_argument(
            '--coe',
            required=True,
            metavar='<coe>',
            help=_('Specify the Container Orchestration Engine to use.'))
        parser.add_argument(
            '--image',
            required=True,
            metavar='<image>',
            help=_('The name or UUID of the base image to customize for the '
                   'Cluster.'))
        parser.add_argument(
            '--external-network',
            dest='external_network',
            required=True,
            metavar='<external-network>',
            help=_('The external Neutron network name or UUID to connect to '
                   'this Cluster Template.'))
        parser.add_argument(
            '--keypair',
            metavar='<keypair>',
            help=_('The name or UUID of the SSH keypair to load into the '
                   'Cluster nodes.'))
        parser.add_argument(
            '--fixed-network',
            dest='fixed_network',
            metavar='<fixed-network>',
            help=_('The private Neutron network name to connect to this '
                   'Cluster model.'))
        parser.add_argument(
            '--fixed-subnet',
            dest='fixed_subnet',
            metavar='<fixed-subnet>',
            help=_('The private Neutron subnet name to connect to Cluster.'))
        parser.add_argument(
            '--network-driver',
            dest='network_driver',
            metavar='<network-driver>',
            help=_('The network driver name for instantiating container '
                   'networks.'))
        parser.add_argument(
            '--volume-driver',
            dest='volume_driver',
            metavar='<volume-driver>',
            help=_('The volume driver name for instantiating container '
                   'volume.'))
        parser.add_argument(
            '--dns-nameserver',
            dest='dns_nameserver',
            metavar='<dns-nameserver>',
            default='8.8.8.8',
            help=_('The DNS nameserver to use for this cluster template.'))
        parser.add_argument(
            '--flavor',
            metavar='<flavor>',
            default='m1.medium',
            help=_('The nova flavor name or UUID to use when launching the '
                   'Cluster.'))
        parser.add_argument(
            '--master-flavor',
            dest='master_flavor',
            metavar='<master-flavor>',
            help=_('The nova flavor name or UUID to use when launching the '
                   'master node of the Cluster.'))
        parser.add_argument(
            '--docker-volume-size',
            dest='docker_volume_size',
            metavar='<docker-volume-size>',
            type=int,
            help=_('Specify the number of size in GB for the docker volume '
                   'to use.'))
        parser.add_argument(
            '--docker-storage-driver',
            dest='docker_storage_driver',
            metavar='<docker-storage-driver>',
            default='devicemapper',
            help=_('Select a docker storage driver. Supported: devicemapper, '
                   'overlay. Default: devicemapper'))
        parser.add_argument(
            '--http-proxy',
            dest='http_proxy',
            metavar='<http-proxy>',
            help=_('The http_proxy address to use for nodes in Cluster.'))
        parser.add_argument(
            '--https-proxy',
            dest='https_proxy',
            metavar='<https-proxy>',
            help=_('The https_proxy address to use for nodes in Cluster.'))
        parser.add_argument(
            '--no-proxy',
            dest='no_proxy',
            metavar='<no-proxy>',
            help=_('The no_proxy address to use for nodes in Cluster.'))
        parser.add_argument(
            '--labels',
            metavar='<KEY1=VALUE1,KEY2=VALUE2;KEY3=VALUE3...>',
            action='append',
            default=[],
            help=_('Arbitrary labels in the form of key=value pairs to '
                   'associate with a cluster template. May be used multiple '
                   'times.'))
        parser.add_argument('--tls-disabled',
                            dest='tls_disabled',
                            action='store_true',
                            default=False,
                            help=_('Disable TLS in the Cluster.'))
        parser.add_argument('--public',
                            action='store_true',
                            default=False,
                            help=_('Make cluster template public.'))
        parser.add_argument('--registry-enabled',
                            dest='registry_enabled',
                            action='store_true',
                            default=False,
                            help=_('Enable docker registry in the Cluster'))
        parser.add_argument(
            '--server-type',
            dest='server_type',
            metavar='<server-type>',
            default='vm',
            help=_('Specify the server type to be used for example vm. '
                   'For this release default server type will be vm.'))
        parser.add_argument(
            '--master-lb-enabled',
            dest='master_lb_enabled',
            action='store_true',
            default=False,
            help=_('Indicates whether created Clusters should have a load '
                   'balancer for master nodes or not.'))
        parser.add_argument(
            '--floating-ip-enabled',
            dest='floating_ip_enabled',
            default=[],
            action='append_const',
            const=True,
            help=_('Indicates whether created Clusters should have a '
                   'floating ip.'))
        parser.add_argument(
            '--floating-ip-disabled',
            dest='floating_ip_enabled',
            action='append_const',
            const=False,
            help=_('Disables floating ip creation on the new Cluster'))

        return parser

    def take_action(self, parsed_args):
        self.log.debug("take_action(%s)", parsed_args)
        mag_client = self.app.client_manager.container_infra
        args = {
            'name': parsed_args.name,
            'image_id': parsed_args.image,
            'keypair_id': parsed_args.keypair,
            'external_network_id': parsed_args.external_network,
            'coe': parsed_args.coe,
            'fixed_network': parsed_args.fixed_network,
            'fixed_subnet': parsed_args.fixed_subnet,
            'network_driver': parsed_args.network_driver,
            'volume_driver': parsed_args.volume_driver,
            'dns_nameserver': parsed_args.dns_nameserver,
            'flavor_id': parsed_args.flavor,
            'master_flavor_id': parsed_args.master_flavor,
            'docker_volume_size': parsed_args.docker_volume_size,
            'docker_storage_driver': parsed_args.docker_storage_driver,
            'http_proxy': parsed_args.http_proxy,
            'https_proxy': parsed_args.https_proxy,
            'no_proxy': parsed_args.no_proxy,
            'labels': magnum_utils.handle_labels(parsed_args.labels),
            'tls_disabled': parsed_args.tls_disabled,
            'public': parsed_args.public,
            'registry_enabled': parsed_args.registry_enabled,
            'server_type': parsed_args.server_type,
            'master_lb_enabled': parsed_args.master_lb_enabled,
        }
        if len(parsed_args.floating_ip_enabled) > 1:
            raise InvalidAttribute('--floating-ip-enabled and '
                                   '--floating-ip-disabled are '
                                   'mutually exclusive and '
                                   'should be specified only once.')
        elif len(parsed_args.floating_ip_enabled) == 1:
            args['floating_ip_enabled'] = parsed_args.floating_ip_enabled[0]

        ct = mag_client.cluster_templates.create(**args)
        print("Request to create cluster template %s accepted" %
              parsed_args.name)
        return _show_cluster_template(ct)
    def get_parser(self, prog_name):
        parser = super(CreateClusterTemplate, self).get_parser(prog_name)

        parser.add_argument('name',
                            metavar='<name>',
                            help=_('Name of the cluster template to create.'))
        parser.add_argument(
            '--coe',
            required=True,
            metavar='<coe>',
            help=_('Specify the Container Orchestration Engine to use.'))
        parser.add_argument(
            '--image',
            required=True,
            metavar='<image>',
            help=_('The name or UUID of the base image to customize for the '
                   'Cluster.'))
        parser.add_argument(
            '--external-network',
            dest='external_network',
            required=True,
            metavar='<external-network>',
            help=_('The external Neutron network name or UUID to connect to '
                   'this Cluster Template.'))
        parser.add_argument(
            '--keypair',
            metavar='<keypair>',
            help=_('The name or UUID of the SSH keypair to load into the '
                   'Cluster nodes.'))
        parser.add_argument(
            '--fixed-network',
            dest='fixed_network',
            metavar='<fixed-network>',
            help=_('The private Neutron network name to connect to this '
                   'Cluster model.'))
        parser.add_argument(
            '--fixed-subnet',
            dest='fixed_subnet',
            metavar='<fixed-subnet>',
            help=_('The private Neutron subnet name to connect to Cluster.'))
        parser.add_argument(
            '--network-driver',
            dest='network_driver',
            metavar='<network-driver>',
            help=_('The network driver name for instantiating container '
                   'networks.'))
        parser.add_argument(
            '--volume-driver',
            dest='volume_driver',
            metavar='<volume-driver>',
            help=_('The volume driver name for instantiating container '
                   'volume.'))
        parser.add_argument(
            '--dns-nameserver',
            dest='dns_nameserver',
            metavar='<dns-nameserver>',
            default='8.8.8.8',
            help=_('The DNS nameserver to use for this cluster template.'))
        parser.add_argument(
            '--flavor',
            metavar='<flavor>',
            default='m1.medium',
            help=_('The nova flavor name or UUID to use when launching the '
                   'Cluster.'))
        parser.add_argument(
            '--master-flavor',
            dest='master_flavor',
            metavar='<master-flavor>',
            help=_('The nova flavor name or UUID to use when launching the '
                   'master node of the Cluster.'))
        parser.add_argument(
            '--docker-volume-size',
            dest='docker_volume_size',
            metavar='<docker-volume-size>',
            type=int,
            help=_('Specify the number of size in GB for the docker volume '
                   'to use.'))
        parser.add_argument(
            '--docker-storage-driver',
            dest='docker_storage_driver',
            metavar='<docker-storage-driver>',
            default='devicemapper',
            help=_('Select a docker storage driver. Supported: devicemapper, '
                   'overlay. Default: devicemapper'))
        parser.add_argument(
            '--http-proxy',
            dest='http_proxy',
            metavar='<http-proxy>',
            help=_('The http_proxy address to use for nodes in Cluster.'))
        parser.add_argument(
            '--https-proxy',
            dest='https_proxy',
            metavar='<https-proxy>',
            help=_('The https_proxy address to use for nodes in Cluster.'))
        parser.add_argument(
            '--no-proxy',
            dest='no_proxy',
            metavar='<no-proxy>',
            help=_('The no_proxy address to use for nodes in Cluster.'))
        parser.add_argument(
            '--labels',
            metavar='<KEY1=VALUE1,KEY2=VALUE2;KEY3=VALUE3...>',
            action='append',
            default=[],
            help=_('Arbitrary labels in the form of key=value pairs to '
                   'associate with a cluster template. May be used multiple '
                   'times.'))
        parser.add_argument('--tls-disabled',
                            dest='tls_disabled',
                            action='store_true',
                            default=False,
                            help=_('Disable TLS in the Cluster.'))
        parser.add_argument('--public',
                            action='store_true',
                            default=False,
                            help=_('Make cluster template public.'))
        parser.add_argument('--registry-enabled',
                            dest='registry_enabled',
                            action='store_true',
                            default=False,
                            help=_('Enable docker registry in the Cluster'))
        parser.add_argument(
            '--server-type',
            dest='server_type',
            metavar='<server-type>',
            default='vm',
            help=_('Specify the server type to be used for example vm. '
                   'For this release default server type will be vm.'))
        parser.add_argument(
            '--master-lb-enabled',
            dest='master_lb_enabled',
            action='store_true',
            default=False,
            help=_('Indicates whether created Clusters should have a load '
                   'balancer for master nodes or not.'))
        parser.add_argument(
            '--floating-ip-enabled',
            dest='floating_ip_enabled',
            default=[],
            action='append_const',
            const=True,
            help=_('Indicates whether created Clusters should have a '
                   'floating ip.'))
        parser.add_argument(
            '--floating-ip-disabled',
            dest='floating_ip_enabled',
            action='append_const',
            const=False,
            help=_('Disables floating ip creation on the new Cluster'))

        return parser
 def __init__(self, opt_names):
     super(AuthPluginOptionsMissing, self).__init__(
         _("Authentication failed. Missing options: %s") %
         ", ".join(opt_names))
     self.opt_names = opt_names
def _get_target_uuid(cs, args):
    target = None
    if args.cluster:
        target = cs.clusters.get(args.cluster)
    elif args.bay:
        print(DEPRECATION_MESSAGE)
        target = cs.bays.get(args.bay)
    else:
        raise utils.MissingArgs(['--cluster or --bay'])
    return target.uuid


@utils.arg('--bay',
           required=False,
           metavar='<bay>',
           help=_('ID or name of the bay.'))
@utils.arg('postional_cluster',
           metavar='<cluster>',
           nargs='?',
           default=None,
           help=_('ID or name of the cluster.'))
@utils.arg('--cluster',
           metavar='<cluster>',
           default=None,
           help=(_('ID or name of the cluster. %s') %
                 utils.CLUSTER_DEPRECATION_HELP))
@utils.deprecated(utils.MAGNUM_CLIENT_DEPRECATION_WARNING)
def do_ca_show(cs, args):
    """Show details about the CA certificate for a bay or cluster."""
    utils.validate_cluster_args(args.postional_cluster, args.cluster)
    args.cluster = args.postional_cluster or args.cluster
 def __init__(self, auth_system):
     super(AuthSystemNotFound, self).__init__(
         _("AuthSystemNotFound: %r") % auth_system)
     self.auth_system = auth_system