def create(self, parent_group_id, ip_protocol=None, from_port=None, to_port=None, cidr=None, group_id=None): """ Create a security group rule :param ip_protocol: IP protocol, one of 'tcp', 'udp' or 'icmp' :param from_port: Source port :param to_port: Destination port :param cidr: Destination IP address(es) in CIDR notation :param group_id: Security group id (int) :param parent_group_id: Parent security group id (int) """ try: from_port = int(from_port) except (TypeError, ValueError): raise exceptions.CommandError(_("From port must be an integer.")) try: to_port = int(to_port) except (TypeError, ValueError): raise exceptions.CommandError(_("To port must be an integer.")) if ip_protocol.upper() not in ['TCP', 'UDP', 'ICMP']: raise exceptions.CommandError(_("IP protocol must be 'tcp', 'udp'" ", or 'icmp'.")) body = {"security_group_rule": { "ip_protocol": ip_protocol, "from_port": from_port, "to_port": to_port, "cidr": cidr, "group_id": group_id, "parent_group_id": parent_group_id}} return self._create('/os-security-group-rules', body, 'security_group_rule')
def create(self, ip_protocol=None, from_port=None, to_port=None, cidr=None): """ Create a security group default rule :param ip_protocol: IP protocol, one of 'tcp', 'udp' or 'icmp' :param from_port: Source port :param to_port: Destination port :param cidr: Destination IP address(es) in CIDR notation """ try: from_port = int(from_port) except (TypeError, ValueError): raise exceptions.CommandError(_("From port must be an integer.")) try: to_port = int(to_port) except (TypeError, ValueError): raise exceptions.CommandError(_("To port must be an integer.")) if ip_protocol.upper() not in ['TCP', 'UDP', 'ICMP']: raise exceptions.CommandError(_("IP protocol must be 'tcp', 'udp'" ", or 'icmp'.")) body = {"security_group_default_rule": { "ip_protocol": ip_protocol, "from_port": from_port, "to_port": to_port, "cidr": cidr}} return self._create('/os-security-group-default-rules', body, 'security_group_default_rule')
def do_cell_capacities(cs, args): """Get cell capacities for all cells or a given cell.""" cell = cs.cells.capacities(args.cell) print(_("Ram Available: %s MB") % cell.capacities['ram_free']['total_mb']) utils.print_dict(cell.capacities['ram_free']['units_by_mb'], dict_property='Ram(MB)', dict_value="Units") print(_("\nDisk Available: %s MB") % cell.capacities['disk_free']['total_mb']) utils.print_dict(cell.capacities['disk_free']['units_by_mb'], dict_property='Disk(MB)', dict_value="Units")
def positive_non_zero_float(text): if text is None: return None try: value = float(text) except ValueError: msg = _("%s must be a float") % text raise argparse.ArgumentTypeError(msg) if value <= 0: msg = _("%s must be greater than 0") % text raise argparse.ArgumentTypeError(msg) return value
def find_resource(manager, name_or_id, **find_args): """Helper for the _find_* methods.""" # for str id which is not uuid (for Flavor and Keypair search currently) if getattr(manager, 'is_alphanum_id_allowed', False): try: return manager.get(name_or_id) except exceptions.NotFound: pass # try to get entity as integer id try: return manager.get(int(name_or_id)) except (TypeError, ValueError, exceptions.NotFound): pass # now try to get entity as uuid try: tmp_id = encodeutils.safe_encode(name_or_id) if six.PY3: tmp_id = tmp_id.decode() uuid.UUID(tmp_id) return manager.get(tmp_id) except (TypeError, ValueError, exceptions.NotFound): pass try: try: resource = getattr(manager, 'resource_class', None) name_attr = resource.NAME_ATTR if resource else 'name' kwargs = {name_attr: name_or_id} kwargs.update(find_args) return manager.find(**kwargs) except exceptions.NotFound: pass # finally try to find entity by human_id try: return manager.find(human_id=name_or_id, **find_args) except exceptions.NotFound: msg = (_("No %(class)s with a name or ID of '%(name)s' exists.") % {'class': manager.resource_class.__name__.lower(), 'name': name_or_id}) raise exceptions.CommandError(msg) except exceptions.NoUniqueMatch: msg = (_("Multiple %(class)s matches found for '%(name)s', use an ID " "to be more specific.") % {'class': manager.resource_class.__name__.lower(), 'name': name_or_id}) raise exceptions.CommandError(msg)
def list(self, **kwargs): if kwargs.get('flavor'): return self._list_by_flavor(kwargs['flavor']) elif kwargs.get('tenant'): return self._list_by_tenant(kwargs['tenant']) else: raise NotImplementedError(_('Unknown list options.'))
def validate_flavor_metadata_keys(keys): for key in keys: valid_name = VALID_KEY_REGEX.match(key) if not valid_name: msg = _('Invalid key: "%s". Keys may only contain letters, ' 'numbers, spaces, underscores, periods, colons and ' 'hyphens.') raise exceptions.CommandError(msg % key)
def do_help(self, args): """ Display help about this program or one of its subcommands. """ if args.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()
def _server_migrate(cs, server): success = True error_message = "" try: cs.servers.migrate(server['uuid']) except Exception as e: success = False error_message = _("Error while migrating instance: %s") % e return HostServersMigrateResponse(base.Manager, {"server_uuid": server['uuid'], "migration_accepted": success, "error_message": error_message})
def do_help(self, args): """ Display help about this program or one of its subcommands. """ if args.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()
def create(self, name, ram, vcpus, disk, flavorid="auto", ephemeral=0, swap=0, rxtx_factor=1.0, is_public=True): """ Create a flavor. :param name: Descriptive name of the flavor :param ram: Memory in MB for the flavor :param vcpus: Number of VCPUs for the flavor :param disk: Size of local disk in GB :param flavorid: ID for the flavor (optional). You can use the reserved value ``"auto"`` to have Patron generate a UUID for the flavor in cases where you cannot simply pass ``None``. :param swap: Swap space in MB :param rxtx_factor: RX/TX factor :rtype: :class:`Flavor` """ try: ram = int(ram) except (TypeError, ValueError): raise exceptions.CommandError(_("Ram must be an integer.")) try: vcpus = int(vcpus) except (TypeError, ValueError): raise exceptions.CommandError(_("VCPUs must be an integer.")) try: disk = int(disk) except (TypeError, ValueError): raise exceptions.CommandError(_("Disk must be an integer.")) if flavorid == "auto": flavorid = None try: swap = int(swap) except (TypeError, ValueError): raise exceptions.CommandError(_("Swap must be an integer.")) try: ephemeral = int(ephemeral) except (TypeError, ValueError): raise exceptions.CommandError(_("Ephemeral must be an integer.")) try: rxtx_factor = float(rxtx_factor) except (TypeError, ValueError): raise exceptions.CommandError(_("rxtx_factor must be a float.")) try: is_public = strutils.bool_from_string(is_public, True) except Exception: raise exceptions.CommandError(_("is_public must be a boolean.")) body = self._build_body(name, ram, vcpus, disk, flavorid, swap, ephemeral, rxtx_factor, is_public) return self._create("/flavors", body, "flavor")
def _extract_service_catalog(self, url, resp, body, extract_token=True): """See what the auth service told us and process the response. We may get redirected to another site, fail or actually get back a service catalog with a token and our endpoints. """ # content must always present if resp.status_code == 200 or resp.status_code == 201: try: self.auth_url = url self.service_catalog = \ service_catalog.ServiceCatalog(body) if extract_token: self.auth_token = self.service_catalog.get_token() self.tenant_id = self.service_catalog.get_tenant_id() management_url = self.service_catalog.url_for( attr='region', filter_value=self.region_name, endpoint_type=self.endpoint_type, service_type=self.service_type, service_name=self.service_name, volume_service_name=self.volume_service_name,) self.management_url = management_url.rstrip('/') return None except exceptions.AmbiguousEndpoints: print(_("Found more than one valid endpoint. Use a more " "restrictive filter")) raise except KeyError: raise exceptions.AuthorizationFailure() except exceptions.EndpointNotFound: print(_("Could not find any suitable endpoint. Correct " "region?")) raise elif resp.status_code == 305: return resp.headers['location'] else: raise exceptions.from_response(resp, body, url)
def _server_evacuate(cs, server, args): success = True error_message = "" try: cs.servers.evacuate(server=server['uuid'], host=args.target_host, on_shared_storage=args.on_shared_storage) except Exception as e: success = False error_message = _("Error while evacuating instance: %s") % e return EvacuateHostResponse(base.Manager, {"server_uuid": server['uuid'], "evacuate_accepted": success, "error_message": error_message})
def save(self, auth_token, management_url, tenant_id): if not HAS_KEYRING or not self.args.os_cache: return if (auth_token == self.auth_token and management_url == self.management_url): # Nothing changed.... return if not all([management_url, auth_token, tenant_id]): raise ValueError(_("Unable to save empty management url/auth " "token")) value = "|".join([str(auth_token), str(management_url), str(tenant_id)]) keyring.set_password("patronclient_auth", self._make_key(), value)
def error(self, message): """error(message: string) Prints a usage message incorporating the message to stderr and exits. """ self.print_usage(sys.stderr) # FIXME(lzyeval): if changes occur in argparse.ArgParser._check_value choose_from = ' (choose from' progparts = self.prog.partition(' ') self.exit(2, _("error: %(errmsg)s\nTry '%(mainp)s help %(subp)s'" " for more information.\n") % {'errmsg': message.split(choose_from)[0], 'mainp': progparts[0], 'subp': progparts[2]})
def get_client_class(version): version_map = { '1.1': 'patronclient.v2.client.Client', '2': 'patronclient.v2.client.Client', '3': 'patronclient.v2.client.Client', } try: client_path = version_map[str(version)] except (KeyError, ValueError): msg = _("Invalid client version '%(version)s'. must be one of: " "%(keys)s") % {'version': version, 'keys': ', '.join(version_map.keys())} raise exceptions.UnsupportedVersion(msg) return importutils.import_class(client_path)
def save(self, auth_token, management_url, tenant_id): if not HAS_KEYRING or not self.args.os_cache: return if (auth_token == self.auth_token and management_url == self.management_url): # Nothing changed.... return if not all([management_url, auth_token, tenant_id]): raise ValueError( _("Unable to save empty management url/auth " "token")) value = "|".join( [str(auth_token), str(management_url), str(tenant_id)]) keyring.set_password("patronclient_auth", self._make_key(), value)
def _server_evacuate(cs, server, args): success = True error_message = "" try: cs.servers.evacuate(server=server['uuid'], host=args.target_host, on_shared_storage=args.on_shared_storage) except Exception as e: success = False error_message = _("Error while evacuating instance: %s") % e return EvacuateHostResponse( base.Manager, { "server_uuid": server['uuid'], "evacuate_accepted": success, "error_message": error_message })
def _server_live_migrate(cs, server, args): class HostEvacuateLiveResponse(object): def __init__(self, server_uuid, live_migration_accepted, error_message): self.server_uuid = server_uuid self.live_migration_accepted = live_migration_accepted self.error_message = error_message success = True error_message = "" try: cs.servers.live_migrate(server['uuid'], args.target_host, args.block_migrate, args.disk_over_commit) except Exception as e: success = False error_message = _("Error while live migrating instance: %s") % e return HostEvacuateLiveResponse(server['uuid'], success, error_message)
def error(self, message): """error(message: string) Prints a usage message incorporating the message to stderr and exits. """ self.print_usage(sys.stderr) # FIXME(lzyeval): if changes occur in argparse.ArgParser._check_value choose_from = ' (choose from' progparts = self.prog.partition(' ') self.exit( 2, _("error: %(errmsg)s\nTry '%(mainp)s help %(subp)s'" " for more information.\n") % { 'errmsg': message.split(choose_from)[0], 'mainp': progparts[0], 'subp': progparts[2] })
def get_resource_manager_extra_kwargs(f, args, allow_conflicts=False): """Return extra_kwargs by calling resource manager kwargs hooks.""" hooks = getattr(f, "resource_manager_kwargs_hooks", []) extra_kwargs = {} for hook in hooks: hook_kwargs = hook(args) hook_name = hook.__name__ conflicting_keys = set(hook_kwargs.keys()) & set(extra_kwargs.keys()) if conflicting_keys and not allow_conflicts: msg = (_("Hook '%(hook_name)s' is attempting to redefine " "attributes '%(conflicting_keys)s'") % {'hook_name': hook_name, 'conflicting_keys': conflicting_keys}) raise exceptions.NoUniqueMatch(msg) extra_kwargs.update(hook_kwargs) return extra_kwargs
def disassociate(self, network, disassociate_host=True, disassociate_project=True): """ Disassociate a specific network from project and/or host. :param network: The ID of the :class:`Network`. :param disassociate_host: Whether to disassociate the host :param disassociate_project: Whether to disassociate the project """ if disassociate_host and disassociate_project: body = {"disassociate": None} elif disassociate_project: body = {"disassociate_project": None} elif disassociate_host: body = {"disassociate_host": None} else: raise exceptions.CommandError( _("Must disassociate either host or project or both")) self.api.client.post("/os-networks/%s/action" % base.getid(network), body=body)
patron setpolicy """ return self.api.client.post("/os-patron-access/setlabel", **kwargs) def getlabel(self, **kwargs): """ patron setpolicy """ return self.api.client.get("/os-patron-access/getlabel", **kwargs) @cliutils.arg( '--op', metavar='<op>', help=_('User op for example:\n\tcompute_extension:admin_actions')) def do_verify(cs, args): """patron verify. Args:op. For example:\n\tcompute_extension:admin_actions""" ans = cs.patron_access.verify(json = {'op': args.op}) print ans @cliutils.arg( '--file', metavar='<file>', help=_('User policy file path')) def do_setpolicy(cs, args): """patron setpolicy. Args:policy.""" #check file exists? if os.path.exists(args.file) and os.path.isfile(args.file) : policy = open(args.file, 'r') obj = dict(json.loads(policy.read()))
def _list_by_tenant(self, tenant): """Print flavor list shared with the given tenant.""" # TODO(uni): need to figure out a proper URI for list_by_tenant # since current API already provided current tenant_id information raise NotImplementedError(_('Sorry, query by tenant not supported.'))
def setlabel(self, **kwargs): """ patron setpolicy """ return self.api.client.post("/os-patron-access/setlabel", **kwargs) def getlabel(self, **kwargs): """ patron setpolicy """ return self.api.client.get("/os-patron-access/getlabel", **kwargs) @cliutils.arg('--op', metavar='<op>', help=_('User op for example:\n\tcompute_extension:admin_actions') ) def do_verify(cs, args): """patron verify. Args:op. For example:\n\tcompute_extension:admin_actions""" ans = cs.patron_access.verify(json={'op': args.op}) print ans @cliutils.arg('--file', metavar='<file>', help=_('User policy file path')) def do_setpolicy(cs, args): """patron setpolicy. Args:policy.""" #check file exists? if os.path.exists(args.file) and os.path.isfile(args.file): policy = open(args.file, 'r') obj = dict(json.loads(policy.read())) ans = cs.patron_access.setpolicy(json={'policy': obj})
# # 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 patronclient.i18n import _ from patronclient.openstack.common import cliutils from patronclient.v2 import shell @cliutils.arg( 'host', metavar='<host>', help=_('Name of host.')) @cliutils.arg( 'action', metavar='<action>', choices=['set', 'delete'], help=_("Actions: 'set' or 'delete'")) @cliutils.arg( 'metadata', metavar='<key=value>', nargs='+', action='append', default=[], help=_('Metadata to set or delete (only key is necessary on delete)')) def do_host_meta(cs, args): """Set or Delete metadata on all instances of a host.""" hypervisors = cs.hypervisors.search(args.host, servers=True)
""" return self._get("/servers/%s/os-instance-actions/%s" % (base.getid(server), request_id), 'instanceAction') def list(self, server): """ Get a list of actions performed on an server. """ return self._list('/servers/%s/os-instance-actions' % base.getid(server), 'instanceActions') @cliutils.arg( 'server', metavar='<server>', help=_('Name or UUID of the server to show an action for.')) @cliutils.arg( 'request_id', metavar='<request_id>', help=_('Request ID of the action to get.')) def do_instance_action(cs, args): """Show an action.""" server = utils.find_resource(cs.servers, args.server) action_resource = cs.instance_action.get(server, args.request_id) action = action_resource._info if 'events' in action: action['events'] = pprint.pformat(action['events']) utils.print_dict(action) @cliutils.arg(
return self._get( "/servers/%s/os-instance-actions/%s" % (base.getid(server), request_id), 'instanceAction') def list(self, server): """ Get a list of actions performed on an server. """ return self._list( '/servers/%s/os-instance-actions' % base.getid(server), 'instanceActions') @cliutils.arg('server', metavar='<server>', help=_('Name or UUID of the server to show an action for.')) @cliutils.arg('request_id', metavar='<request_id>', help=_('Request ID of the action to get.')) def do_instance_action(cs, args): """Show an action.""" server = utils.find_resource(cs.servers, args.server) action_resource = cs.instance_action.get(server, args.request_id) action = action_resource._info if 'events' in action: action['events'] = pprint.pformat(action['events']) utils.print_dict(action) @cliutils.arg('server', metavar='<server>',
opts['cell_name'] = cell_name # Transform the dict to a sequence of two-element tuples in fixed # order, then the encoded string will be consistent in Python 2&3. new_opts = sorted(opts.items(), key=lambda x: x[0]) query_string = "?%s" % parse.urlencode(new_opts) if new_opts else "" return self._list("/os-migrations%s" % query_string, "migrations") @cliutils.arg( '--host', dest='host', metavar='<host>', help=_('Fetch migrations for the given host.')) @cliutils.arg( '--status', dest='status', metavar='<status>', help=_('Fetch migrations for the given status.')) @cliutils.arg( '--cell_name', dest='cell_name', metavar='<cell_name>', help=_('Fetch migrations for the given cell_name.')) def do_migration_list(cs, args): """Print a list of migrations.""" _print_migrations(cs.migrations.list(args.host, args.status, args.cell_name))
def capacities(self, cell_name=None): """ Get capacities for a cell. :param cell_name: Name of the :class:`Cell` to get capacities for. :rtype: :class:`Cell` """ path = ["%s/capacities" % cell_name, "capacities"][cell_name is None] return self._get("/os-cells/%s" % path, "cell") @cliutils.arg( 'cell', metavar='<cell-name>', help=_('Name of the cell.')) def do_cell_show(cs, args): """Show details of a given cell.""" cell = cs.cells.get(args.cell) utils.print_dict(cell._info) @cliutils.arg( '--cell', metavar='<cell-name>', help=_("Name of the cell to get the capacities."), default=None) def do_cell_capacities(cs, args): """Get cell capacities for all cells or a given cell.""" cell = cs.cells.capacities(args.cell) print(_("Ram Available: %s MB") % cell.capacities['ram_free']['total_mb'])
def do_net_list(cs, args): """ DEPRECATED, use tenant-network-list instead. """ do_tenant_network_list(cs, args) def do_tenant_network_list(cs, args): """ List tenant networks. """ networks = cs.tenant_networks.list() utils.print_list(networks, ["ID", "Label", "CIDR"]) @cliutils.arg("label", metavar="<network_label>", help=_("Network label (ex. my_new_network)")) @cliutils.arg("cidr", metavar="<cidr>", help=_("IP block to allocate from (ex. 172.16.0.0/24 or 2001:DB8::/64)")) def do_net_create(cs, args): """ DEPRECATED, use tenant-network-create instead. """ do_tenant_network_create(cs, args) @cliutils.arg("label", metavar="<network_label>", help=_("Network label (ex. my_new_network)")) @cliutils.arg("cidr", metavar="<cidr>", help=_("IP block to allocate from (ex. 172.16.0.0/24 or 2001:DB8::/64)")) def do_tenant_network_create(cs, args): """ Create a tenant network. """ network = cs.tenant_networks.create(args.label, args.cidr)
cs.servers.live_migrate(server['uuid'], args.target_host, args.block_migrate, args.disk_over_commit) except Exception as e: success = False error_message = _("Error while live migrating instance: %s") % e return HostEvacuateLiveResponse(server['uuid'], success, error_message) @cliutils.arg('host', metavar='<host>', help='Name of host.') @cliutils.arg( '--target-host', metavar='<target_host>', default=None, help=_('Name of target host.')) @cliutils.arg( '--block-migrate', action='store_true', default=False, help=_('Enable block migration.')) @cliutils.arg( '--disk-over-commit', action='store_true', default=False, help=_('Enable disk overcommit.')) def do_host_evacuate_live(cs, args): """Live migrate all instances of the specified host to other available hosts. """ hypervisors = cs.hypervisors.search(args.host, servers=True)
def authenticate(self): if not self.auth_url: msg = _("Authentication requires 'auth_url', which should be " "specified in '%s'") % self.__class__.__name__ raise exceptions.AuthorizationFailure(msg) magic_tuple = netutils.urlsplit(self.auth_url) scheme, netloc, path, query, frag = magic_tuple port = magic_tuple.port if port is None: port = 80 path_parts = path.split('/') for part in path_parts: if len(part) > 0 and part[0] == 'v': self.version = part break if self.auth_token and self.management_url: self._save_keys() return # TODO(sandy): Assume admin endpoint is 35357 for now. # Ideally this is going to have to be provided by the service catalog. new_netloc = netloc.replace(':%d' % port, ':%d' % (35357,)) admin_url = parse.urlunsplit( (scheme, new_netloc, path, query, frag)) auth_url = self.auth_url if self.version == "v2.0": # FIXME(chris): This should be better. while auth_url: if not self.auth_system or self.auth_system == 'keystone': auth_url = self._v2_auth(auth_url) else: auth_url = self._plugin_auth(auth_url) # Are we acting on behalf of another user via an # existing token? If so, our actual endpoints may # be different than that of the admin token. if self.proxy_token: if self.bypass_url: self.set_management_url(self.bypass_url) else: self._fetch_endpoints_from_auth(admin_url) # Since keystone no longer returns the user token # with the endpoints any more, we need to replace # our service account token with the user token. self.auth_token = self.proxy_token else: try: while auth_url: auth_url = self._v1_auth(auth_url) # In some configurations patron makes redirection to # v2.0 keystone endpoint. Also, new location does not contain # real endpoint, only hostname and port. except exceptions.AuthorizationFailure: if auth_url.find('v2.0') < 0: auth_url = auth_url + '/v2.0' self._v2_auth(auth_url) if self.bypass_url: self.set_management_url(self.bypass_url) elif not self.management_url: raise exceptions.Unauthorized('Patron Client') self._save_keys()
def _boot(self, resource_url, response_key, name, image, flavor, meta=None, files=None, userdata=None, reservation_id=None, return_raw=False, min_count=None, max_count=None, security_groups=None, key_name=None, availability_zone=None, block_device_mapping=None, block_device_mapping_v2=None, nics=None, scheduler_hints=None, config_drive=None, admin_pass=None, disk_config=None, **kwargs): """ Create (boot) a new server. :param name: Something to name the server. :param image: The :class:`Image` to boot with. :param flavor: The :class:`Flavor` to boot onto. :param meta: A dict of arbitrary key/value metadata to store for this server. A maximum of five entries is allowed, and both keys and values must be 255 characters or less. :param files: A dict of files to overwrite on the server upon boot. Keys are file names (i.e. ``/etc/passwd``) and values are the file contents (either as a string or as a file-like object). A maximum of five entries is allowed, and each file must be 10k or less. :param reservation_id: a UUID for the set of servers being requested. :param return_raw: If True, don't try to coerce the result into a Resource object. :param security_groups: list of security group names :param key_name: (optional extension) name of keypair to inject into the instance :param availability_zone: Name of the availability zone for instance placement. :param block_device_mapping: A dict of block device mappings for this server. :param block_device_mapping_v2: A dict of block device mappings V2 for this server. :param nics: (optional extension) an ordered list of nics to be added to this server, with information about connected networks, fixed IPs, etc. :param scheduler_hints: (optional extension) arbitrary key-value pairs specified by the client to help boot an instance. :param config_drive: (optional extension) If True, enable config drive on the server. :param admin_pass: admin password for the server. :param disk_config: (optional extension) control how the disk is partitioned when the server is created. """ body = { "server": { "name": name, "imageRef": str(base.getid(image)) if image else '', "flavorRef": str(base.getid(flavor)), } } if userdata: if hasattr(userdata, 'read'): userdata = userdata.read() if six.PY3: userdata = userdata.encode("utf-8") else: userdata = encodeutils.safe_encode(userdata) userdata_b64 = base64.b64encode(userdata).decode('utf-8') body["server"]["user_data"] = userdata_b64 if meta: body["server"]["metadata"] = meta if reservation_id: body["server"]["reservation_id"] = reservation_id if key_name: body["server"]["key_name"] = key_name if scheduler_hints: body['os:scheduler_hints'] = scheduler_hints if config_drive: body["server"]["config_drive"] = config_drive if admin_pass: body["server"]["adminPass"] = admin_pass if not min_count: min_count = 1 if not max_count: max_count = min_count body["server"]["min_count"] = min_count body["server"]["max_count"] = max_count if security_groups: body["server"]["security_groups"] = [{ 'name': sg } for sg in security_groups] # Files are a slight bit tricky. They're passed in a "personality" # list to the POST. Each item is a dict giving a file name and the # base64-encoded contents of the file. We want to allow passing # either an open file *or* some contents as files here. if files: personality = body['server']['personality'] = [] for filepath, file_or_string in sorted(files.items(), key=lambda x: x[0]): if hasattr(file_or_string, 'read'): data = file_or_string.read() else: data = file_or_string if six.PY3 and isinstance(data, str): data = data.encode('utf-8') cont = base64.b64encode(data).decode('utf-8') personality.append({ 'path': filepath, 'contents': cont, }) if availability_zone: body["server"]["availability_zone"] = availability_zone # Block device mappings are passed as a list of dictionaries if block_device_mapping: body['server']['block_device_mapping'] = \ self._parse_block_device_mapping(block_device_mapping) elif block_device_mapping_v2: body['server']['block_device_mapping_v2'] = block_device_mapping_v2 if nics is not None: # NOTE(tr3buchet): nics can be an empty list all_net_data = [] for nic_info in nics: net_data = {} # if value is empty string, do not send value in body if nic_info.get('net-id'): net_data['uuid'] = nic_info['net-id'] if (nic_info.get('v4-fixed-ip') and nic_info.get('v6-fixed-ip')): raise base.exceptions.CommandError( _("Only one of 'v4-fixed-ip' and 'v6-fixed-ip' may be" " provided.")) elif nic_info.get('v4-fixed-ip'): net_data['fixed_ip'] = nic_info['v4-fixed-ip'] elif nic_info.get('v6-fixed-ip'): net_data['fixed_ip'] = nic_info['v6-fixed-ip'] if nic_info.get('port-id'): net_data['port'] = nic_info['port-id'] all_net_data.append(net_data) body['server']['networks'] = all_net_data if disk_config is not None: body['server']['OS-DCF:diskConfig'] = disk_config return self._create(resource_url, body, response_key, return_raw=return_raw, **kwargs)
def main(self, 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) # Discover available auth plugins patronclient.auth_plugin.discover_auth_systems() # build available subcommands based on version self.extensions = self._discover_extensions( options.os_compute_api_version) self._run_extension_hooks('__pre_parse_args__') # 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' subcommand_parser = self.get_subcommand_parser( options.os_compute_api_version) self.parser = subcommand_parser if options.help or not argv: subcommand_parser.print_help() return 0 args = subcommand_parser.parse_args(argv) self._run_extension_hooks('__post_parse_args__', args) # Short-circuit and deal with help right away. if 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 os_username = args.os_username os_user_id = args.os_user_id os_password = None # Fetched and set later as needed os_tenant_name = args.os_tenant_name os_tenant_id = args.os_tenant_id os_auth_url = args.os_auth_url os_region_name = args.os_region_name os_auth_system = args.os_auth_system endpoint_type = args.endpoint_type insecure = args.insecure service_type = args.service_type service_name = args.service_name volume_service_name = args.volume_service_name bypass_url = args.bypass_url os_cache = args.os_cache cacert = args.os_cacert timeout = args.timeout keystone_session = None keystone_auth = None # We may have either, both or none of these. # If we have both, we don't need USERNAME, PASSWORD etc. # Fill in the blanks from the SecretsHelper if possible. # Finally, authenticate unless we have both. # Note if we don't auth we probably don't have a tenant ID so we can't # cache the token. auth_token = args.os_auth_token if args.os_auth_token else None management_url = bypass_url if bypass_url else None if os_auth_system and os_auth_system != "keystone": auth_plugin = patronclient.auth_plugin.load_plugin(os_auth_system) else: auth_plugin = None if not endpoint_type: endpoint_type = DEFAULT_PATRON_ENDPOINT_TYPE # This allow users to use endpoint_type as (internal, public or admin) # just like other openstack clients (glance, cinder etc) if endpoint_type in ['internal', 'public', 'admin']: endpoint_type += 'URL' if not service_type: os_compute_api_version = (options.os_compute_api_version or DEFAULT_OS_COMPUTE_API_VERSION) try: service_type = DEFAULT_PATRON_SERVICE_TYPE_MAP[ os_compute_api_version] except KeyError: service_type = DEFAULT_PATRON_SERVICE_TYPE_MAP[ DEFAULT_OS_COMPUTE_API_VERSION] service_type = cliutils.get_service_type(args.func) or service_type # If we have an auth token but no management_url, we must auth anyway. # Expired tokens are handled by client.py:_cs_request must_auth = not (cliutils.isunauthenticated(args.func) or (auth_token and management_url)) # Do not use Keystone session for cases with no session support. The # presence of auth_plugin means os_auth_system is present and is not # keystone. use_session = True if auth_plugin or bypass_url or os_cache or volume_service_name: use_session = False # FIXME(usrleon): Here should be restrict for project id same as # for os_username or os_password but for compatibility it is not. if must_auth: if auth_plugin: auth_plugin.parse_opts(args) if not auth_plugin or not auth_plugin.opts: if not os_username and not os_user_id: raise exc.CommandError( _("You must provide a username " "or user id via --os-username, --os-user-id, " "env[OS_USERNAME] or env[OS_USER_ID]")) if not any([ args.os_tenant_name, args.os_tenant_id, args.os_project_id, args.os_project_name ]): raise exc.CommandError( _("You must provide a project name or" " project id via --os-project-name," " --os-project-id, env[OS_PROJECT_ID]" " or env[OS_PROJECT_NAME]. You may" " use os-project and os-tenant" " interchangeably.")) if not os_auth_url: if os_auth_system and os_auth_system != 'keystone': os_auth_url = auth_plugin.get_auth_url() if not os_auth_url: raise exc.CommandError( _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL] " "or specify an auth_system which defines a " "default url with --os-auth-system " "or env[OS_AUTH_SYSTEM]")) project_id = args.os_project_id or args.os_tenant_id project_name = args.os_project_name or args.os_tenant_name if use_session: # Not using Patron auth plugin, so use keystone start_time = time.time() keystone_session = ksession.Session.load_from_cli_options(args) keystone_auth = self._get_keystone_auth( keystone_session, args.os_auth_url, username=args.os_username, user_id=args.os_user_id, user_domain_id=args.os_user_domain_id, user_domain_name=args.os_user_domain_name, password=args.os_password, auth_token=args.os_auth_token, project_id=project_id, project_name=project_name, project_domain_id=args.os_project_domain_id, project_domain_name=args.os_project_domain_name) end_time = time.time() self.times.append(('%s %s' % ('auth_url', args.os_auth_url), start_time, end_time)) if (options.os_compute_api_version and options.os_compute_api_version != '1.0'): if not any([ args.os_tenant_id, args.os_tenant_name, args.os_project_id, args.os_project_name ]): raise exc.CommandError( _("You must provide a project name or" " project id via --os-project-name," " --os-project-id, env[OS_PROJECT_ID]" " or env[OS_PROJECT_NAME]. You may" " use os-project and os-tenant" " interchangeably.")) if not os_auth_url: raise exc.CommandError( _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL]")) self.cs = client.Client(options.os_compute_api_version, os_username, os_password, os_tenant_name, tenant_id=os_tenant_id, user_id=os_user_id, auth_url=os_auth_url, insecure=insecure, region_name=os_region_name, endpoint_type=endpoint_type, extensions=self.extensions, service_type=service_type, service_name=service_name, auth_system=os_auth_system, auth_plugin=auth_plugin, auth_token=auth_token, volume_service_name=volume_service_name, timings=args.timings, bypass_url=bypass_url, os_cache=os_cache, http_log_debug=options.debug, cacert=cacert, timeout=timeout, session=keystone_session, auth=keystone_auth) # Now check for the password/token of which pieces of the # identifying keyring key can come from the underlying client if must_auth: helper = SecretsHelper(args, self.cs.client) if (auth_plugin and auth_plugin.opts and "os_password" not in auth_plugin.opts): use_pw = False else: use_pw = True tenant_id = helper.tenant_id # Allow commandline to override cache if not auth_token: auth_token = helper.auth_token if not management_url: management_url = helper.management_url if tenant_id and auth_token and management_url: self.cs.client.tenant_id = tenant_id self.cs.client.auth_token = auth_token self.cs.client.management_url = management_url self.cs.client.password_func = lambda: helper.password elif use_pw: # We're missing something, so auth with user/pass and save # the result in our helper. self.cs.client.password = helper.password self.cs.client.keyring_saver = helper try: # This does a couple of bits which are useful even if we've # got the token + service URL already. It exits fast in that case. if not cliutils.isunauthenticated(args.func): if not use_session: # Only call authenticate() if Patron auth plugin is used. # If keystone is used, authentication is handled as part # of session. self.cs.authenticate() except exc.Unauthorized: raise exc.CommandError(_("Invalid OpenStack Patron credentials.")) except exc.AuthorizationFailure: raise exc.CommandError(_("Unable to authorize user")) if options.os_compute_api_version == "3" and service_type != 'image': # NOTE(cyeoh): create an image based client because the # images api is no longer proxied by the V3 API and we # sometimes need to be able to look up images information # via glance when connected to the patron api. image_service_type = 'image' # NOTE(hdd): the password is needed again because creating a new # Client without specifying bypass_url will force authentication. # We can't reuse self.cs's bypass_url, because that's the URL for # the patron service; we need to get glance's URL for this Client if not os_password: os_password = helper.password self.cs.image_cs = client.Client( options.os_compute_api_version, os_username, os_password, os_tenant_name, tenant_id=os_tenant_id, auth_url=os_auth_url, insecure=insecure, region_name=os_region_name, endpoint_type=endpoint_type, extensions=self.extensions, service_type=image_service_type, service_name=service_name, auth_system=os_auth_system, auth_plugin=auth_plugin, volume_service_name=volume_service_name, timings=args.timings, bypass_url=bypass_url, os_cache=os_cache, http_log_debug=options.debug, session=keystone_session, auth=keystone_auth, cacert=cacert, timeout=timeout) args.func(self.cs, args) if args.timings: self._dump_timings(self.times + self.cs.get_timings())
def get_base_parser(self): parser = patronclientArgumentParser( prog='patron', description=__doc__.strip(), epilog='See "patron 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=patronclient.__version__) 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), True), action='store_true', help=_("Use the auth token cache. Defaults to False if " "env[OS_CACHE] is not set.")) parser.add_argument( '--timings', default=False, action='store_true', help=_("Print call timing info")) parser.add_argument( '--os-auth-token', default=cliutils.env('OS_AUTH_TOKEN'), help='Defaults to env[OS_AUTH_TOKEN]') parser.add_argument( '--os_username', help=argparse.SUPPRESS) parser.add_argument( '--os_password', help=argparse.SUPPRESS) parser.add_argument( '--os-tenant-name', metavar='<auth-tenant-name>', default=cliutils.env('OS_TENANT_NAME', 'PATRON_PROJECT_ID'), help=_('Defaults to env[OS_TENANT_NAME].')) parser.add_argument( '--os_tenant_name', help=argparse.SUPPRESS) parser.add_argument( '--os-tenant-id', metavar='<auth-tenant-id>', default=cliutils.env('OS_TENANT_ID'), help=_('Defaults to env[OS_TENANT_ID].')) parser.add_argument( '--os_auth_url', help=argparse.SUPPRESS) parser.add_argument( '--os-region-name', metavar='<region-name>', default=cliutils.env('OS_REGION_NAME', 'PATRON_REGION_NAME'), help=_('Defaults to env[OS_REGION_NAME].')) parser.add_argument( '--os_region_name', help=argparse.SUPPRESS) parser.add_argument( '--os-auth-system', metavar='<auth-system>', default=cliutils.env('OS_AUTH_SYSTEM'), help='Defaults to env[OS_AUTH_SYSTEM].') parser.add_argument( '--os_auth_system', help=argparse.SUPPRESS) parser.add_argument( '--service-type', metavar='<service-type>', help=_('Defaults to compute for most actions')) parser.add_argument( '--service_type', help=argparse.SUPPRESS) parser.add_argument( '--service-name', metavar='<service-name>', default=cliutils.env('PATRON_SERVICE_NAME'), help=_('Defaults to env[PATRON_SERVICE_NAME]')) parser.add_argument( '--service_name', help=argparse.SUPPRESS) parser.add_argument( '--volume-service-name', metavar='<volume-service-name>', default=cliutils.env('PATRON_VOLUME_SERVICE_NAME'), help=_('Defaults to env[PATRON_VOLUME_SERVICE_NAME]')) parser.add_argument( '--volume_service_name', help=argparse.SUPPRESS) parser.add_argument( '--os-endpoint-type', metavar='<endpoint-type>', dest='endpoint_type', default=cliutils.env( 'PATRON_ENDPOINT_TYPE', default=cliutils.env( 'OS_ENDPOINT_TYPE', default=DEFAULT_PATRON_ENDPOINT_TYPE)), help=_('Defaults to env[PATRON_ENDPOINT_TYPE], ' 'env[OS_ENDPOINT_TYPE] or ') + DEFAULT_PATRON_ENDPOINT_TYPE + '.') parser.add_argument( '--endpoint-type', help=argparse.SUPPRESS) # 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( '--os-compute-api-version', metavar='<compute-api-ver>', default=cliutils.env('OS_COMPUTE_API_VERSION', default=DEFAULT_OS_COMPUTE_API_VERSION), help=_('Accepts 1.1 or 3, ' 'defaults to env[OS_COMPUTE_API_VERSION].')) parser.add_argument( '--os_compute_api_version', help=argparse.SUPPRESS) parser.add_argument( '--bypass-url', metavar='<bypass-url>', dest='bypass_url', default=cliutils.env('patronclient_BYPASS_URL'), help="Use this API endpoint instead of the Service Catalog. " "Defaults to env[patronclient_BYPASS_URL]") parser.add_argument('--bypass_url', help=argparse.SUPPRESS) # The auth-system-plugins might require some extra options patronclient.auth_plugin.load_auth_system_opts(parser) self._append_global_identity_args(parser) return parser
def main(self, 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) # Discover available auth plugins patronclient.auth_plugin.discover_auth_systems() # build available subcommands based on version self.extensions = self._discover_extensions( options.os_compute_api_version) self._run_extension_hooks('__pre_parse_args__') # 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' subcommand_parser = self.get_subcommand_parser( options.os_compute_api_version) self.parser = subcommand_parser if options.help or not argv: subcommand_parser.print_help() return 0 args = subcommand_parser.parse_args(argv) self._run_extension_hooks('__post_parse_args__', args) # Short-circuit and deal with help right away. if 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 os_username = args.os_username os_user_id = args.os_user_id os_password = None # Fetched and set later as needed os_tenant_name = args.os_tenant_name os_tenant_id = args.os_tenant_id os_auth_url = args.os_auth_url os_region_name = args.os_region_name os_auth_system = args.os_auth_system endpoint_type = args.endpoint_type insecure = args.insecure service_type = args.service_type service_name = args.service_name volume_service_name = args.volume_service_name bypass_url = args.bypass_url os_cache = args.os_cache cacert = args.os_cacert timeout = args.timeout keystone_session = None keystone_auth = None # We may have either, both or none of these. # If we have both, we don't need USERNAME, PASSWORD etc. # Fill in the blanks from the SecretsHelper if possible. # Finally, authenticate unless we have both. # Note if we don't auth we probably don't have a tenant ID so we can't # cache the token. auth_token = args.os_auth_token if args.os_auth_token else None management_url = bypass_url if bypass_url else None if os_auth_system and os_auth_system != "keystone": auth_plugin = patronclient.auth_plugin.load_plugin(os_auth_system) else: auth_plugin = None if not endpoint_type: endpoint_type = DEFAULT_PATRON_ENDPOINT_TYPE # This allow users to use endpoint_type as (internal, public or admin) # just like other openstack clients (glance, cinder etc) if endpoint_type in ['internal', 'public', 'admin']: endpoint_type += 'URL' if not service_type: os_compute_api_version = (options.os_compute_api_version or DEFAULT_OS_COMPUTE_API_VERSION) try: service_type = DEFAULT_PATRON_SERVICE_TYPE_MAP[ os_compute_api_version] except KeyError: service_type = DEFAULT_PATRON_SERVICE_TYPE_MAP[ DEFAULT_OS_COMPUTE_API_VERSION] service_type = cliutils.get_service_type(args.func) or service_type # If we have an auth token but no management_url, we must auth anyway. # Expired tokens are handled by client.py:_cs_request must_auth = not (cliutils.isunauthenticated(args.func) or (auth_token and management_url)) # Do not use Keystone session for cases with no session support. The # presence of auth_plugin means os_auth_system is present and is not # keystone. use_session = True if auth_plugin or bypass_url or os_cache or volume_service_name: use_session = False # FIXME(usrleon): Here should be restrict for project id same as # for os_username or os_password but for compatibility it is not. if must_auth: if auth_plugin: auth_plugin.parse_opts(args) if not auth_plugin or not auth_plugin.opts: if not os_username and not os_user_id: raise exc.CommandError( _("You must provide a username " "or user id via --os-username, --os-user-id, " "env[OS_USERNAME] or env[OS_USER_ID]")) if not any([args.os_tenant_name, args.os_tenant_id, args.os_project_id, args.os_project_name]): raise exc.CommandError(_("You must provide a project name or" " project id via --os-project-name," " --os-project-id, env[OS_PROJECT_ID]" " or env[OS_PROJECT_NAME]. You may" " use os-project and os-tenant" " interchangeably.")) if not os_auth_url: if os_auth_system and os_auth_system != 'keystone': os_auth_url = auth_plugin.get_auth_url() if not os_auth_url: raise exc.CommandError( _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL] " "or specify an auth_system which defines a " "default url with --os-auth-system " "or env[OS_AUTH_SYSTEM]")) project_id = args.os_project_id or args.os_tenant_id project_name = args.os_project_name or args.os_tenant_name if use_session: # Not using Patron auth plugin, so use keystone start_time = time.time() keystone_session = ksession.Session.load_from_cli_options(args) keystone_auth = self._get_keystone_auth( keystone_session, args.os_auth_url, username=args.os_username, user_id=args.os_user_id, user_domain_id=args.os_user_domain_id, user_domain_name=args.os_user_domain_name, password=args.os_password, auth_token=args.os_auth_token, project_id=project_id, project_name=project_name, project_domain_id=args.os_project_domain_id, project_domain_name=args.os_project_domain_name) end_time = time.time() self.times.append( ('%s %s' % ('auth_url', args.os_auth_url), start_time, end_time)) if (options.os_compute_api_version and options.os_compute_api_version != '1.0'): if not any([args.os_tenant_id, args.os_tenant_name, args.os_project_id, args.os_project_name]): raise exc.CommandError(_("You must provide a project name or" " project id via --os-project-name," " --os-project-id, env[OS_PROJECT_ID]" " or env[OS_PROJECT_NAME]. You may" " use os-project and os-tenant" " interchangeably.")) if not os_auth_url: raise exc.CommandError( _("You must provide an auth url " "via either --os-auth-url or env[OS_AUTH_URL]")) self.cs = client.Client( options.os_compute_api_version, os_username, os_password, os_tenant_name, tenant_id=os_tenant_id, user_id=os_user_id, auth_url=os_auth_url, insecure=insecure, region_name=os_region_name, endpoint_type=endpoint_type, extensions=self.extensions, service_type=service_type, service_name=service_name, auth_system=os_auth_system, auth_plugin=auth_plugin, auth_token=auth_token, volume_service_name=volume_service_name, timings=args.timings, bypass_url=bypass_url, os_cache=os_cache, http_log_debug=options.debug, cacert=cacert, timeout=timeout, session=keystone_session, auth=keystone_auth) # Now check for the password/token of which pieces of the # identifying keyring key can come from the underlying client if must_auth: helper = SecretsHelper(args, self.cs.client) if (auth_plugin and auth_plugin.opts and "os_password" not in auth_plugin.opts): use_pw = False else: use_pw = True tenant_id = helper.tenant_id # Allow commandline to override cache if not auth_token: auth_token = helper.auth_token if not management_url: management_url = helper.management_url if tenant_id and auth_token and management_url: self.cs.client.tenant_id = tenant_id self.cs.client.auth_token = auth_token self.cs.client.management_url = management_url self.cs.client.password_func = lambda: helper.password elif use_pw: # We're missing something, so auth with user/pass and save # the result in our helper. self.cs.client.password = helper.password self.cs.client.keyring_saver = helper try: # This does a couple of bits which are useful even if we've # got the token + service URL already. It exits fast in that case. if not cliutils.isunauthenticated(args.func): if not use_session: # Only call authenticate() if Patron auth plugin is used. # If keystone is used, authentication is handled as part # of session. self.cs.authenticate() except exc.Unauthorized: raise exc.CommandError(_("Invalid OpenStack Patron credentials.")) except exc.AuthorizationFailure: raise exc.CommandError(_("Unable to authorize user")) if options.os_compute_api_version == "3" and service_type != 'image': # NOTE(cyeoh): create an image based client because the # images api is no longer proxied by the V3 API and we # sometimes need to be able to look up images information # via glance when connected to the patron api. image_service_type = 'image' # NOTE(hdd): the password is needed again because creating a new # Client without specifying bypass_url will force authentication. # We can't reuse self.cs's bypass_url, because that's the URL for # the patron service; we need to get glance's URL for this Client if not os_password: os_password = helper.password self.cs.image_cs = client.Client( options.os_compute_api_version, os_username, os_password, os_tenant_name, tenant_id=os_tenant_id, auth_url=os_auth_url, insecure=insecure, region_name=os_region_name, endpoint_type=endpoint_type, extensions=self.extensions, service_type=image_service_type, service_name=service_name, auth_system=os_auth_system, auth_plugin=auth_plugin, volume_service_name=volume_service_name, timings=args.timings, bypass_url=bypass_url, os_cache=os_cache, http_log_debug=options.debug, session=keystone_session, auth=keystone_auth, cacert=cacert, timeout=timeout) args.func(self.cs, args) if args.timings: self._dump_timings(self.times + self.cs.get_timings())
:param node_id: The ID of the node to list. :rtype: list """ interfaces = [] node = self._get("/os-baremetal-nodes/%s" % node_id, 'node') for interface in node.interfaces: interface_object = BareMetalNodeInterface(self, interface) interfaces.append(interface_object) return interfaces @cliutils.arg( 'service_host', metavar='<service_host>', help=_('Name of patron compute host which will control this baremetal ' 'node')) @cliutils.arg( 'cpus', metavar='<cpus>', type=int, help=_('Number of CPUs in the node')) @cliutils.arg( 'memory_mb', metavar='<memory_mb>', type=int, help=_('Megabytes of RAM in the node')) @cliutils.arg( 'local_gb', metavar='<local_gb>', type=int, help=_('Gigabytes of local storage in the node'))
success = False error_message = _("Error while evacuating instance: %s") % e return EvacuateHostResponse( base.Manager, { "server_uuid": server['uuid'], "evacuate_accepted": success, "error_message": error_message }) @cliutils.arg('host', metavar='<host>', help='Name of host.') @cliutils.arg( '--target_host', metavar='<target_host>', default=None, help=_('Name of target host. If no host is specified the scheduler will ' 'select a target.')) @cliutils.arg( '--on-shared-storage', dest='on_shared_storage', action="store_true", default=False, help=_('Specifies whether all instances files are on shared storage')) def do_host_evacuate(cs, args): """Evacuate all instances from failed host.""" hypervisors = cs.hypervisors.search(args.host, servers=True) response = [] for hyper in hypervisors: if hasattr(hyper, 'servers'): for server in hyper.servers: response.append(_server_evacuate(cs, server, args))
def get_base_parser(self): parser = patronclientArgumentParser( prog='patron', description=__doc__.strip(), epilog='See "patron 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=patronclient.__version__) 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), True), action='store_true', help=_("Use the auth token cache. Defaults to False if " "env[OS_CACHE] is not set.")) parser.add_argument('--timings', default=False, action='store_true', help=_("Print call timing info")) parser.add_argument('--os-auth-token', default=cliutils.env('OS_AUTH_TOKEN'), help='Defaults to env[OS_AUTH_TOKEN]') parser.add_argument('--os_username', help=argparse.SUPPRESS) parser.add_argument('--os_password', help=argparse.SUPPRESS) parser.add_argument('--os-tenant-name', metavar='<auth-tenant-name>', default=cliutils.env('OS_TENANT_NAME', 'PATRON_PROJECT_ID'), help=_('Defaults to env[OS_TENANT_NAME].')) parser.add_argument('--os_tenant_name', help=argparse.SUPPRESS) parser.add_argument('--os-tenant-id', metavar='<auth-tenant-id>', default=cliutils.env('OS_TENANT_ID'), help=_('Defaults to env[OS_TENANT_ID].')) parser.add_argument('--os_auth_url', help=argparse.SUPPRESS) parser.add_argument('--os-region-name', metavar='<region-name>', default=cliutils.env('OS_REGION_NAME', 'PATRON_REGION_NAME'), help=_('Defaults to env[OS_REGION_NAME].')) parser.add_argument('--os_region_name', help=argparse.SUPPRESS) parser.add_argument('--os-auth-system', metavar='<auth-system>', default=cliutils.env('OS_AUTH_SYSTEM'), help='Defaults to env[OS_AUTH_SYSTEM].') parser.add_argument('--os_auth_system', help=argparse.SUPPRESS) parser.add_argument('--service-type', metavar='<service-type>', help=_('Defaults to compute for most actions')) parser.add_argument('--service_type', help=argparse.SUPPRESS) parser.add_argument('--service-name', metavar='<service-name>', default=cliutils.env('PATRON_SERVICE_NAME'), help=_('Defaults to env[PATRON_SERVICE_NAME]')) parser.add_argument('--service_name', help=argparse.SUPPRESS) parser.add_argument( '--volume-service-name', metavar='<volume-service-name>', default=cliutils.env('PATRON_VOLUME_SERVICE_NAME'), help=_('Defaults to env[PATRON_VOLUME_SERVICE_NAME]')) parser.add_argument('--volume_service_name', help=argparse.SUPPRESS) parser.add_argument('--os-endpoint-type', metavar='<endpoint-type>', dest='endpoint_type', default=cliutils.env( 'PATRON_ENDPOINT_TYPE', default=cliutils.env( 'OS_ENDPOINT_TYPE', default=DEFAULT_PATRON_ENDPOINT_TYPE)), help=_('Defaults to env[PATRON_ENDPOINT_TYPE], ' 'env[OS_ENDPOINT_TYPE] or ') + DEFAULT_PATRON_ENDPOINT_TYPE + '.') parser.add_argument('--endpoint-type', help=argparse.SUPPRESS) # 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('--os-compute-api-version', metavar='<compute-api-ver>', default=cliutils.env( 'OS_COMPUTE_API_VERSION', default=DEFAULT_OS_COMPUTE_API_VERSION), help=_('Accepts 1.1 or 3, ' 'defaults to env[OS_COMPUTE_API_VERSION].')) parser.add_argument('--os_compute_api_version', help=argparse.SUPPRESS) parser.add_argument( '--bypass-url', metavar='<bypass-url>', dest='bypass_url', default=cliutils.env('patronclient_BYPASS_URL'), help="Use this API endpoint instead of the Service Catalog. " "Defaults to env[patronclient_BYPASS_URL]") parser.add_argument('--bypass_url', help=argparse.SUPPRESS) # The auth-system-plugins might require some extra options patronclient.auth_plugin.load_auth_system_opts(parser) self._append_global_identity_args(parser) return parser
success = True error_message = "" try: cs.servers.live_migrate(server['uuid'], args.target_host, args.block_migrate, args.disk_over_commit) except Exception as e: success = False error_message = _("Error while live migrating instance: %s") % e return HostEvacuateLiveResponse(server['uuid'], success, error_message) @cliutils.arg('host', metavar='<host>', help='Name of host.') @cliutils.arg('--target-host', metavar='<target_host>', default=None, help=_('Name of target host.')) @cliutils.arg('--block-migrate', action='store_true', default=False, help=_('Enable block migration.')) @cliutils.arg('--disk-over-commit', action='store_true', default=False, help=_('Enable disk overcommit.')) def do_host_evacuate_live(cs, args): """Live migrate all instances of the specified host to other available hosts. """ hypervisors = cs.hypervisors.search(args.host, servers=True) response = [] for hyper in hypervisors:
""" do_tenant_network_list(cs, args) def do_tenant_network_list(cs, args): """ List tenant networks. """ networks = cs.tenant_networks.list() utils.print_list(networks, ['ID', 'Label', 'CIDR']) @cliutils.arg( 'label', metavar='<network_label>', help=_('Network label (ex. my_new_network)')) @cliutils.arg( 'cidr', metavar='<cidr>', help=_('IP block to allocate from (ex. 172.16.0.0/24 or 2001:DB8::/64)')) def do_net_create(cs, args): """ DEPRECATED, use tenant-network-create instead. """ do_tenant_network_create(cs, args) @cliutils.arg( 'label', metavar='<network_label>', help=_('Network label (ex. my_new_network)'))
on_shared_storage=args.on_shared_storage) except Exception as e: success = False error_message = _("Error while evacuating instance: %s") % e return EvacuateHostResponse(base.Manager, {"server_uuid": server['uuid'], "evacuate_accepted": success, "error_message": error_message}) @cliutils.arg('host', metavar='<host>', help='Name of host.') @cliutils.arg( '--target_host', metavar='<target_host>', default=None, help=_('Name of target host. If no host is specified the scheduler will ' 'select a target.')) @cliutils.arg( '--on-shared-storage', dest='on_shared_storage', action="store_true", default=False, help=_('Specifies whether all instances files are on shared storage')) def do_host_evacuate(cs, args): """Evacuate all instances from failed host.""" hypervisors = cs.hypervisors.search(args.host, servers=True) response = [] for hyper in hypervisors: if hasattr(hyper, 'servers'): for server in hyper.servers: response.append(_server_evacuate(cs, server, args))