def patch_attributes(self, attributes): if attributes.get('password', None) is not None: # defaults aren't set yet hash_method = HASH_METHODS[attributes.get( 'hash_method', self.ITEM_ATTRIBUTES['hash_method'], )] salt = attributes.get('salt', None) if self.node.os in self.node.OS_FAMILY_BSD: attributes['password_hash'] = bcrypt.encrypt( force_text(attributes['password']), rounds=8, # default rounds for OpenBSD accounts salt=_DEFAULT_BCRYPT_SALT if salt is None else salt, ) elif attributes.get('hash_method') == 'md5': attributes['password_hash'] = hash_method.encrypt( force_text(attributes['password']), salt=_DEFAULT_SALT if salt is None else salt, ) else: attributes['password_hash'] = hash_method.encrypt( force_text(attributes['password']), rounds=5000, # default from glibc salt=_DEFAULT_SALT if salt is None else salt, ) if 'use_shadow' not in attributes: attributes['use_shadow'] = self.node.use_shadow_passwords for attr in ('gid', 'uid'): if isinstance(attributes.get(attr), int): attributes[attr] = str(attributes[attr]) return attributes
def patch_attributes(self, attributes): if attributes.get('password', None) is not None: # defaults aren't set yet hash_method = HASH_METHODS[attributes.get( 'hash_method', self.ITEM_ATTRIBUTES['hash_method'], )] salt = attributes.get('salt', None) if self.node.os in self.node.OS_FAMILY_BSD: attributes['password_hash'] = bcrypt.encrypt( force_text(attributes['password']), rounds=8, # default rounds for OpenBSD accounts salt=_DEFAULT_BCRYPT_SALT if salt is None else salt, ) else: attributes['password_hash'] = hash_method.encrypt( force_text(attributes['password']), rounds=5000, # default from glibc salt=_DEFAULT_SALT if salt is None else salt, ) if 'use_shadow' not in attributes: attributes['use_shadow'] = self.node.use_shadow_passwords for attr in ('gid', 'uid'): if isinstance(attributes.get(attr), int): attributes[attr] = str(attributes[attr]) return attributes
def diff(content_old, content_new, filename, encoding_hint=None): output = "" LOG.debug("diffing {filename}: {len_before} B before, {len_after} B after".format( filename=filename, len_before=len(content_old), len_after=len(content_new), )) content_old = force_text(content_old) content_new = force_text(content_new) start = datetime.now() for line in unified_diff( content_old.splitlines(True), content_new.splitlines(True), fromfile=filename, tofile=_("<bundlewrap content>"), ): suffix = "" line = force_text(line).rstrip("\n") if len(line) > DIFF_MAX_LINE_LENGTH: line = line[:DIFF_MAX_LINE_LENGTH] suffix += _(" (line truncated after {} characters)").format(DIFF_MAX_LINE_LENGTH) if line.startswith("+"): line = green(line) elif line.startswith("-"): line = red(line) output += line + suffix + "\n" duration = datetime.now() - start LOG.debug("diffing {file}: complete after {time}s".format( file=filename, time=duration.total_seconds(), )) return output
def test_nontext(self): self.assertEqual(text.force_text(None), None) self.assertEqual(text.force_text(True), True) self.assertEqual(text.force_text(False), False) e = Exception() self.assertEqual(text.force_text(e), e) self.assertEqual(text.force_text({}), {})
def _template_content(self): if self.attributes['source'] is not None: filename = join(self.item_data_dir, self.attributes['source']) if not exists(filename): filename = join(self.item_dir, self.attributes['source']) with open(filename, 'rb') as f: return force_text(f.read()) else: return force_text(self.attributes['content'])
def _template_content(self): if self.attributes["source"] is not None: filename = join(self.item_data_dir, self.attributes["source"]) if exists(filename): with open(filename, "rb") as f: content = f.read() else: filename = join(self.item_dir, self.attributes["source"]) with open(filename, "rb") as f: content = f.read() return force_text(content) else: return force_text(self.attributes["content"])
def patch_attributes(self, attributes): if 'password' in attributes: attributes['password_hash'] = postgres_context.encrypt( force_text(attributes['password']), user=self.name, ) return attributes
def svc_masked(node, svcname): result = node.run( "systemctl is-enabled -- {}".format(quote(svcname)), may_fail=True, ) return (result.return_code == 1 and force_text(result.stdout).strip() == "masked")
def display_on_create(self, cdict): if (self.attributes['content_type'] not in ('any', 'base64', 'binary') and len(self.content) < DIFF_MAX_FILE_SIZE): del cdict['content_hash'] cdict['content'] = diff_value_text("", "", force_text( self.content)).rstrip("\n") del cdict['type'] return cdict
def get_databases(node): output = node.run("echo '\\l' | sudo -u postgres psql -Anqt -F '|' | grep '|'").stdout result = {} for line in force_text(output).strip().split("\n"): db, owner = line.strip().split("|", 2)[:2] result[db] = { 'owner': owner, } return result
def svc_enabled(node, svcname): result = node.run( "systemctl is-enabled -- {}".format(quote(svcname)), may_fail=True, ) return ( result.return_code == 0 and force_text(result.stdout).strip() != "runtime-enabled" )
def __init__( self, bundle, name, attributes, has_been_triggered=False, skip_validation=False, skip_name_validation=False ): self.attributes = {} self.bundle = bundle self.has_been_triggered = has_been_triggered self.item_dir = join(bundle.bundle_dir, self.BUNDLE_ATTRIBUTE_NAME) self.item_data_dir = join(bundle.bundle_data_dir, self.BUNDLE_ATTRIBUTE_NAME) self.name = name self.node = bundle.node self._faults_missing_for_attributes = set() self._precedes_items = [] if not skip_validation: if not skip_name_validation: self._validate_name(bundle, name) self.validate_name(bundle, name) self._validate_attribute_names(bundle, self.id, attributes) self._validate_required_attributes(bundle, self.id, attributes) self.validate_attributes(bundle, self.id, attributes) try: attributes = self.patch_attributes(attributes) except FaultUnavailable: self._faults_missing_for_attributes.add(_("unknown")) for attribute_name, attribute_default in BUILTIN_ITEM_ATTRIBUTES.items(): setattr(self, attribute_name, force_text(attributes.get(attribute_name, copy(attribute_default)))) for attribute_name, attribute_default in self.ITEM_ATTRIBUTES.items(): if attribute_name not in BUILTIN_ITEM_ATTRIBUTES: try: self.attributes[attribute_name] = force_text(attributes.get(attribute_name, attribute_default)) except FaultUnavailable: self._faults_missing_for_attributes.add(attribute_name) if self.cascade_skip is None: self.cascade_skip = not (self.unless or self.triggered) if self.id in self.triggers: raise BundleError( _("item {item} in bundle '{bundle}' can't trigger itself").format(bundle=self.bundle.name, item=self.id) )
def __init__(self, bundle, name, attributes, has_been_triggered=False, skip_validation=False, skip_name_validation=False): self.attributes = {} self.bundle = bundle self.has_been_triggered = has_been_triggered self.item_dir = join(bundle.bundle_dir, self.BUNDLE_ATTRIBUTE_NAME) self.item_data_dir = join(bundle.bundle_data_dir, self.BUNDLE_ATTRIBUTE_NAME) self.name = name self.node = bundle.node self._precedes_items = [] if not skip_validation: if not skip_name_validation: self._validate_name(bundle, name) self.validate_name(bundle, name) self._validate_attribute_names(bundle, self.id, attributes) self._validate_required_attributes(bundle, self.id, attributes) self.validate_attributes(bundle, self.id, attributes) attributes = self.patch_attributes(attributes) for attribute_name, attribute_default in \ self.ITEM_ATTRIBUTES.items(): if attribute_name in BUILTIN_ITEM_ATTRIBUTES: continue self.attributes[attribute_name] = force_text(attributes.get( attribute_name, attribute_default, )) for attribute_name, attribute_default in \ BUILTIN_ITEM_ATTRIBUTES.items(): setattr(self, attribute_name, force_text(attributes.get( attribute_name, copy(attribute_default), ))) if self.cascade_skip is None: self.cascade_skip = not (self.unless or self.triggered)
def __hash_remote_file(self, filename): path_info = PathInfo(self.node, filename) if not path_info.is_file: return None if hasattr(path_info, 'sha256'): return path_info.sha256 else: """"pending pr so do it manualy""" if self.node.os == 'macos': result = self.node.run("shasum -a 256 -- {}".format(quote(filename))) elif self.node.os in self.node.OS_FAMILY_BSD: result = self.node.run("sha256 -q -- {}".format(quote(filename))) else: result = self.node.run("sha256sum -- {}".format(quote(filename))) return force_text(result.stdout).strip().split()[0]
def get_role(node, role): result = node.run("echo \"SELECT rolcanlogin, rolsuper, rolpassword from pg_authid " "WHERE rolname='{}'\" " "| sudo -u postgres psql -Anqwx -F '|'".format(role)) role_attrs = {} for line in force_text(result.stdout).strip().split("\n"): try: key, value = line.split("|") except ValueError: pass else: role_attrs[AUTHID_COLUMNS[key]] = value for bool_attr in ('can_login', 'superuser'): if bool_attr in role_attrs: role_attrs[bool_attr] = role_attrs[bool_attr] == "t" return role_attrs if role_attrs else None
def patch_attributes(self, attributes): # import privileges into class self.available_privs = AVAILABLE_PRIVS.copy() self.available_db_privs = AVAILABLE_DB_PRIVS.copy() self.sql_available_privs = SQL_AVAILABLE_PRIVS.copy() self.sql_available_db_privs = SQL_AVAILABLE_DB_PRIVS.copy() if self.node.os == 'debian' and self.node.os_version[0] >= 10: self.available_privs += [ 'Delete_history_priv', # MariaDB > 1.5 ] self.sql_available_privs[ 'Delete_history_priv'] = 'DELETE HISTORY' # MariaDB > 1.5 self.available_db_privs += [ 'Delete_history_priv', # MariaDB > 1.5 ] self.sql_available_db_privs[ 'Delete_history_priv'] = 'DELETE HISTORY' # since MariaDB > 1.5 if 'password' in attributes and attributes['password'] != '': attributes['password_hash'] = mysql_context.encrypt( force_text(attributes['password'])) # sort hosts, since they do not depent in order if 'hosts' in attributes: attributes['hosts'] = sorted(attributes['hosts']) if 'superuser' in attributes and attributes['superuser']: attributes['privileges'] = AVAILABLE_PRIVS.copy() if attributes.get('db_priv', None) is None: attributes['db_priv'] = {} if 'db_priv' in attributes: for db, rights in attributes['db_priv'].items(): if rights == 'all': attributes['db_priv'][db] = self.available_db_privs.copy() elif type(attributes['db_priv'][db]) is not list: attributes['db_priv'][db] = [] return attributes
def __init__( self, bundle, name, attributes, has_been_triggered=False, skip_validation=False, skip_name_validation=False, ): self.attributes = {} self.bundle = bundle self.has_been_triggered = has_been_triggered self.item_dir = join(bundle.bundle_dir, self.BUNDLE_ATTRIBUTE_NAME) self.item_data_dir = join(bundle.bundle_data_dir, self.BUNDLE_ATTRIBUTE_NAME) self.name = name self.node = bundle.node self.when_creating = {} self._faults_missing_for_attributes = set() self._precedes_items = [] if not skip_validation: if not skip_name_validation: self._validate_name(bundle, name) self.validate_name(bundle, name) self._validate_attribute_names(bundle, self.id, attributes) self._validate_required_attributes(bundle, self.id, attributes) self.validate_attributes(bundle, self.id, attributes) try: attributes = self.patch_attributes(attributes) except FaultUnavailable: self._faults_missing_for_attributes.add(_("unknown")) for attribute_name, attribute_default in BUILTIN_ITEM_ATTRIBUTES.items( ): normalize = make_normalize(attribute_default) try: setattr( self, attribute_name, force_text( normalize( attributes.get( attribute_name, copy(attribute_default), )))) except FaultUnavailable: self._faults_missing_for_attributes.add(attribute_name) setattr(self, attribute_name, BUILTIN_ITEM_ATTRIBUTES[attribute_name]) for attribute_name, attribute_default in self.ITEM_ATTRIBUTES.items(): if attribute_name not in BUILTIN_ITEM_ATTRIBUTES: normalize = make_normalize(attribute_default) try: self.attributes[attribute_name] = force_text( normalize( attributes.get( attribute_name, copy(attribute_default), ))) except FaultUnavailable: self._faults_missing_for_attributes.add(attribute_name) for attribute_name, attribute_default in self.WHEN_CREATING_ATTRIBUTES.items( ): normalize = make_normalize(attribute_default) try: self.when_creating[attribute_name] = force_text( normalize( attributes.get('when_creating', {}).get( attribute_name, copy(attribute_default), ))) except FaultUnavailable: self._faults_missing_for_attributes.add('when_creating/' + attribute_name) if self.cascade_skip is None: self.cascade_skip = not (self.unless or self.triggered) if self.id in self.triggers: raise BundleError( _("item {item} in bundle '{bundle}' can't trigger itself"). format( bundle=self.bundle.name, item=self.id, ))
def test_unicode(self): self.assertEqual(text.force_text(u"ö"), u"ö")
def test_unsupported_encoding(self): self.assertEqual(text.force_text(u"ö".encode('latin-1')), u"�")
def test_utf8(self): self.assertEqual(text.force_text(u"ö".encode('utf-8')), u"ö")
def display_on_create(self, cdict): cdict['manifest'] = diff_value_text( "", "", force_text(cdict['manifest'])).rstrip("\n") return cdict
def display_on_delete(self, sdict): sdict['manifest'] = diff_value_text("", force_text(sdict['manifest']), "").rstrip("\n") return sdict
def _template_content(self): # required by content processors filename = join(self.item_data_dir, self.attributes['manifest_file']) if not exists(filename): filename = join(self.item_dir, self.attributes['manifest_file']) with open(filename, 'rb') as f: return force_text(f.read())