def write_file(self, word, word_field='name', this_path='', yaml_type='main'): ''' 从mongo中读取数据后,写入临时文件 :parm word:关键字 word_field:根据那个字段(name或者this_path)去关键字 this_path:写入的目录,如果提供按照指定目录写入,如果不指定随机目录 yaml_type:yaml类型。main、include、roles、full_roles四种 ''' if not this_path or not re.search('^/', this_path): this_path = self.temp_basedir + '/' + random_str() + str( int(time.time())) + '/' result = self.read2db(word, word_field=word_field, yaml_type=yaml_type) if result[0]: try: content = result[1]['content'] yaml_type = result[1]['type'] name = result[1]['name'] except: self.logger.error('通过关键字从数据库中搜索并读取数据失败,原因:数据写入数据库时出现错误') return (False, '数据写入数据库时出现错误') else: return result result = self.data2file(content, this_path, yaml_type=yaml_type, name=name) return result
def write_random_file(data): for i in range(10) : temp_file = '/dev/shm/lykops/' + random_str(ranlen=30) + str(i) + '_' + str(time.time()) result = write_file(temp_file, 'w', data) if result[0] : return (True, temp_file) return (False, '临时文件无法写入/dev/shm/lykops/')
def upload_file(file, upload_dir='', filename='', max_upload_size=1024 * 1024, chmods='444'): ''' 用于web页面上传文件 :parm file:上传文件内容 upload_file:上传目录,默认:在项目根目录下的/file/upload filename:上传后的文件名,默认:10个随机字符+_+文件名 max_upload_size:最大上传文件大小,默认为1M :return False:上传失败 filename:上传成功后的文件名 ''' try: if file.size > max_upload_size: return (False, '上传文件超过最大值') if not filename: filename = random_str(ranlen=10) + '_' + file.name except Exception as e: return (False, '上传失败,可能是参数file出问题,' + str(e)) if upload_dir: result = path_isexists(upload_dir) if not result[0]: upload_dir = os.path.join(BASE_DIR, 'file/upload/') make_dir(upload_dir, force=False, backup=False) else: upload_dir = os.path.join(BASE_DIR, 'file/upload/') make_dir(upload_dir, force=False, backup=False) this_path = upload_dir + filename result = path_isexists(upload_dir) if not result[0]: return (False, '上传目录不存在') with open(this_path, 'wb+') as dest: for chunk in file.chunks(): dest.write(chunk) os.system('chmod ' + str(chmods) + ' ' + this_path) return (True, this_path) return (False, '上传失败')
def data2file(self, content, this_path='', yaml_type='main', name='main'): ''' 写入临时文件 :parm content:yaml的原始内容 this_path:写入的目录,如果提供按照指定目录写入,如果不指定随机目录 yaml_type:yaml类型。main、include、roles、full_roles四种 name:用于确认include和roles的文件名 ''' if not this_path or not re.search('^/', this_path): this_path = self.temp_basedir + '/' + random_str() + str(int(time.time())) + '/' def type_roles(content_dict, roles_name): ''' 专用于类型为roles的数据写入 ''' for this_dir in content_dict : # roles_path = this_path + '/roles/' + os.path.basename(roles_name) + '/' + this_dir roles_path = this_path + '/roles/' + roles_name + '/' + this_dir if this_dir == 'templates' : for temp_file , temp_content in content_dict[this_dir].items() : filename = roles_path + '/' + temp_file result = self._write2file(temp_content, filename) if not result[0] : self.logger.error('将roles名为' + roles_name + '中的文件名为' + this_dir + '/' + temp_file + 'yaml数据内容写入文件' + filename + '失败,' + result[1]) return (False, '将roles名为' + roles_name + '中的文件名为' + this_dir + '/' + temp_file + 'yaml数据内容写入文件' + filename + '失败,' + result[1]) else : self.logger.info('将roles名为' + roles_name + '中的文件名为' + this_dir + '/' + temp_file + 'yaml数据内容写入文件' + filename + '成功') else : filename = roles_path + '/main.yaml' result = self._write2file(content_dict[this_dir], filename) if not result[0] : self.logger.error('将roles名为' + roles_name + '中的文件名为' + this_dir + '/main.yaml数据内容写入文件' + filename + '失败,' + result[1]) return (False, '将roles名为' + roles_name + '中的文件名为' + this_dir + '/main.yaml数据内容写入文件' + filename + '失败,' + result[1]) else : self.logger.info('将roles名为' + roles_name + '中的文件名为' + this_dir + '/main.yaml数据内容写入文件' + filename + '成功') return (True, this_path) log_prefix = '将yaml数据内容写入文件' if isinstance(content, str) : filename = this_path + name + '.yaml' result = self._write2file(content, filename) return result if not isinstance(content, dict) : self.logger.error(log_prefix + '失败,原因:数据写入数据库时出现错误') return (False, '数据写入数据库时出现错误') if yaml_type == 'roles' : result = type_roles(content, name) else : try : roles_dict = content['roles'] for roles_name in roles_dict : roles_content_dict = roles_dict[roles_name] result = type_roles(roles_content_dict, roles_name) except Exception as e : print(e) roles_dict = {} try : include_dict = content['include'] for incluce_file , incluce_content in include_dict.items() : filename = this_path + '/' + incluce_file result = self._write2file(incluce_content, filename) if not result[0] : self.logger.error(log_prefix + '失败,路径为' + filename + ',原因:' + str(result[1])) return (False, log_prefix + '失败,路径为' + filename + ',' + str(result[1])) except Exception as e : print(e) include_dict = {} try : main_content = content['main'] filename = this_path + '/main.yaml' result = self._write2file(main_content, filename) if not result[0] : self.logger.error(log_prefix + '失败,路径为' + filename + ',原因:' + str(result[1])) return (False, log_prefix + '失败,路径为' + filename + ',原因:' + str(result[1])) except Exception as e : print(e) main_content = '' self.logger.info(log_prefix + '成功,路径为' + this_path) return (True, this_path)
def import_upload(self, file, name, yaml_tpye='main', file_type='tasks', describe=''): result = upload_file(file) if not result: self.logger.error('为用户' + self.username + '上传文件方式导入ansible yaml数据失败,上传文件失败,原因:' + result[1]) return (False, '上传文件失败,' + result[1]) else: this_path = result[1] if yaml_tpye == 'roles': roles_path = '/dev/shm/lykops/ansible/yaml/' + random_str( ranlen=16) result = uncompress(this_path, roles_path) if not result[0]: self.logger.error( '为用户' + self.username + '上传文件方式导入ansible yaml数据失败,原因:不是一个压缩文件。注:系统要求导入类型为roles时,文件格式必须是zip格式的压缩文件、目录或者文件名等其中之一' ) return (False, '上传文件不是一个格式为zip格式的压缩文件') result = self.read2file_api.roles(roles_path, preserve=True, together=True, name=name, describe=describe) if result[0]: self.logger.info('为用户' + self.username + '从服务器本地路径为' + this_path + '导入ansible yaml数据成功') return (True, '对yaml文件进行语法验证等处理工作成功') else: self.logger.error( '为用户' + self.username + '从服务器本地路径为' + this_path + '导入ansible yaml数据失败,对yaml文件进行语法验证等处理工作时失败,原因:' + result[1]) return (False, '对yaml文件进行语法验证等处理工作时失败,原因:' + result[1]) elif yaml_tpye in ('main', 'full_roles'): result = get_filetype(this_path) if not result[0]: self.logger.error( '为用户' + self.username + '上传文件方式导入ansible yaml数据失败,原因:指定的路径为文件,但不是文本文件。注:系统要求导入类型为main或者full_roles时,如果路径是目录或者是压缩文件解压后的目录,必须带有main.yaml;如果是文件,必须是一个格式为zip格式的压缩文件或者是文本文件' ) return ( False, '指定的路径为文件,但不是文本文件。注:系统要求导入类型为main或者full_roles时,如果路径是目录或者是压缩文件解压后的目录,必须带有main.yaml;如果是文件,必须是一个格式为zip格式的压缩文件或者是文本文件' ) if result[1] == 'txt': pass elif result[1] == 'zip': dest_dir = '/dev/shm/lykops/ansible/yaml/' + random_str( ranlen=16) result = uncompress(this_path, dest_dir) if not result[0]: self.logger.error( '为用户' + self.username + '上传文件方式导入ansible yaml数据失败,原因:路径为' + this_path + '不是一个格式为zip的压缩文件。注:系统要求导入类型为main或者full_roles时,如果路径是目录或者是压缩文件解压后的目录,必须带有main.yaml;如果是文件,必须是一个格式为zip格式的压缩文件或者是文本文件' ) return (False, '路径为' + this_path + '不是一个格式为zip的压缩文件') this_path = dest_dir + '/main.yaml' if not os.path.exists(this_path): self.logger.error( '为用户' + self.username + '上传文件方式导入ansible yaml数据失败,原因:压缩文件解压后发现无法找到mai.yamln。注:系统要求导入类型为main或者full_roles时,如果路径是目录或者是压缩文件解压后的目录,必须带有main.yaml;如果是文件,必须是一个格式为zip格式的压缩文件或者是文本文件' ) return (False, '压缩文件解压后发现无法找到main.yaml') else: self.logger.error( '为用户' + self.username + '上传文件方式导入ansible yaml数据失败,原因:暂时只支持txt或者zip格式文件。注:系统要求导入类型为main或者full_roles时,如果路径是目录或者是压缩文件解压后的目录,必须带有main.yaml;如果是文件,必须是一个格式为zip格式的压缩文件或者是文本文件' ) return (False, '暂时只支持txt或者zip格式文件') result = self.read2file_api.main(this_path, preserve=True, together=True, name=name, describe=describe) if result[0]: self.logger.info('为用户' + self.username + '上传文件方式导入ansible yaml数据成功') return (True, '对yaml文件进行语法验证等处理工作成功') else: self.logger.error( '为用户' + self.username + '上传文件方式导入ansible yaml数据失败,对yaml文件进行语法验证等处理工作时失败,原因:' + result[1]) return (False, '对yaml文件进行语法验证等处理工作时失败,原因:' + result[1]) else: result = get_filetype(this_path) if not result[0]: self.logger.error( '为用户' + self.username + '上传文件方式导入ansible yaml数据失败,原因:不是文本文件。注:系统要求导入类型为include时,暂时只支持文本格式文件' ) return (False, '指定的路径为文件,但不是文本文件。注:系统要求导入类型为include时,暂时只支持文本格式文件') if result[1] == 'txt': result = self.read2file_api.include(this_path, file_type=file_type, preserve=True, name=name, describe=describe) if result[0]: self.logger.info('为用户' + self.username + '上传文件方式导入ansible yaml数据成功') return (True, '对yaml文件进行语法验证等处理工作成功') else: self.logger.error( '为用户' + self.username + '上传文件方式导入ansible yaml数据失败,对yaml文件进行语法验证等处理工作时失败,原因:' + result[1]) return (False, '对yaml文件进行语法验证等处理工作时失败,原因:' + result[1]) else: self.logger.error( '为用户' + self.username + '上传文件方式导入ansible yaml数据失败,原因:不是txt格式文件。注:系统要求导入类型为include时,暂时只支持文本格式文件' ) return (False, '暂时只支持文本格式文件')
def write_file(self, username, vault_password, group_list=[]): self.init_para(username) result = self.get_data(username, self.inve_rediskey, self.inve_mongocollect, force=False, mongoshare=False) if not group_list or not (isinstance(group_list, (list, tuple)) or group_list == 'all') or 'all' in group_list: group_list = self.group_list used_hosts_list = [] group_dict = {} if result[0] : allhost_data = result[1] for data in allhost_data : result = self.decryp_dict(username, vault_password, data, self.host_vault_list) if not result[0] : return result data = result[1] group = data.get('group', []) try : for g in group : if g in group_list : name = data.get('name', '') if g not in group_dict : if g != 'all' : group_dict[g] = [] if name not in used_hosts_list : ansible_ssh_host = data['ssh_host'] ansible_ssh_port = data.get('ssh_port', '') ansible_ssh_user = data.get('ssh_user', '') ansible_ssh_pass = data.get('ssh_pass', '') ansible_sudo_pass = data.get('sudo_pass', '') ansible_sudo_exec = data.get('sudo_exec', '') ansible_ssh_private_key_file = data.get('ssh_private_key_file', '') ansible_shell_type = data.get('shell_type', '') ansible_connection = data.get('connection', '') ansible_python_interpreter = data.get('python_interpreter', '') host_str = str(name) + ' ansible_ssh_host=' + str(ansible_ssh_host) protect_str = str(name) + ' ansible_ssh_host=' + str(ansible_ssh_host) if ansible_ssh_port : host_str = host_str + ' ansible_ssh_port=' + str(ansible_ssh_port) protect_str = protect_str + ' ansible_ssh_port=' + str(ansible_ssh_port) if ansible_ssh_user : host_str = host_str + ' ansible_ssh_user='******' ansible_ssh_user='******' ansible_ssh_pass='******' ansible_ssh_pass='******'***hidden***' if ansible_sudo_pass : host_str = host_str + ' ansible_sudo_pass='******' ansible_sudo_pass='******'***hidden***' if ansible_sudo_exec : host_str = host_str + ' ansible_sudo_exec=' + str(ansible_sudo_exec) protect_str = protect_str + ' ansible_sudo_exec=' + str(ansible_sudo_exec) if ansible_ssh_private_key_file : host_str = host_str + ' ansible_ssh_private_key_file=' + str(ansible_ssh_private_key_file) protect_str = protect_str + ' ansible_ssh_private_key_file=' + '***hidden***' if ansible_shell_type : host_str = host_str + ' ansible_shell_type=' + str(ansible_shell_type) protect_str = protect_str + ' ansible_shell_type=' + str(ansible_shell_type) if ansible_connection : host_str = host_str + ' ansible_connection=' + str(ansible_connection) protect_str = protect_str + ' ansible_connection=' + str(ansible_connection) if ansible_python_interpreter : host_str = host_str + ' ansible_python_interpreter=' + str(ansible_python_interpreter) protect_str = protect_str + ' ansible_python_interpreter=' + str(ansible_python_interpreter) group_dict[g].append((host_str, protect_str)) used_hosts_list.append(name) except : pass content_str = '' protect_content_str = '' for group in group_dict : content_list = group_dict[group] if content_str : content_str = content_str + '\n[' + group + ']' protect_content_str = protect_content_str + '\n[' + group + ']' else : content_str = '[' + group + ']' protect_content_str = '[' + group + ']' for content in content_list : host_str = content[0] protect_str = content[1] content_str = content_str + '\n' + host_str protect_content_str = protect_content_str + '\n' + protect_str content_str = content_str + '\n' protect_content_str = protect_content_str + '\n' inve_file = '/dev/shm/lykops/ansible/inventory_' + random_str() result = write_file(inve_file , 'w' , content_str) if result[0] : self.logger.info('将用户' + username + '主机按照ansible的hosts.conf格式写入临时文件成功') return (True, inve_file, protect_content_str) else : self.logger.info('将用户' + username + '主机按照ansible的hosts.conf格式写入临时文件失败,原因:' + result[1]) return result