def _resource_signal(heat_client, args): fields = {'stack_id': args.stack, 'resource_name': args.resource} data = args.data data_file = args.data_file if data and data_file: raise exc.CommandError( _('Should only specify one of data or ' 'data-file')) if data_file: data_url = heat_utils.normalise_file_path_to_url(data_file) data = request.urlopen(data_url).read() if data: try: data = jsonutils.loads(data) except ValueError as ex: raise exc.CommandError(_('Data should be in JSON format: %s') % ex) if not isinstance(data, dict): raise exc.CommandError(_('Data should be a JSON dict')) fields['data'] = data try: heat_client.resources.signal(**fields) except heat_exc.HTTPNotFound: raise exc.CommandError( _('Stack %(stack)s or resource %(resource)s ' 'not found.') % { 'stack': args.stack, 'resource': args.resource })
def take_action(self, parsed_args): self.log.debug("take_action(%s)", parsed_args) rows = [] columns = [ 'ID', 'Stack Name', 'Stack Status', 'Creation Time', 'Updated Time' ] heat_client = self.app.client_manager.orchestration for stack in parsed_args.stack: try: data = heat_client.stacks.get(stack_id=stack) except heat_exc.HTTPNotFound: raise exc.CommandError('Stack not found: %s' % stack) status = getattr(data, 'stack_status').lower() if status == 'update_in_progress': data = _stack_action( stack, parsed_args, heat_client, heat_client.actions.cancel_update ) rows += [utils.get_dict_properties(data.to_dict(), columns)] else: err = _("Stack %(id)s with status \'%(status)s\' " "not in cancelable state") % { 'id': stack, 'status': status} raise exc.CommandError(err) return (columns, rows)
def _stack_action(stack, parsed_args, heat_client, action, action_name=None): if parsed_args.wait: # find the last event to use as the marker events = event_utils.get_events(heat_client, stack_id=stack, event_args={'sort_dir': 'desc', 'limit': 1}) marker = events[0].id if events else None try: action(stack) except heat_exc.HTTPNotFound: msg = _('Stack not found: %s') % stack raise exc.CommandError(msg) if parsed_args.wait: s = heat_client.stacks.get(stack) stack_status, msg = event_utils.poll_for_events( heat_client, s.stack_name, action=action_name, marker=marker) if action_name: if stack_status == '%s_FAILED' % action_name: raise exc.CommandError(msg) else: if stack_status.endswith('_FAILED'): raise exc.CommandError(msg) return heat_client.stacks.get(stack)
def take_action(self, parsed_args): identity_client = self.app.client_manager.identity auth_ref = self.app.client_manager.auth_ref # No user or project specified, list all roles in the system if not parsed_args.user and not parsed_args.project: columns = ('ID', 'Name') data = identity_client.roles.list() elif parsed_args.user and parsed_args.project: user = utils.find_resource( identity_client.users, parsed_args.user, ) project = utils.find_resource( identity_client.projects, parsed_args.project, ) data = identity_client.roles.roles_for_user(user.id, project.id) elif parsed_args.user: user = utils.find_resource( identity_client.users, parsed_args.user, ) if self.app.client_manager.auth_ref: project = utils.find_resource(identity_client.projects, auth_ref.project_id) else: msg = _("Project must be specified") raise exceptions.CommandError(msg) data = identity_client.roles.roles_for_user(user.id, project.id) elif parsed_args.project: project = utils.find_resource( identity_client.projects, parsed_args.project, ) if self.app.client_manager.auth_ref: user = utils.find_resource(identity_client.users, auth_ref.user_id) else: msg = _("User must be specified") raise exceptions.CommandError(msg) data = identity_client.roles.roles_for_user(user.id, project.id) if parsed_args.user or parsed_args.project: columns = ('ID', 'Name', 'Project', 'User') for user_role in data: user_role.user = user.name user_role.project = project.name return (columns, (utils.get_item_properties( s, columns, formatters={}, ) for s in data))
def validate_int_range(text, min_val, max_val): try: int_text = int(text) except ValueError: msg = "%s is not an integer." % text raise exceptions.CommandError(msg) if min_val <= int_text <= max_val: return int_text msg = "%s is out of range[%i-%i]." % (text, min_val, max_val) raise exceptions.CommandError(msg)
def find_resource(manager, name_or_id, **kwargs): try: if isinstance(name_or_id, int) or name_or_id.isdigit(): return manager.get(int(name_or_id), **kwargs) except Exception as ex: if type(ex).__name__ == 'NotFound': pass else: raise try: return manager.get(name_or_id, **kwargs) except Exception: pass if len(kwargs) == 0: kwargs = {} try: if 'NAME_ATTR' in manager.resource_class.__dict__: kwargs[manager.resource_class.NAME_ATTR] = name_or_id else: kwargs['name'] = name_or_id except Exception: pass try: return manager.find(**kwargs) except Exception as ex: if type(ex).__name__ == 'NotFound': msg = "No %s with a name or ID of '%s' exists." % \ (manager.resource_class.__name__.lower(), name_or_id) raise exceptions.CommandError(msg) if type(ex).__name__ == 'NoUniqueMatch': msg = "More than one %s exists with the name '%s'." % \ (manager.resource_class.__name__.lower(), name_or_id) raise exceptions.CommandError(msg) else: pass try: for resource in manager.list(): if (resource.get('id') == name_or_id or resource.get('name') == name_or_id): return resource else: pass except Exception: pass msg = "Could not find resource %s" % name_or_id raise exceptions.CommandError(msg)
def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) client = self.app.client_manager.orchestration if not parsed_args.all and parsed_args.output is None: msg = _('Either <OUTPUT NAME> or --all must be specified.') raise exc.CommandError(msg) if parsed_args.all and parsed_args.output is not None: msg = _('Cannot specify both <OUTPUT NAME> and --all.') raise exc.CommandError(msg) if parsed_args.all: try: stack = client.stacks.get(parsed_args.stack) except heat_exc.HTTPNotFound: msg = _('Stack not found: %s') % parsed_args.stack raise exc.CommandError(msg) outputs = stack.to_dict().get('outputs', []) columns = [] values = [] for output in outputs: columns.append(output['output_key']) values.append(heat_utils.json_formatter(output)) return columns, values try: output = client.stacks.output_show(parsed_args.stack, parsed_args.output)['output'] except heat_exc.HTTPNotFound: msg = _('Stack %(id)s or output %(out)s not found.') % { 'id': parsed_args.stack, 'out': parsed_args.output } raise exc.CommandError(msg) if 'output_error' in output: msg = _('Output error: %s') % output['output_error'] raise exc.CommandError(msg) if (isinstance(output['output_value'], list) or isinstance(output['output_value'], dict)): output['output_value'] = heat_utils.json_formatter( output['output_value']) return self.dict2columns(output)
def take_action(self, parsed_args): vnf_client = self.app.eclsdk.conn.virtual_network_appliance target = vnf_client.\ get_virtual_network_appliance( parsed_args.virtual_network_appliance) rows = ['ID', 'Name', 'Description', 'Tags'] row_headers = rows # serialize request parmeter as JSON requested_param = {} if hasattr(parsed_args, 'name') and parsed_args.name is not None: requested_param['name'] = parsed_args.name if hasattr(parsed_args, 'description') and parsed_args.description is not None: requested_param['description'] = parsed_args.description if hasattr(parsed_args, 'tags') and parsed_args.tags is not None: tags = parsed_args.tags or '{}' try: requested_param['tags'] = json.loads(tags) except Exception: msg = _("You must specify JSON object format") raise exceptions.CommandError(msg) # serialize current parmeter as JSON current_param = { 'name': target.name, 'description': target.description, 'tags': target.tags, } origin_param = copy.deepcopy(current_param) merged_param = jmp.merge(current_param, requested_param) patch = jmp.create_patch(origin_param, merged_param) if target.tags != requested_param['tags']: patch[tags] = requested_param['tags'] if not patch: msg = _('No change will be expected') raise exceptions.CommandError(msg) data = vnf_client.update_virtual_network_appliance( parsed_args.virtual_network_appliance, **patch) _set_interface_names_for_display(data) return row_headers, utils.get_item_properties(data, rows)
def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) client = self.app.client_manager.orchestration config = {} if parsed_args.config: try: config = client.software_configs.get(parsed_args.config) except heat_exc.HTTPNotFound: msg = (_('Software configuration not found: %s') % parsed_args.config) raise exc.CommandError(msg) derived_params = deployment_utils.build_derived_config_params( parsed_args.action, config, parsed_args.name, heat_utils.format_parameters(parsed_args.input_value, False), parsed_args.server, parsed_args.signal_transport, signal_id=deployment_utils.build_signal_id(client, parsed_args)) derived_config = client.software_configs.create(**derived_params) sd = client.software_deployments.create(config_id=derived_config.id, server_id=parsed_args.server, action=parsed_args.action, status='IN_PROGRESS') return zip(*sorted(sd.to_dict().items()))
def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) client = self.app.client_manager.orchestration fields = { # 'nested_depth': parsed_args.nested_depth, 'with_detail': parsed_args.long, # 'filters': heat_utils.format_parameters(parsed_args.filter), } try: resources = client.resources.list(parsed_args.stack, **fields) except heat_exc.HTTPNotFound: msg = _('Stack not found: %s') % parsed_args.stack raise exc.CommandError(msg) columns = [ 'physical_resource_id', 'resource_type', 'resource_status', # 'updated_time' ] if len(resources) >= 1 and not hasattr(resources[0], 'resource_name'): columns.insert(0, 'logical_resource_id') else: columns.insert(0, 'resource_name') # if parsed_args.nested_depth or parsed_args.long: if parsed_args.long: columns.append('stack_name') return (columns, (utils.get_item_properties(r, columns) for r in resources))
def _get_ip_address(addresses, address_type, ip_address_family): # Old style addresses if address_type in addresses: for addy in addresses[address_type]: if int(addy['version']) in ip_address_family: return addy['addr'] # New style addresses new_address_type = address_type if address_type == 'public': new_address_type = 'floating' if address_type == 'private': new_address_type = 'fixed' for network in addresses: for addy in addresses[network]: # Case where it is list of strings if isinstance(addy, six.string_types): if new_address_type == 'fixed': return addresses[network][0] else: return addresses[network][-1] # Case where it is a dict if 'OS-EXT-IPS:type' not in addy: continue if addy['OS-EXT-IPS:type'] == new_address_type: if int(addy['version']) in ip_address_family: return addy['addr'] raise exceptions.CommandError("ERROR: No %s IP version %s address found" % (address_type, ip_address_family))
def take_action(self, parsed_args): compute_client = self.app.client_manager.compute public_key = parsed_args.public_key if public_key: try: with open(os.path.expanduser(parsed_args.public_key)) as p: public_key = p.read() except IOError as e: msg = "Key file %s not found: %s" raise exceptions.CommandError(msg % (parsed_args.public_key, e)) keypair = compute_client.keypairs.create( parsed_args.name, public_key=public_key, ) # NOTE(dtroyer): how do we want to handle the display of the private # key when it needs to be communicated back to the user # For now, duplicate nova keypair-add command output info = {} if public_key: info.update(keypair._info) del info['public_key'] return zip(*sorted(six.iteritems(info))) else: sys.stdout.write(keypair.private_key) return ({}, {})
def parse_vna_interface(text, valid_keys): """parse vna interface text :param text: not in one of the following format net-id=net-uuid,ip-address=ip-addr,name=interface-name, slot-no=number,name=name slot-no=number,net-id=net-uuid,fixed-ips=ip-addr1:ip-addr2... interface-slot-no=number,ip-address=ip-addr, \ mac-address=mac-addr,type=type,vrid=vrid :param valid_keys: keys of the vna interface :return: """ try: params = {} pattern_valid_keys = r'(%s)' % '|'.join(map(lambda x: x + '=', valid_keys)) match_keys = re.findall(pattern_valid_keys, text) tmp_text = re.sub(r'\\t', '', text) match_values = re.sub(pattern_valid_keys, '\t', tmp_text).split('\t') for index, key in enumerate(match_keys): params[key.strip('=')] = match_values[index + 1].rstrip(',') if len(params) == 0: raise ValueError return params except ValueError: msg = "%r is not in the format of " \ " net-id=net-uuid,ip-address=ip-addr,name=interface-name, or," \ " slot-no=number,name=name, or," \ " slot-no=number,net-id=net-uuid,fixed-ips=ip-addr1:ip-addr2," \ " or, interface-slot-no=number,ip-address=ip-addr, " \ "mac-address=mac-addr,type=type,vrid=vrid>" raise exceptions.CommandError(msg % text)
def take_action(self, parsed_args): self.log.debug('take_action(%s)', parsed_args) client = self.app.client_manager.orchestration env_files, env = ( template_utils.process_multiple_environments_and_files( env_paths=parsed_args.environment)) adopt_url = heat_utils.normalise_file_path_to_url( parsed_args.adopt_file) adopt_data = request.urlopen(adopt_url).read().decode('utf-8') fields = { 'stack_name': parsed_args.name, 'disable_rollback': not parsed_args.enable_rollback, 'adopt_stack_data': adopt_data, 'parameters': heat_utils.format_parameters(parsed_args.parameter), 'files': dict(list(env_files.items())), 'environment': env, 'timeout': parsed_args.timeout } stack = client.stacks.create(**fields)['stack'] if parsed_args.wait: stack_status, msg = event_utils.poll_for_events( client, parsed_args.name, action='ADOPT') if stack_status == 'ADOPT_FAILED': raise exc.CommandError(msg) return _show_stack(client, stack['id'], format='table', short=True)
def _show_config(heat_client, config_id, config_only): try: sc = heat_client.software_configs.get(config_id=config_id) except heat_exc.HTTPNotFound: raise exc.CommandError(_('Configuration not found: %s') % config_id) columns = None rows = None if config_only: print(sc.config) else: columns = ( 'id', 'name', 'group', 'config', 'inputs', 'outputs', 'options', 'creation_time', ) rows = utils.get_dict_properties(sc.to_dict(), columns) return columns, rows
def validate_ipv4(text): try: ipaddress.IPv4Address(unicode(text)) except ipaddress.AddressValueError: msg = "%r is not a valid IPv4 address" raise exceptions.CommandError(msg % text) return text
def parse_tags(text): try: k, v = text.split('=', 1) return {k: v} except ValueError: msg = "%r is not in the format of key=value" raise exceptions.CommandError(msg % text)
def get_password(stdin, prompt=None, confirm=True): message = prompt or "User Password:"******"Repeat " + message) if first_pass == second_pass: return first_pass print("The passwords entered were not the same") except EOFError: raise exceptions.CommandError("Error reading password.") raise exceptions.CommandError("There was a request to be prompted for a" " password and a terminal was not detected.")
def parse_bool(text): if text == 'true': return True elif text == 'false': return False else: msg = "%r is not boolean (true or false)" raise exceptions.CommandError(msg % text)
def read_blob_file_contents(blob_file): try: with open(blob_file) as file: blob = file.read().strip() return blob except IOError: msg = "Error occurred trying to read from file %s" raise exceptions.CommandError(msg % blob_file)
def parse_allocation_pools(text): if not text: return {} lst = text.split(',') if len(lst) != 2: msg = "%r is not in the format of ipv4,ipv4" raise exceptions.CommandError(msg % text) return {'start': lst[0], 'end': lst[1]}
def parse_host_routes(text): if not text: return {} lst = text.split(',') if len(lst) != 2: msg = "%r is not in the format of cidr,ipv4" raise exceptions.CommandError(msg % text) return {'destination': lst[0], 'nexthop': lst[1]}
def _type_uuid(uuid): regex = re.compile( '^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}\Z', re.I) if not regex.match(uuid): msg = _("%r is not a valid uuid") raise exceptions.CommandError(msg % uuid) return uuid
def take_action(self, parsed_args): identity_client = self.app.client_manager.identity auth_ref = self.app.client_manager.auth_ref # Project and user are required, if not included in command args # default to the values used for authentication. For token-flow # authentication they must be included on the command line. if not parsed_args.project: if self.app.client_manager.auth_ref: parsed_args.project = auth_ref.project_id else: msg = _("Project must be specified") raise exceptions.CommandError(msg) if not parsed_args.user: if self.app.client_manager.auth_ref: parsed_args.user = auth_ref.user_id else: msg = _("User must be specified") raise exceptions.CommandError(msg) project = utils.find_resource( identity_client.tenants, parsed_args.project, ) user = utils.find_resource(identity_client.users, parsed_args.user) data = identity_client.roles.roles_for_user(user.id, project.id) columns = ( 'ID', 'Name', 'Project', 'User', ) # Add the names to the output even though they will be constant for role in data: role.user = user.name role.project = project.name return (columns, (utils.get_item_properties( s, columns, formatters={}, ) for s in data))
def validate_ipv4(text): try: if type(text) is not six.text_type: text = six.u(text) ipaddress.IPv4Address(text) except ipaddress.AddressValueError: msg = "%r is not a valid IPv4 address" raise exceptions.CommandError(msg % text) return text
def get_field(item, field): try: if isinstance(item, dict): return item[field] else: return getattr(item, field) except Exception: msg = "Resource doesn't have field %s" % field raise exceptions.CommandError(msg)
def _list(client, args=None): kwargs = {} columns = [ 'ID', 'Stack Name', 'Stack Status', 'Creation Time', # 'Updated Time', ] if args: kwargs = { 'limit': args.limit, 'marker': args.marker, # 'filters': heat_utils.format_parameters(args.properties), 'tags': None, 'tags_any': None, 'not_tags': None, 'not_tags_any': None, # 'global_tenant': args.all_projects or args.long, 'show_deleted': args.deleted, # 'show_hidden': args.hidden } if args.tags: if args.tag_mode: if args.tag_mode == 'any': kwargs['tags_any'] = args.tags elif args.tag_mode == 'not': kwargs['not_tags'] = args.tags elif args.tag_mode == 'not-any': kwargs['not_tags_any'] = args.tags else: err = _('tag mode must be one of "any", "not", "not-any"') raise exc.CommandError(err) else: kwargs['tags'] = args.tags if args.short: columns.pop() columns.pop() # if args.long: # columns.insert(2, 'Stack Owner') # if args.long or args.all_projects: # columns.insert(2, 'Project') # if args.nested: # columns.append('Parent') # kwargs['show_nested'] = True data = client.stacks.list(**kwargs) data = utils.sort_items(data, args.sort if args else None) return ( columns, (utils.get_item_properties(s, columns) for s in data) )
def _decorated(self, parsed_args): auth_plugin_name = self.app.client_manager.auth_plugin_name if auth_plugin_name in UNSCOPED_AUTH_PLUGINS: return func(self, parsed_args) else: msg = ('This command requires the use of an unscoped SAML ' 'authentication plugin. Please use argument ' '--os-auth-type with one of the following ' 'plugins: ' + ', '.join(UNSCOPED_AUTH_PLUGINS)) raise exceptions.CommandError(msg)
def _list_snapshot(self, heat_client, parsed_args): fields = {'stack_id': parsed_args.stack} try: snapshots = heat_client.stacks.snapshot_list(**fields) except heat_exc.HTTPNotFound: raise exc.CommandError( _('Stack not found: %s') % parsed_args.stack) columns = ['id', 'name', 'status', 'status_reason', 'creation_time'] return (columns, (utils.get_dict_properties(s, columns) for s in snapshots['snapshots']))
def parse_allowed_address_pairs(text): if not text: return {} lst = text.split(',') if len(lst) > 2: msg = "%r is not in the format of ipv4|cidr,mac or ipv4|cidr" raise exceptions.CommandError(msg % text) if len(lst) == 2: return {'ip_address': lst[0], 'mac_address': lst[1]} if len(lst) == 1: return {'ip_address': lst[0]}