def test_dictionary(self): payload = {'password': '******'} expected = {'password': '******'} self.assertEqual(expected, strutils.mask_dict_password(payload)) payload = {'user': '******', 'password': '******'} expected = {'user': '******', 'password': '******'} self.assertEqual(expected, strutils.mask_dict_password(payload)) payload = {'strval': 'somestring', 'dictval': {'user': '******', 'password': '******'}} expected = {'strval': 'somestring', 'dictval': {'user': '******', 'password': '******'}} self.assertEqual(expected, strutils.mask_dict_password(payload)) payload = {'strval': '--password abc', 'dont_change': 'this is fine', 'dictval': {'user': '******', 'password': b'TL0EfN33'}} expected = {'strval': '--password ***', 'dont_change': 'this is fine', 'dictval': {'user': '******', 'password': '******'}} self.assertEqual(expected, strutils.mask_dict_password(payload)) payload = {'ipmi_password': '******'} expected = {'ipmi_password': '******'} self.assertEqual(expected, strutils.mask_dict_password(payload))
def test_dictionary(self): payload = {'password': '******'} expected = {'password': '******'} self.assertEqual(expected, strutils.mask_dict_password(payload)) payload = {'user': '******', 'password': '******'} expected = {'user': '******', 'password': '******'} self.assertEqual(expected, strutils.mask_dict_password(payload)) payload = {'strval': 'somestring', 'dictval': {'user': '******', 'password': '******'}} expected = {'strval': 'somestring', 'dictval': {'user': '******', 'password': '******'}} self.assertEqual(expected, strutils.mask_dict_password(payload)) payload = {'strval': '--password abc', 'dont_change': 'this is fine', 'dictval': {'user': '******', 'password': b'mypassword'}} expected = {'strval': '--password ***', 'dont_change': 'this is fine', 'dictval': {'user': '******', 'password': '******'}} self.assertEqual(expected, strutils.mask_dict_password(payload))
def attach_volume(self, connection_info, instance_name, disk_bus=constants.CTRL_TYPE_SCSI): tries_left = CONF.hyperv.volume_attach_retry_count + 1 while tries_left: try: self._attach_volume(connection_info, instance_name, disk_bus) break except Exception as ex: tries_left -= 1 if not tries_left: LOG.exception( _("Failed to attach volume %(connection_info)s " "to instance %(instance_name)s. "), {'connection_info': strutils.mask_dict_password(connection_info), 'instance_name': instance_name}) self.disconnect_volume(connection_info) raise exception.VolumeAttachFailed( volume_id=connection_info['serial'], reason=ex) else: LOG.warning( "Failed to attach volume %(connection_info)s " "to instance %(instance_name)s. " "Tries left: %(tries_left)s.", {'connection_info': strutils.mask_dict_password( connection_info), 'instance_name': instance_name, 'tries_left': tries_left}) time.sleep(CONF.hyperv.volume_attach_retry_interval)
def as_dict(self, secure=False): d = super(Node, self).as_dict() if secure: d['driver_info'] = strutils.mask_dict_password( d.get('driver_info', {}), "******") d['instance_info'] = strutils.mask_dict_password( d.get('instance_info', {}), "******") return d
def test_do_no_harm(self): payload = {} expected = {} self.assertEqual(expected, strutils.mask_dict_password(payload)) payload = {'somekey': 'somevalue', 'anotherkey': 'anothervalue'} expected = {'somekey': 'somevalue', 'anotherkey': 'anothervalue'} self.assertEqual(expected, strutils.mask_dict_password(payload))
def test_do_no_harm(self): payload = {} expected = {} self.assertEqual(expected, strutils.mask_dict_password(payload)) payload = {"somekey": "somevalue", "anotherkey": "anothervalue"} expected = {"somekey": "somevalue", "anotherkey": "anothervalue"} self.assertEqual(expected, strutils.mask_dict_password(payload))
def test_argument_untouched(self): """Make sure that the argument passed in is not modified""" payload = {'password': '******', 'bool': True, 'dict': {'cat': 'meow', 'password': "******"}, 'float': 0.1, 'int': 123, 'list': [1, 2], 'none': None, 'str': 'foo'} pristine = copy.deepcopy(payload) # Send the payload into the function, to see if it gets modified strutils.mask_dict_password(payload) self.assertEqual(pristine, payload)
def mask_secrets(payload): """Remove secrets from payload object.""" mask = '******' if hasattr(payload, 'instance_info'): payload.instance_info = strutils.mask_dict_password( payload.instance_info, mask) if 'image_url' in payload.instance_info: payload.instance_info['image_url'] = mask if hasattr(payload, 'driver_info'): payload.driver_info = strutils.mask_dict_password( payload.driver_info, mask)
def as_dict(self, secure=False, mask_configdrive=True): d = super(Node, self).as_dict() if secure: d['driver_info'] = strutils.mask_dict_password( d.get('driver_info', {}), "******") iinfo = d.pop('instance_info', {}) configdrive = iinfo.pop('configdrive', None) d['instance_info'] = strutils.mask_dict_password(iinfo, "******") if configdrive is not None: d['instance_info']['configdrive'] = ( "******" if mask_configdrive else configdrive) d['driver_internal_info'] = strutils.mask_dict_password( d.get('driver_internal_info', {}), "******") return d
def _handle_requests(self, func, name, params): """Convert arguments and call a method. :param func: Callable object. :param name: RPC call name for logging. :param params: Keyword arguments. :return: call result as JSON. """ # TODO(dtantsur): server-side version check? params.pop('rpc.version', None) logged_params = strutils.mask_dict_password(params) try: context = params.pop('context') except KeyError: context = None else: # A valid context is required for deserialization if not isinstance(context, dict): raise InvalidParams( _("Context must be a dictionary, if provided")) context = ir_context.RequestContext.from_dict(context) params = { key: self.serializer.deserialize_entity(context, value) for key, value in params.items() } params['context'] = context LOG.debug('RPC %s with %s', name, logged_params) try: result = func(**params) # FIXME(dtantsur): we could use the inspect module, but # oslo_messaging.expected_exceptions messes up signatures. except TypeError as exc: raise InvalidParams(params=', '.join(params), method=name, error=exc) if context is not None: # Currently it seems that we can serialize even with invalid # context, but I'm not sure it's guaranteed to be the case. result = self.serializer.serialize_entity(context, result) LOG.debug( 'RPC %s returned %s', name, strutils.mask_dict_password(result) if isinstance(result, dict) else result) return result
def test_nested_non_dict(self): expected = {'nested': {'password': '******', 'foo': 'bar', } } payload = NestedMapping() self.assertEqual(expected, strutils.mask_dict_password(payload))
def test_other_non_str_values(self): payload = { 'password': '******', 'bool': True, 'dict': { 'cat': 'meow', 'password': "******" }, 'float': 0.1, 'int': 123, 'list': [1, 2], 'none': None, 'str': 'foo' } expected = { 'password': '******', 'bool': True, 'dict': { 'cat': 'meow', 'password': '******' }, 'float': 0.1, 'int': 123, 'list': [1, 2], 'none': None, 'str': 'foo' } self.assertEqual(expected, strutils.mask_dict_password(payload))
def test_non_dict(self): expected = { 'password': '******', 'foo': 'bar', } payload = TestMapping() self.assertEqual(expected, strutils.mask_dict_password(payload))
def data(self): values = {} for configItem in self.configuration_items: key = configItem.configuration_key value = configItem.configuration_value values[key] = value configuration_dict = { "id": self.configuration.id, "name": self.configuration.name, "description": self.configuration.description, "values": strutils.mask_dict_password(values), "created": self.configuration.created, "updated": self.configuration.updated, "instance_count": getattr(self.configuration, "instance_count", 0), "datastore_name": self.configuration.datastore.name, "datastore_version_id": self.configuration.datastore_version_id, "datastore_version_name": self.configuration.datastore_version.name, "datastore_version_number": self.configuration.datastore_version.version } return {"configuration": configuration_dict}
def get_iscsi_dict(self, device_info, volume): """Populate iscsi dict to pass to nova. :param device_info: device info dict :param volume: volume object :returns: iscsi dict """ metro_ip_iqn, metro_host_lun = None, None try: ip_and_iqn = device_info['ip_and_iqn'] is_multipath = device_info['is_multipath'] host_lun_id = device_info['hostlunid'] except KeyError as e: exception_message = (_("Cannot get iSCSI ipaddresses, multipath " "flag, or hostlunid. Exception is %(e)s.") % {'e': six.text_type(e)}) raise exception.VolumeBackendAPIException( message=exception_message) if device_info.get('metro_ip_and_iqn'): LOG.debug("Volume is Metro device...") metro_ip_iqn = device_info['metro_ip_and_iqn'] metro_host_lun = device_info['metro_hostlunid'] iscsi_properties = self.vmax_get_iscsi_properties( volume, ip_and_iqn, is_multipath, host_lun_id, metro_ip_iqn, metro_host_lun) LOG.info("iSCSI properties are: %(props)s", {'props': strutils.mask_dict_password(iscsi_properties)}) return {'driver_volume_type': 'iscsi', 'data': iscsi_properties}
def sanitize_secrets(content, mask="****"): """Extends oslo_utils strutils to make mask passwords more robust.""" def mask_dict_password(dictionary, secret="***"): """Overriding strutils.mask_dict_password. Overriding mask_dict_password to accept CaseInsenstiveDict as well. """ out = deepcopy(dictionary) for k, v in dictionary.items(): if is_dict(v): out[k] = mask_dict_password(v, secret=secret) continue for sani_key in strutils._SANITIZE_KEYS: if sani_key in k: out[k] = secret break else: if isinstance(v, six.string_types): out[k] = strutils.mask_password(v, secret=secret) return out strutils.mask_dict_password = mask_dict_password if is_dict(content): return strutils.mask_dict_password(content, mask) if is_string(content): return strutils.mask_password(content, mask)
def get_iscsi_dict(self, device_info, volume): """Populate iscsi dict to pass to nova. :param device_info: device info dict :param volume: volume object :returns: iscsi dict """ metro_ip_iqn, metro_host_lun = None, None try: ip_and_iqn = device_info['ip_and_iqn'] is_multipath = device_info['is_multipath'] host_lun_id = device_info['hostlunid'] except KeyError as e: exception_message = (_("Cannot get iSCSI ipaddresses, multipath " "flag, or hostlunid. Exception is %(e)s.") % { 'e': six.text_type(e) }) raise exception.VolumeBackendAPIException( message=exception_message) if device_info.get('metro_ip_and_iqn'): LOG.debug("Volume is Metro device...") metro_ip_iqn = device_info['metro_ip_and_iqn'] metro_host_lun = device_info['metro_hostlunid'] iscsi_properties = self.vmax_get_iscsi_properties( volume, ip_and_iqn, is_multipath, host_lun_id, metro_ip_iqn, metro_host_lun) LOG.info("iSCSI properties are: %(props)s", {'props': strutils.mask_dict_password(iscsi_properties)}) return {'driver_volume_type': 'iscsi', 'data': iscsi_properties}
def mask_data(obj): if isinstance(obj, dict): return mask_dict_password(obj) elif isinstance(obj, list): return [mask_data(i) for i in obj] else: return mask_password(obj)
def save(self): if not self.is_valid(): raise exception.InvalidModelError(errors=self.errors) self['updated'] = utils.utcnow() LOG.debug("Saving %(name)s: %(dict)s" % {'name': self.__class__.__name__, 'dict': strutils.mask_dict_password(self.__dict__)}) return self.db_api.save(self)
def save(self): if not self.is_valid(): raise exception.InvalidModelError(errors=self.errors) self['updated'] = timeutils.utcnow() LOG.debug("Saving %(name)s: %(dict)s", {'name': self.__class__.__name__, 'dict': strutils.mask_dict_password(self.__dict__)}) return self.db_api.save(self)
def mask_password(cmd): """Return a string in which the password is masked.""" if len(cmd) > 3 and cmd[0] == 'raidcom' and cmd[1] == '-login': tmp = list(cmd) tmp[3] = strutils.mask_dict_password({'password': ''}).get('password') else: tmp = cmd return ' '.join([six.text_type(c) for c in tmp])
def trace_logging_wrapper(*args, **kwargs): filter_function = dec_kwargs.get('filter_function') if len(args) > 0: maybe_self = args[0] else: maybe_self = kwargs.get('self', None) if maybe_self and hasattr(maybe_self, '__module__'): logger = logging.getLogger(maybe_self.__module__) else: logger = LOG # NOTE(ameade): Don't bother going any further if DEBUG log level # is not enabled for the logger. if not logger.isEnabledFor(py_logging.DEBUG): return f(*args, **kwargs) all_args = inspect.getcallargs(f, *args, **kwargs) pass_filter = filter_function is None or filter_function(all_args) if pass_filter: logger.debug( '==> %(func)s: call %(all_args)r', { 'func': func_name, 'all_args': strutils.mask_password( six.text_type(all_args)) }) start_time = time.time() * 1000 try: result = f(*args, **kwargs) except Exception as exc: total_time = int(round(time.time() * 1000)) - start_time logger.debug('<== %(func)s: exception (%(time)dms) %(exc)r', { 'func': func_name, 'time': total_time, 'exc': exc }) raise total_time = int(round(time.time() * 1000)) - start_time if isinstance(result, dict): mask_result = strutils.mask_dict_password(result) elif isinstance(result, six.string_types): mask_result = strutils.mask_password(result) else: mask_result = result if pass_filter: logger.debug('<== %(func)s: return (%(time)dms) %(result)r', { 'func': func_name, 'time': total_time, 'result': mask_result }) return result
def detach_volume(self, connection_info, instance_name): LOG.debug("Detaching volume: %(connection_info)s " "from %(instance_name)s", {'connection_info': strutils.mask_dict_password( connection_info), 'instance_name': instance_name}) volume_driver = self._get_volume_driver(connection_info) volume_driver.detach_volume(connection_info, instance_name) volume_driver.disconnect_volume(connection_info)
def extend_volume(self, connection_properties): """Update the local kernel's size information. Try and update the local kernel's size information for an iSCSI volume. """ LOG.info("Extend volume for %s", strutils.mask_dict_password(connection_properties)) volume_paths = self.get_volume_paths(connection_properties) LOG.info("Found paths for volume %s", volume_paths) if volume_paths: return self._linuxscsi.extend_volume(volume_paths) else: LOG.warning("Couldn't find any volume paths on the host to " "extend volume for %(props)s", {'props': strutils.mask_dict_password( connection_properties)}) raise exception.VolumePathsNotFound()
def _make_vim_dict(self, vim_db, fields=None, mask_password=True): res = dict((key, vim_db[key]) for key in VIM_ATTRIBUTES) vim_auth_db = vim_db.vim_auth res['auth_url'] = vim_auth_db[0].auth_url res['vim_project'] = vim_auth_db[0].vim_project res['auth_cred'] = vim_auth_db[0].auth_cred res['auth_cred']['password'] = vim_auth_db[0].password if mask_password: res['auth_cred'] = strutils.mask_dict_password(res['auth_cred']) return self._fields(res, fields)
def extend_volume(self, connection_properties): """Update the local kernel's size information. Try and update the local kernel's size information for an iSCSI volume. """ LOG.info("Extend volume for %s", strutils.mask_dict_password(connection_properties)) volume_paths = self.get_volume_paths(connection_properties) LOG.info("Found paths for volume %s", volume_paths) if volume_paths: return self._linuxscsi.extend_volume(volume_paths) else: LOG.warning( "Couldn't find any volume paths on the host to " "extend volume for %(props)s", {'props': strutils.mask_dict_password(connection_properties)}) raise exception.VolumePathsNotFound()
def notify(self, ctxt, message, priority, retry): logger = logging.getLogger('%s.%s' % (self.LOGGER_BASE, message['event_type'])) method = getattr(logger, priority.lower(), None) if method: method(jsonutils.dumps(strutils.mask_dict_password(message))) else: warnings.warn('Unable to log message as notify cannot find a ' 'logger with the priority specified ' '%s' % priority.lower())
def test_dictionary(self): payload = {'password': '******'} expected = {'password': '******'} self.assertEqual(expected, strutils.mask_dict_password(payload)) payload = {'user': '******', 'password': '******'} expected = {'user': '******', 'password': '******'} self.assertEqual(expected, strutils.mask_dict_password(payload)) payload = { 'strval': 'somestring', 'dictval': { 'user': '******', 'password': '******' } } expected = { 'strval': 'somestring', 'dictval': { 'user': '******', 'password': '******' } } self.assertEqual(expected, strutils.mask_dict_password(payload)) payload = { 'strval': '--password abc', 'dont_change': 'this is fine', 'dictval': { 'user': '******', 'password': b'mypassword' } } expected = { 'strval': '--password ***', 'dont_change': 'this is fine', 'dictval': { 'user': '******', 'password': '******' } } self.assertEqual(expected, strutils.mask_dict_password(payload))
def test_other_non_str_values(self): payload = {'password': '******', 'bool': True, 'dict': {'cat': 'meow', 'password': "******"}, 'float': 0.1, 'int': 123, 'list': [1, 2], 'none': None, 'str': 'foo'} expected = {'password': '******', 'bool': True, 'dict': {'cat': 'meow', 'password': '******'}, 'float': 0.1, 'int': 123, 'list': [1, 2], 'none': None, 'str': 'foo'} self.assertEqual(expected, strutils.mask_dict_password(payload))
def initialize_connection(self, volume, connector): try: sys = self.client.get_cluster() except exception.NotFound: msg = _("XtremIO not initialized correctly, no clusters found") raise exception.VolumeBackendAPIException(data=msg) login_chap = (sys.get('chap-authentication-mode', 'disabled') != 'disabled') discovery_chap = (sys.get('chap-discovery-mode', 'disabled') != 'disabled') initiator_name = self._get_initiator_names(connector)[0] initiator = self.client.get_initiator(initiator_name) if initiator: login_passwd = initiator['chap-authentication-initiator-password'] discovery_passwd = initiator['chap-discovery-initiator-password'] ig = self._get_ig(initiator['ig-id'][XTREMIO_OID_NAME]) else: ig = self._get_ig(self._get_ig_name(connector)) if not ig: ig = self._create_ig(self._get_ig_name(connector)) (login_passwd, discovery_passwd) = self._create_initiator(connector, login_chap, discovery_chap) # if CHAP was enabled after the initiator was created if login_chap and not login_passwd: LOG.info('Initiator has no password while using chap, adding it.') data = {} (login_passwd, d_passwd) = self._add_auth(data, login_chap, discovery_chap and not discovery_passwd) discovery_passwd = (discovery_passwd if discovery_passwd else d_passwd) self.client.req('initiators', 'PUT', data, idx=initiator['index']) # lun mappping lunmap = self.create_lun_map(volume, ig['ig-id'][XTREMIO_OID_NAME]) properties = self._get_iscsi_properties(lunmap) if login_chap: properties['auth_method'] = 'CHAP' properties['auth_username'] = '******' properties['auth_password'] = login_passwd if discovery_chap: properties['discovery_auth_method'] = 'CHAP' properties['discovery_auth_username'] = '******' properties['discovery_auth_password'] = discovery_passwd LOG.debug('init conn params:\n%s', strutils.mask_dict_password(properties)) return { 'driver_volume_type': 'iscsi', 'data': properties }
def detach_volume(self, connection_info, instance_name): LOG.debug( "Detaching volume: %(connection_info)s " "from %(instance_name)s", { 'connection_info': strutils.mask_dict_password(connection_info), 'instance_name': instance_name }) volume_driver = self._get_volume_driver(connection_info) volume_driver.detach_volume(connection_info, instance_name) volume_driver.disconnect_volume(connection_info)
def delete(self): self['updated'] = timeutils.utcnow() LOG.debug("Deleting %(name)s: %(dict)s", {'name': self.__class__.__name__, 'dict': strutils.mask_dict_password(self.__dict__)}) if self.preserve_on_delete: self['deleted_at'] = timeutils.utcnow() self['deleted'] = True return self.db_api.save(self) else: return self.db_api.delete(self)
def trace_logging_wrapper(*args, **kwargs): filter_function = dec_kwargs.get('filter_function') if len(args) > 0: maybe_self = args[0] else: maybe_self = kwargs.get('self', None) if maybe_self and hasattr(maybe_self, '__module__'): logger = logging.getLogger(maybe_self.__module__) else: logger = LOG # NOTE(ameade): Don't bother going any further if DEBUG log level # is not enabled for the logger. if not logger.isEnabledFor(py_logging.DEBUG): return f(*args, **kwargs) all_args = inspect.getcallargs(f, *args, **kwargs) pass_filter = filter_function is None or filter_function(all_args) if pass_filter: logger.debug('==> %(func)s: call %(all_args)r', {'func': func_name, 'all_args': strutils.mask_password( six.text_type(all_args))}) start_time = time.time() * 1000 try: result = f(*args, **kwargs) except Exception as exc: total_time = int(round(time.time() * 1000)) - start_time logger.debug('<== %(func)s: exception (%(time)dms) %(exc)r', {'func': func_name, 'time': total_time, 'exc': exc}) raise total_time = int(round(time.time() * 1000)) - start_time if isinstance(result, dict): mask_result = strutils.mask_dict_password(result) elif isinstance(result, six.string_types): mask_result = strutils.mask_password(result) else: mask_result = result if pass_filter: logger.debug('<== %(func)s: return (%(time)dms) %(result)r', {'func': func_name, 'time': total_time, 'result': mask_result}) return result
def delete(self): self['updated'] = utils.utcnow() LOG.debug("Deleting %(name)s: %(dict)s" % {'name': self.__class__.__name__, 'dict': strutils.mask_dict_password(self.__dict__)}) if self.preserve_on_delete: self['deleted_at'] = utils.utcnow() self['deleted'] = True return self.db_api.save(self) else: return self.db_api.delete(self)
def trace_logging_wrapper(*args, **kwargs): if len(args) > 0: maybe_self = args[0] else: maybe_self = kwargs.get('self', None) if maybe_self and hasattr(maybe_self, '__module__'): logger = logging.getLogger(maybe_self.__module__) else: logger = LOG # NOTE(ameade): Don't bother going any further if DEBUG log level # is not enabled for the logger. if not logger.isEnabledFor(py_logging.DEBUG): return f(*args, **kwargs) all_args = inspect.getcallargs(f, *args, **kwargs) logger.debug( '==> %(func)s: call %(all_args)r', { 'func': func_name, # NOTE(mriedem): We have to stringify the dict first # and don't use mask_dict_password because it results in # an infinite recursion failure. 'all_args': strutils.mask_password(str(all_args)) }) start_time = time.time() * 1000 try: result = f(*args, **kwargs) except Exception as exc: total_time = int(round(time.time() * 1000)) - start_time logger.debug('<== %(func)s: exception (%(time)dms) %(exc)r', { 'func': func_name, 'time': total_time, 'exc': exc }) raise total_time = int(round(time.time() * 1000)) - start_time if isinstance(result, dict): mask_result = strutils.mask_dict_password(result) elif isinstance(result, str): mask_result = strutils.mask_password(result) else: mask_result = result logger.debug('<== %(func)s: return (%(time)dms) %(result)r', { 'func': func_name, 'time': total_time, 'result': mask_result }) return result
def test_mask_passwords(self): # Ensure that passwords are masked with notifications driver = _impl_log.LogDriver(None, None, None) logger = mock.MagicMock() logger.info = mock.MagicMock() message = {'password': '******', 'event_type': 'foo'} mask_str = jsonutils.dumps(strutils.mask_dict_password(message)) with mock.patch.object(logging, 'getLogger') as gl: gl.return_value = logger driver.notify(None, message, 'info', 0) logger.info.assert_called_once_with(mask_str)
def mask_secrets(payload): """Remove secrets from payload object.""" mask = '******' dict_fields = ['instance_info', 'driver_info', 'driver_internal_info'] for f in dict_fields: if hasattr(payload, f): masked = strutils.mask_dict_password(getattr(payload, f), mask) setattr(payload, f, masked) if hasattr(payload, 'instance_info'): if 'image_url' in payload.instance_info: payload.instance_info['image_url'] = mask
def attach_volume(self, connection_info, instance_name, disk_bus=constants.CTRL_TYPE_SCSI): tries_left = CONF.hyperv.volume_attach_retry_count + 1 while tries_left: try: self._attach_volume(connection_info, instance_name, disk_bus) break except Exception as ex: tries_left -= 1 if not tries_left: LOG.exception( "Failed to attach volume %(connection_info)s " "to instance %(instance_name)s.", { 'connection_info': strutils.mask_dict_password(connection_info), 'instance_name': instance_name }) self.disconnect_volume(connection_info) raise exception.VolumeAttachFailed( volume_id=connection_info['serial'], reason=ex) else: LOG.warning( "Failed to attach volume %(connection_info)s " "to instance %(instance_name)s. " "Tries left: %(tries_left)s.", { 'connection_info': strutils.mask_dict_password(connection_info), 'instance_name': instance_name, 'tries_left': tries_left }) time.sleep(CONF.hyperv.volume_attach_retry_interval)
def test_dictionary(self): payload = {"password": "******"} expected = {"password": "******"} self.assertEqual(expected, strutils.mask_dict_password(payload)) payload = {"user": "******", "password": "******"} expected = {"user": "******", "password": "******"} self.assertEqual(expected, strutils.mask_dict_password(payload)) payload = {"strval": "somestring", "dictval": {"user": "******", "password": "******"}} expected = {"strval": "somestring", "dictval": {"user": "******", "password": "******"}} self.assertEqual(expected, strutils.mask_dict_password(payload)) payload = { "strval": "--password abc", "dont_change": "this is fine", "dictval": {"user": "******", "password": b"mypassword"}, } expected = { "strval": "--password ***", "dont_change": "this is fine", "dictval": {"user": "******", "password": "******"}, } self.assertEqual(expected, strutils.mask_dict_password(payload))
def _attach_volume(self, connection_info, instance_name, disk_bus=constants.CTRL_TYPE_SCSI): LOG.debug( "Attaching volume: %(connection_info)s to %(instance_name)s", {'connection_info': strutils.mask_dict_password(connection_info), 'instance_name': instance_name}) volume_driver = self._get_volume_driver(connection_info) volume_driver.attach_volume(connection_info, instance_name, disk_bus) qos_specs = connection_info['data'].get('qos_specs') or {} if qos_specs: volume_driver.set_disk_qos_specs(connection_info, qos_specs)
def _request(self, context, method, cast=False, version=None, **kwargs): """Call conductor RPC. Versioned objects are automatically serialized and deserialized. :param context: Security context. :param method: Method name. :param cast: If true, use a JSON RPC notification. :param version: RPC API version to use. :param kwargs: Keyword arguments to pass. :return: RPC result (if any). """ params = { key: self.serializer.serialize_entity(context, value) for key, value in kwargs.items() } params['context'] = context.to_dict() if version is None: version = self.version if version is not None: _check_version(version, self.version_cap) params['rpc.version'] = version body = { "jsonrpc": "2.0", "method": method, "params": params, } if not cast: body['id'] = context.request_id or uuidutils.generate_uuid() LOG.debug("RPC %s with %s", method, strutils.mask_dict_password(body)) scheme = 'http' if CONF.json_rpc.use_ssl: scheme = 'https' url = '%s://%s:%d' % (scheme, netutils.escape_ipv6( self.host), CONF.json_rpc.port) result = _get_session().post(url, json=body) LOG.debug('RPC %s returned %s', method, strutils.mask_password(result.text or '<None>')) if not cast: result = result.json() self._handle_error(result.get('error')) result = self.serializer.deserialize_entity( context, result['result']) return result
def _attach_volume(self, connection_info, instance_name, disk_bus=constants.CTRL_TYPE_SCSI): LOG.debug( "Attaching volume: %(connection_info)s to %(instance_name)s", { 'connection_info': strutils.mask_dict_password(connection_info), 'instance_name': instance_name }) volume_driver = self._get_volume_driver(connection_info) volume_driver.attach_volume(connection_info, instance_name, disk_bus) qos_specs = connection_info['data'].get('qos_specs') or {} if qos_specs: volume_driver.set_disk_qos_specs(connection_info, qos_specs)
def mask_dict_password(config): # Adds a few more filters ontop of the strutils version... tmp_config = strutils.mask_dict_password(config) if 'ssl' in tmp_config: for k in list(tmp_config['ssl'].keys()): v = tmp_config['ssl'].get(k, {}) if v and 'contents' in v: v['contents'] = SECRETE if 'ssh' in tmp_config: for k in ['private_key', 'public_key']: if k in tmp_config['ssh']: tmp_config['ssh'][k] = SECRETE if 'stock' in tmp_config: for k in list(tmp_config['stock'].keys()): tmp_config['stock'][k] = SECRETE if 'google_calendar' in tmp_config: for k in ["credentials"]: tmp_config['google_calendar'][k] = SECRETE return tmp_config
def __call__(self, req): if os.path.normpath(req.path_info) == "/": resp = base.ec2_md_print(base.VERSIONS + ["latest"]) req.response.body = encodeutils.to_utf8(resp) req.response.content_type = base.MIME_TYPE_TEXT_PLAIN return req.response # Convert webob.headers.EnvironHeaders to a dict and mask any sensitive # details from the logs. if CONF.debug: headers = {k: req.headers[k] for k in req.headers} LOG.debug('Metadata request headers: %s', strutils.mask_dict_password(headers)) if CONF.neutron.service_metadata_proxy: if req.headers.get('X-Metadata-Provider'): meta_data = self._handle_instance_id_request_from_lb(req) else: meta_data = self._handle_instance_id_request(req) else: if req.headers.get('X-Instance-ID'): LOG.warning( "X-Instance-ID present in request headers. The " "'service_metadata_proxy' option must be " "enabled to process this header.") meta_data = self._handle_remote_ip_request(req) if meta_data is None: raise webob.exc.HTTPNotFound() try: data = meta_data.lookup(req.path_info) except base.InvalidMetadataPath: raise webob.exc.HTTPNotFound() if callable(data): return data(req, meta_data) resp = base.ec2_md_print(data) req.response.body = encodeutils.to_utf8(resp) req.response.content_type = meta_data.get_mimetype() return req.response
def test_do_an_int(self): payload = {} payload[1] = 2 expected = payload.copy() self.assertEqual(expected, strutils.mask_dict_password(payload))
def lookup(self, context, **kwargs): """Find a matching node for the agent. Method to be called the first time a ramdisk agent checks in. This can be because this is a node just entering cleaning or a node that rebooted for some reason. We will use the mac addresses listed in the kwargs to find the matching node, then return the node object to the agent. The agent can that use that UUID to use the node vendor passthru method. Currently, we don't handle the instance where the agent doesn't have a matching node (i.e. a brand new, never been in Ironic node). Additionally, we may pass on useful configurations to the agent, which it would then be responsible for applying if relevant. Today these are limited to heartbeat_timeout and metrics configuration. kwargs should have the following format:: { "version": "2" "inventory": { "interfaces": [ { "name": "eth0", "mac_address": "00:11:22:33:44:55", "switch_port_descr": "port24", "switch_chassis_descr": "tor1" }, ... ], ... }, "node_uuid": "ab229209-0139-4588-bbe5-64ccec81dd6e" } The interfaces list should include a list of the non-IPMI MAC addresses in the form aa:bb:cc:dd:ee:ff. node_uuid argument is optional. If it's provided (e.g. as a result of inspection run before lookup), this method will just return a node and options. This method will also return the timeout for heartbeats. The driver will expect the agent to heartbeat before that timeout, or it will be considered down. This will be in a root level key called 'heartbeat_timeout' :raises: NotFound if no matching node is found. :raises: InvalidParameterValue with unknown payload version """ LOG.warning( _LW('Agent lookup vendor passthru is deprecated and will be ' 'removed in the Ocata release; please update your ' 'ironic-python-agent image to the Newton version')) LOG.debug('Agent lookup using data %s', kwargs) uuid = kwargs.get('node_uuid') if uuid: node = objects.Node.get_by_uuid(context, uuid) else: inventory = kwargs.get('inventory') interfaces = self._get_interfaces(inventory) mac_addresses = self._get_mac_addresses(interfaces) node = self._find_node_by_macs(context, mac_addresses) LOG.info(_LI('Initial lookup for node %s succeeded, agent is running ' 'and waiting for commands'), node.uuid) ndict = node.as_dict() cdict = context.to_dict() show_driver_secrets = policy.check('show_password', cdict, cdict) if not show_driver_secrets: ndict['driver_info'] = strutils.mask_dict_password( ndict['driver_info'], "******") return { # heartbeat_timeout is a config, so moving it into the # config namespace. Instead of a separate deprecation, # this will die when the vendor_passthru version of # lookup goes away. 'heartbeat_timeout': CONF.api.ramdisk_heartbeat_timeout, 'node': ndict, 'config': ramdisk.config(), }
def test_mask_values(self): payload = {"somekey": "test = cmd --password my\xe9\x80\x80pass"} expected = {"somekey": "test = cmd --password ***"} self.assertEqual(expected, strutils.mask_dict_password(payload))