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
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
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 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
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
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
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]
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)
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))
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)
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 })
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))
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)
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)
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)
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
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. '
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
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
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)
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'
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 _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