def post(self, request, **kwargs): try: post_data = json.loads(request.body) sys_name = post_data.get('sys_name') login_address = post_data.get('login_address') device = NetDevice.objects.filter(sys_name=sys_name) if device.exists(): device = device[0] else: device = NetDevice.objects.create(**post_data) if Ip.objects.filter(ip=login_address).exists(): ip = Ip.objects.get(ip=login_address) else: seg = get_segment_by_ip(login_address) ip = get_or_create_ip_obj(seg.vlan.idc.idc_name, seg.vlan.vlan_num, login_address) if not device.idc: device.idc = ip.segment.vlan.idc device.save(update_fields=['idc']) if ip not in device.ip.all(): device.ip.add(ip) # device = NetDevice.objects.filter(login_address=login_address) # if device.exists(): # device = device[0] # if Ip.objects.filter(ip=login_address).exists(): # ip = Ip.objects.get(ip=login_address) # if ip not in device.ip.all(): # device.ip.add(ip) # device.sys_name = sys_name # device.save(update_fields=['sys_name']) res = {'code': 0, 'result': 'Success: Automatic add ip:%s to NetDevice:%s!' % (login_address, device.sys_name)} except Exception as e: res = {'code': 1, 'errmsg': 'Failed: /cmdb/v1/net_device_list/\n' + str(e)} send_msg_to_admin(json.dumps(res)) return self.render_json_response(res)
def cmdb_agent_running_check(): try: one_day_ago = ( datetime.date.today() + datetime.timedelta(days=-1)).strftime("%Y-%m-%d %H:%M:%S") one_day_no_updated = list() for s in Server.objects.filter(date_last_checked__lte=one_day_ago).exclude(uuid='').exclude(comment='pod').\ exclude(status__in=['deleted', 'ots']): nic_list = Nic.objects.filter(server=s) ips = [ '{}({})'.format(ip.ip, ip.last_detected) for nic in nic_list for ip in nic.ip.all() ] if not ips: if not s.app.all() and not s.pre_app.all() and s.is_vm is True: print(s.hostname, s.date_last_checked) s.delete() continue one_day_no_updated.append( "%-20s\t%-20s\t%-20s\t%-20s\n" % (s.hostname, ','.join(ips), s.applicant, s.date_last_checked)) if one_day_no_updated: num = 0 while num < len(one_day_no_updated): pprint(one_day_no_updated[num:num + 500]) send_msg_to_admin( '以下服务器与cmdb失联超过1天,请确认cmdb_agent脚本正常执行:\n主机名\tIP\t申请人\t最后一次检测时间\n' + '\n'.join(one_day_no_updated[num:num + 500])) num += 500 except Exception: send_msg_to_admin(str(traceback.print_exc()))
def post(self, request): try: date_now = datetime.datetime.now().strftime("%Y%m%d%H%M%S") redis_key = str(uuid.uuid4()) task_name = request.POST.get('task_name') host_user = request.POST.get('host_user') program = request.POST.get('program') execute = request.POST.get('execute') task = Task.objects.create(name=date_now + "-" + task_name, user=request.user, exec_type=execute, task_type="download") data = { "host_user": host_user, "resource": list(), "hosts_file": [request.POST.get('inventory')] } if program == "ansible": host = request.POST.get('host') ansible_module = request.POST.get('module') # 获取远程主机上的文件,并下载到本机 src_file = request.POST.get('src_file') dest_file = request.POST.get('dest_file') task.source_file = src_file task.destination_file = dest_file task.save(update_fields=['source_file', 'destination_file']) tmp_dir = os.path.join(FILE_DOWNLOAD_TMP_DIR, request.user.username, str(task.id)) make_directory(tmp_dir) data.update({ "module_name": ansible_module, "module_args": "src={} dest={}-{{{{inventory_hostname}}}} flat=yes". format(src_file, os.path.join(tmp_dir, dest_file)) }) async_func.delay(task.id, redis_key, host=host, **data) else: # paramiko task = Task.objects.create(name=date_now + "-" + task_name, user=request.user, exec_type=program) except Exception as e: send_msg_to_admin(traceback.print_exc()) return self.render_json_response({'code': 1, 'errmsg': str(e)}) return self.render_json_response({'code': 0, 'result': '命令已提交!'})
def no_binding_ip_check(): try: no_device_binding_msg = '' for ip in Ip.objects.all(): if Nic.objects.filter(ip=ip).exists() \ or Pod.objects.filter(ip=ip.ip).exists()\ or NetDevice.objects.filter(ip=ip).exists(): pass else: no_device_binding_msg += "%-20s\t%-20s\t%-20s\n" % ( ip.ip, ip.comment, ip.last_detected) if no_device_binding_msg: send_msg_to_admin('以下ip没有与任何主机设备关联:\nIP\t备注\t最后一次检测时间\n' + no_device_binding_msg) except Exception: send_msg_to_admin(str(traceback.print_exc()))
def dead_ip_check(): try: three_day_ago = ( datetime.date.today() + datetime.timedelta(days=-3)).strftime("%Y-%m-%d %H:%M:%S") dead_ip_list = list() for ip in Ip.objects.filter(last_detected__lte=three_day_ago): dead_ip_list.append("%-20s\t%-20s\t%-20s" % (ip.ip, ip.comment, ip.last_detected)) if dead_ip_list: pprint(dead_ip_list) send_msg_to_admin( '以下ip3天未扫描到(请确定是否可以释放ip资源):\nIP\t备注\t最后一次检测时间\n' + '\n'.join(dead_ip_list)) except Exception: send_msg_to_admin(str(traceback.print_exc()))
def host_alive_check(): try: one_day_ago = ( datetime.date.today() + datetime.timedelta(days=-1)).strftime("%Y-%m-%d %H:%M:%S") one_day_no_updated = '' for s in Server.objects.filter(date_last_checked__lte=one_day_ago): ips = get_ips_by_server_id(s.id) one_day_no_updated += "%-20s\t%-20s\t%-20s\t%-20s\n" % ( s.hostname, ','.join(ips), s.applicant, s.date_last_checked) if one_day_no_updated: send_msg_to_admin( '以下服务器与cmdb失联超过1天,请确认cmdb_agent.py脚本正常执行:\n主机名\tIP\t申请人\t最后一次检测时间\n' + one_day_no_updated) except Exception: send_msg_to_admin(str(traceback.print_exc()))
def post(self, request, *args, **kwargs): ip_mac_changed, ip_not_bonded, ip_not_exists = list(), list(), list() try: print(request.body) post_data = json.loads(request.body.decode("utf-8")) segment = "" if len(post_data) == 0 else str(IP(list(post_data.keys())[0]).make_net('255.255.255.0').net()) for ip, mac in post_data.items(): if Ip.objects.filter(ip=ip).exists(): Ip.objects.filter(ip=ip).update(last_detected=datetime.datetime.now()) if Nic.objects.filter(mac_address=mac.lower(), ip__ip=ip).exists(): pass elif Server.objects.filter(manage_address=ip).exists(): pass elif NetDevice.objects.filter(ip__ip=ip).exists(): pass elif Nic.objects.filter(mac_address=mac.lower()).exists(): ip = Ip.objects.get(ip=ip) Nic.objects.get(mac_address=mac.lower()).ip.add(ip) else: # 根据 mac_address 找不到网卡,ip 地址可以查到网卡,且该 网卡 绑定的网卡名和mac都是其 hostname # 说明该网卡是esx采集脚本采集而来,server 是vmware 主机。所以,更新该网卡的mac_address为真正的mac地址 nic = Nic.objects.filter(ip__ip=ip) if nic: nic = nic[0] if nic.nic_name == nic.mac_address == nic.server.hostname: nic.mac_address = mac nic.save(update_fields=['mac_address']) else: ip_mac_changed.append("{} {}".format(ip, mac)) else: ip_not_bonded.append("{} {}".format(ip, mac)) else: ip_not_exists.append("{} {}".format(ip, mac)) res = {'code': 0, 'result': '执行成功', 'ip_mac_changed': '%s' % ','.join(ip_mac_changed), 'ip_not_bonded': '%s' % ','.join(ip_not_bonded), 'ip_not_exists': '%s' % ','.join(ip_not_exists)} send_msg = "检测ip段:{0}/24\nip存在,mac不同:\n{1}\nip未绑定:\n{2}\nip不存在:\n{3}".format( segment, '\n'.join(ip_mac_changed), '\n'.join(ip_not_bonded), '\n'.join(ip_not_exists)) except Exception as e: res = {'code': 1, 'errmsg': '执行出错:%s' % str(e)} send_msg = "/cmdb/v1/ip_check/ 执行出错:\n%s" % str(e) send_msg_to_admin(send_msg) return self.render_json_response(res)
def no_binding_ip_check(): try: no_device_binding = list() for ip in Ip.objects.all(): if Nic.objects.filter(ip=ip).exists() or NetDevice.objects.filter( ip=ip).exists(): continue if Server.objects.filter( manage_address=ip.ip).exists() or Server.objects.filter( manage_address=ip.ip + ":22").exists(): continue no_device_binding.append("%-20s\t%-20s\t%-20s" % (ip.ip, ip.comment, ip.last_detected)) if no_device_binding: pprint(no_device_binding) send_msg_to_admin('以下ip没有与任何主机设备关联:\nIP\t备注\t最后一次检测时间\n' + '\n'.join(no_device_binding)) except Exception: send_msg_to_admin(str(traceback.print_exc()))
def application_update(data): url = "http://wex.yadoom.com/api/wex/api/application/update" # data = { # "app_code": data["app_code"], # "app_name": data["app_name"], # "app_type": data["app_type"], # "tomcat_port": data["tomcat_port"], # "scm_url": data["scm_url"], # "importance": data["importance"], # "domain_name": data["domain_name"], # "primary": data["primary"], # "secondary": data["secondary"], # "comment": data["comment"] # } headers = {"Content-Type": "application/json; charset=UTF-8"} status, ret = http_request.post(url=url, params=json.dumps(data), headers=headers) if status is False: send_msg_to_admin("wex更新应用接口调用出错:\n" + ret) print(ret)
def sync_ding_user_id(self): """ 本公司使用工号(username)登陆oneops,并且工号对应钉钉系统中字段 "jobnumber"。 所以可根据钉钉中 jobnumber 查到该用户的 ding_user_id。 """ try: for dept_id in self.root_dept_id.split(','): dept_id_list = self.get_dept_list_id_fetch_child(dept_id) for di in dept_id_list: url = 'https://oapi.dingtalk.com/user/list?access_token={0}&department_id={1}'.format( self.token, di) try: resp = requests.get(url, timeout=3) ret = str(resp.content, encoding="utf8") # print('user_list_by_dept_id:', ret) s = json.loads(ret) if s["errcode"] == 0: for u in s["userlist"]: try: cmd = """SETEX {} 86400 {}""".format( u[self.key], u["userid"]) rs.execute_command(cmd) except: send_msg_to_admin(traceback.print_exc()) else: print(ret) except: send_msg_to_admin(traceback.print_exc()) time.sleep(1) except Exception: send_msg_to_admin(traceback.print_exc())
def async_func(task_id, t_uuid, host=None, **kwargs): _task = Task.objects.get(id=task_id) try: if _task.exec_type == "ad-hoc": # 高危命令校验 white_cmd, perilous_cmd, sensitive_cmd = get_perilous_cmd( _task.user) if white_cmd or perilous_cmd or sensitive_cmd: if kwargs.get("module_name") in ["command", "raw"]: if perilous_cmd_check(kwargs.get('module_args'), white_cmd, perilous_cmd, sensitive_cmd) is False: _task.error_msg = "您的命令已被黑白名单拦截!请联系管理员添加权限" _task.executed = True _task.save(update_fields=['executed', 'error_msg']) return else: _task.error_msg = "您被设置了命令黑白名单,只能执行command、raw模块!" _task.executed = True _task.save(update_fields=['executed', 'error_msg']) return ansible_api = AnsibleAPI(_task.id, t_uuid, **kwargs) ansible_api.run_ad_hoc(host, kwargs.get('module_name'), kwargs.get('module_args')) elif _task.exec_type == "playbook": ansible_api = AnsibleAPI(_task.id, t_uuid, **kwargs) ansible_api.run_playbook([kwargs.get('playbook')], json.loads(kwargs.get('extra_vars'))) else: _task.error_msg = "调用错误!" _task.save(update_fields=['error_msg']) return ansible_api.save_result() except Exception as e: send_msg_to_admin(traceback.print_exc()) _task.error_msg = str(e) _task.task_nums = TaskLog.objects.filter(task_id=_task.id).count() _task.executed = True _task.save(update_fields=['task_nums', 'executed', 'error_msg'])
def no_binding_and_dead_ip_check(): no_device_binding = list() for ip in Ip.objects.all(): if Nic.objects.filter(ip=ip).exists() or NetDevice.objects.filter( ip=ip).exists(): continue if Server.objects.filter( manage_address=ip.ip).exists() or Server.objects.filter( manage_address=ip.ip + ":22").exists(): continue no_device_binding.append("%-20s\t%-20s\t%-20s" % (ip.ip, ip.comment, ip.last_detected)) three_day_ago = (datetime.date.today() + datetime.timedelta(days=-3)).strftime("%Y-%m-%d %H:%M:%S") dead_ip_list = list() for ip in Ip.objects.filter(last_detected__lte=three_day_ago): dead_ip_list.append("%-20s\t%-20s\t%-20s" % (ip.ip, ip.comment, ip.last_detected)) # 两个list交集 res = list(set(no_device_binding).intersection(set(dead_ip_list))) if res: pprint(res) send_msg_to_admin('以下ip未绑定设备,并且3天未扫描到:\nIP\t备注\t最后一次检测时间\n' + '\n'.join(res))
def get_or_create_ip_obj(idc, vlan, ip, netmask='255.255.255.0'): print(idc, vlan, ip) try: if IDC.objects.filter(idc_name=idc).exists(): idc = IDC.objects.get(idc_name=idc) ipy = IP(ip).make_net(netmask) if vlan is not None: segment = NetworkSegment.objects.filter(vlan__vlan_num=vlan, segment=str(ipy.net())) else: vlan_list = [vlan for vlan in idc.vlan_set.all()] segment = NetworkSegment.objects.filter(vlan__in=vlan_list, segment=str(ipy.net())) if segment: if Ip.objects.filter(ip=ip, segment=segment[0]).exists(): return Ip.objects.get(ip=ip, segment=segment[0]) return Ip.objects.create(ip=ip, segment=segment[0]) else: send_msg_to_admin("Create Ip Instance Failed:{} {} {}\n无法找到该ip对应的网段!".format(idc, vlan, ip)) else: send_msg_to_admin("Create Ip Instance Failed:{} {} {}\n无法找到该IDC!".format(idc, vlan, ip)) except Exception as e: traceback.print_exc() send_msg_to_admin("Create Ip Instance Failed:{} {} {}\n{}".format(idc, vlan, ip, str(e))) return None
def api_compatibility(request): post_data = json.loads(request.body.decode('utf-8')) if 'hostname' in post_data and 'sn' in post_data: if post_data['os'] != 'VMware ESX': send_msg_to_admin("还在跑老cmdb_agent脚本:" + post_data.get('hostname') + ' sn:' + post_data.get('sn')) jsonrpc_id = post_data['id'] func = post_data['method'] print(jsonrpc_id, type(jsonrpc_id), func) if jsonrpc_id == 1 and func == 'server.radd': try: data = post_data['params'] if "server_cpu" in data: data['cpu_total'] = data.pop('server_cpu') if "server_mem" in data: data['mem_total'] = data.pop('server_mem') if "used_cpu" in data: data['cpu_used'] = data.pop('used_cpu') if "used_mem" in data: data['mem_used'] = data.pop('used_mem') if "server_disk" in data: data['disk'] = data.pop('server_disk') if "disk_used" in data: data.pop("disk_used") if "vendor" in data: data["manufacturer"] = data.pop("vendor") if "vm_num" in data: data['vm_count'] = data.pop('vm_num') storage_info = dict() if "vmware_disk" in data: vmware_disk = data.pop('vmware_disk') print(vmware_disk) data["disk"] = '{}/{}%'.format(vmware_disk["total"], vmware_disk["used_pct"]) storage_info = vmware_disk["detail"] # 从esx获取信息时,可得到宿主机的hostname,将其转换成 parent_id if "parent_host" in data: parent_host_name = data.pop("parent_host") if Server.objects.filter(hostname=parent_host_name).exists(): data["parent_id"] = Server.objects.get(hostname=parent_host_name).id # 从openstack获取信息,可获取宿主机的hostname和虚拟机的uuid。所以要根据宿主机的hostname得到parent_id。 # 当根据 hostname取出多台或0台,则不做处理。 if "parent_host_name" in data: parent_host_name = data.pop("parent_host_name") if parent_host_name == "": return JsonResponse({'code': 1, 'errmsg': 'parent hostname is null!'}) if Server.objects.filter(hostname=parent_host_name).count() == 1: data["parent_id"] = Server.objects.get(hostname=parent_host_name).id # 从openstack获取信息,版本太低获取不到 虚拟主机的uuid。只能根据hostname来确定主机。 # 当根据 hostname取出多台或0台,则不做处理。 if "uuid" not in data: if Server.objects.filter(hostname=data["hostname"]).count() == 1: data["uuid"] = Server.objects.get(hostname=data["hostname"]).uuid if "nic_mac_ip" in data: nic_mac_ip_dict = data.pop("nic_mac_ip") if isinstance(nic_mac_ip_dict, str): nic_mac_ip_dict = json.loads(nic_mac_ip_dict) else: nic_mac_ip_dict = {} if "tomcat_ports" in data: tomcat_ports = data.pop("tomcat_ports") else: tomcat_ports = list() if "check_update_time" in data: data["date_last_checked"] = data.pop("check_update_time") else: data["date_last_checked"] = datetime.datetime.now() if "product_name" in data: if re.search(r'OpenStack|KVM|Virtual', data['product_name'], re.I): data['is_vm'] = True if "uuid" in data and data["uuid"] != "": if "hostname" in data: server_query = Server.objects.filter(uuid=data["uuid"]) if server_query.exists(): server_query.update(**data) server = Server.objects.filter(uuid=data["uuid"])[0] else: # server 不存在 server = Server.objects.create(**data) else: Server.objects.filter(uuid=data["uuid"]).update(**data) return JsonResponse({'code': 0, 'result': 'update server success'}) else: # uuid 为空,则无法精确匹配到server,直接退出 return JsonResponse({'code': 1, 'errmsg': 'uuid is null!'}) # 重新绑定vmware存储 if storage_info: Storage.objects.filter(server=server).delete() for k, v in storage_info.items(): Storage.objects.create(server=server, name=k, total=v[0], free=v[1], used_pct=v[2]) # 录入资源使用率 ServerResource.objects.create(s=server, cpu_used=data['cpu_used'], mem_used=data['mem_used']) # 重新绑定该服务器 和 应用 tomcat_ports = [int(p) for p in tomcat_ports] if re.match(r'^jf-prod-|^jf-pre-', data['hostname'], re.I): tomcat_ports_last = [a.tomcat_port for a in server.app.all()] tomcat_ports_pre = [a.tomcat_port for a in server.pre_app.all()] # 之前存在,这次不存在。说明该应用已下线 yixiaxian = [port for port in tomcat_ports_last if port not in tomcat_ports] # 之前不存在,这次存在。说明该应用刚上线 yufenpeishangxian, weifenpeishangxian = list(), list() for port in tomcat_ports: if port not in tomcat_ports_last and port in tomcat_ports_pre: yufenpeishangxian.append(port) if port not in tomcat_ports_last and port not in tomcat_ports_pre: weifenpeishangxian.append(port) if yixiaxian or yufenpeishangxian or weifenpeishangxian: msg = """应用变动告警:{}\n下线:{}\n预分配应用上线:{}\n未预分配应用上线:{}\n未录入端口:{}""".format( server.hostname, " ".join( [str(a.tomcat_port) + "-" + a.app_code for a in App.objects.filter(tomcat_port__in=yixiaxian)]), " ".join( [str(a.tomcat_port) + "-" + a.app_code for a in App.objects.filter(tomcat_port__in=yufenpeishangxian)]), " ".join( [str(a.tomcat_port) + "-" + a.app_code for a in App.objects.filter(tomcat_port__in=weifenpeishangxian)]), " ".join( [str(p) for p in tomcat_ports if not App.objects.filter(tomcat_port=p).exists()]) ) send_msg_to_admin(msg) server.app.set(App.objects.filter(tomcat_port__in=tomcat_ports)) for app in App.objects.filter(tomcat_port__in=tomcat_ports): server.pre_app.remove(app) if re.match(r'^(JF|wry)-prod-(?!beta)', data['hostname'], re.I): server.app_env = 'prod' elif re.match(r'^(JF|wry)-prod-beta-', data['hostname'], re.I): server.app_env = 'beta' elif re.match(r'^(JF|wry)-pre-', data['hostname'], re.I): server.app_env = 'pre' elif re.match(r'^mdc-|wry-stable-', data['hostname'], re.I): server.app_env = 'test' else: server.app_env = 'unknown' if re.search(r'-it\d?', data['hostname'], re.I): server.department = BizMgtDept.objects.get(dept_code='it') elif re.search(r'-yunwei\d?', data['hostname'], re.I): server.department = BizMgtDept.objects.get(dept_code='yunwei') elif re.search(r'-bigdata\d?', data['hostname'], re.I): server.department = BizMgtDept.objects.get(dept_code='bigdata') elif re.search(r'-zhifu\d?', data['hostname'], re.I): server.department = BizMgtDept.objects.get(dept_code='zhifu') elif re.search(r'-zichan\d?', data['hostname'], re.I): server.department = BizMgtDept.objects.get(dept_code='zichan') elif re.search(r'-zhongjianjian\d?', data['hostname'], re.I): server.department = BizMgtDept.objects.get(dept_code='zhongjianjian') elif re.search(r'-zijin\d?', data['hostname'], re.I): server.department = BizMgtDept.objects.get(dept_code='zijin') idc = None if nic_mac_ip_dict: # 取出nic表所有该 server 的记录,下面会将该server 不存在的nic 删除。 last_nic_ids = [n.id for n in Nic.objects.filter(server=server)] """ data = { ["mac1"]:[ {"eth0": [ip1, ip2]}, {"eth0.1": [ip3]} ], ["mac2"]:..., } """ print(type(nic_mac_ip_dict), nic_mac_ip_dict) ip_total = list() for (mac, nic_ips_list) in nic_mac_ip_dict.items(): print(type(nic_ips_list), nic_ips_list) for nic_ips in nic_ips_list: for (nic, ips) in nic_ips.items(): print(mac, nic, ips, type(ips)) if nic == mac: # vmware host if Nic.objects.filter(nic_name=mac).exists(): # vmware host nic = Nic.objects.get(nic_name=mac) last_nic_ids.remove(nic.id) if nic.id in last_nic_ids else None else: nic_data = {'nic_name': nic, 'mac_address': mac, 'server': server, 'date_last_checked': datetime.datetime.now()} nic = Nic.objects.create(**nic_data) else: # 网卡处理,先解绑该网卡绑定的所有ip。然后再给该网卡绑定 本次扫描到的ip。 nic_query = Nic.objects.filter(nic_name=nic, mac_address=mac.lower().replace('-', ':')) if nic_query.exists(): # 网卡已存在,则更新其 nic_name和server nic_query.update(**{'server': server, 'date_last_checked': datetime.datetime.now()}) nic = nic_query[0] last_nic_ids.remove(nic.id) if nic.id in last_nic_ids else None else: # 根据mac查不到网卡,则创建网卡记录,并绑定server nic_data = {'nic_name': nic, 'mac_address': mac.lower().replace('-', ':'), 'server': server, 'date_last_checked': datetime.datetime.now()} nic = Nic.objects.create(**nic_data) # ip 处理 for ip in ips: ip_total.append(ip) ip_query = Ip.objects.filter(ip=ip) if ip_query: ip = ip_query[0] idc = ip.segment.vlan.idc # IP已存在,则更新last_detected 最后一次检测到的时间 ip_query.update(**{'last_detected': datetime.datetime.now()}) # 删除nic表中该ip的记录,下面会重新创建绑定 for n in Nic.objects.filter(ip=ip): n.ip.remove(ip) else: # IP 不存在,则新建 seg = get_segment_by_ip(ip) ip = get_or_create_ip_obj(seg.vlan.idc.idc_name, seg.vlan.vlan_num, ip, seg.netmask) idc = seg.vlan.idc if isinstance(ip, Ip): # 重新绑定nic和ip nic.ip.add(ip) if len(ip_total) == 1: if not server.login_address or server.login_address == '127.0.0.1:22': server.login_address = ip_total[0] elif re.match(r'^\d{,3}\.\d{,3}\.\d{,3}\.\d{,3}$', server.login_address): server.login_address = server.login_address + ':22' elif not re.match(r'\d{,3}\.\d{,3}\.\d{,3}\.\d{,3}:\d{,5}', server.login_address): send_msg_to_admin( 'Login_address error: {} {}!'.format(server.hostname, server.login_address)) # 在脚本取到网卡的前提下,上一次记录last_nic_ids,这次还未重新绑定的,表示它不再与server 有关联,需删除该条垃圾数据 if last_nic_ids and nic_mac_ip_dict: Nic.objects.filter(id__in=last_nic_ids).delete() if idc: # 根据ip推出主机所在的机房 server.idc = idc server.save() return JsonResponse({'code': 0, 'result': 'create server success'}) except Exception as e: print(traceback.print_exc()) return JsonResponse({'code': 1, 'errmsg': str(e)})
def run_tomcat(flow_id, user_id, app_id, hostname, step): cf = CommonFlow.objects.get(id=flow_id) wf = cf.workflow user = User.objects.get(id=user_id) app = App.objects.get(id=app_id) try: s = app.app_server.get(hostname=hostname) resource = GenResource.gen_host_list([s.id]) ans = AnsibleAPI(0, str(uuid.uuid4()), resource=resource, hosts_file=None) date_now = datetime.datetime.now().strftime("%Y%m%d%H%M") file_name = "%s-%s" % (date_now, app.app_code) extra_vars = { "apphost": "default_group", "app_name": app.app_code, "app_port": app.tomcat_port, "file_name": file_name } if cf.workflow.code == 'tomcat_dump': ans.run_playbook( playbook=["/data/ansible/playbook/admin/tomcat_dump.yml"], extra_vars=extra_vars) cont = "文件下载地址:{}/media/tomcat/{}.phrof".format( ROOT_URL, file_name) # 邮件发给当前流程的操作人,并抄送应用申请人 及 当前流程操作组中的其他人 mail_to = [cf.applicant.email] flow_step = FlowStep.objects.get(workflow=wf, step=step) mail_cc = list() for email in app.primary.split(",") + app.secondary.split(","): mail_cc.append(email) for u in flow_step.group.user_set.all(): mail_cc.append(u.email) mail_cont = """ 应用名:{0} 端口:{1} 导出服务器:{2} 工单地址:{3}{4} 该Tomcat在线Dump流程已执行! """.format( app.app_code, app.tomcat_port, hostname, ROOT_URL, reverse_lazy('workflow:flow-tomcat-dump-detail', kwargs={'flow_id': int(flow_id)})) MailSender().send_email("%s Tomcat在线Dump流程已执行" % app.app_code, mail_cont, list_to_addr=list(set(mail_to)), list_cc_addr=list(set(mail_cc))) FlowStepLog.objects.create(cf=cf, flow_step=flow_step, operator=user, is_passed=True, reply=mail_cont) elif cf.workflow.code == 'tomcat_jstack': ans.run_playbook( playbook=["/data/ansible/playbook/admin/tomcat_jstack.yml"], extra_vars=extra_vars) cont = "文件下载地址:{}/media/tomcat/{}.jstack".format( ROOT_URL, file_name) cf.current_step = step cf.status = 'end' cf.save(update_fields=['current_step', 'status']) flow_step = FlowStep.objects.get(workflow=wf, step=step + 1) FlowStepLog.objects.filter(cf=cf, flow_step=flow_step, operator=user).update(is_passed=True, reply=cont) except Exception as e: cf.result = traceback.print_exc() cf.save(update_fields=['result']) send_msg_to_admin(traceback.print_exc())
def post(self, request): try: date_now = datetime.datetime.now().strftime("%Y%m%d%H%M%S") redis_key = str(uuid.uuid4()) task_name = request.POST.get('task_name') host_user = request.POST.get('host_user') program = request.POST.get('program') execute = request.POST.get('execute') task = Task.objects.create(name=date_now + "-" + task_name, user=request.user, exec_type=execute, task_type="upload") data = { "host_user": host_user, "resource": list(), "hosts_file": [request.POST.get('inventory')] } if program == "ansible": host = request.POST.get('host') ansible_module = request.POST.get('module') # 获取上传的文件,并拷贝到目标主机 upload_args = request.POST.get('upload_args') upload_files = request.FILES.getlist('upload_file', []) if len(upload_files) == 0: task.error_msg = '文件未上传成功!' task.save(update_fields=['task_type', 'error_msg']) return self.render_json_response({ 'code': 1, 'errmsg': '文件未上传成功!' }) task.source_file = '|'.join( [u_file.name for u_file in upload_files]) task.save(update_fields=['source_file']) if re.match(r'dest=\S+', upload_args): task.destination_file = re.match( r'(?:dest=)\S+', upload_args).group().replace('dest=', '') task.save(update_fields=['destination_file']) else: task.error_msg = '缺少参数"dest=/path/to/"' task.save(update_fields=['error_msg']) return self.render_json_response({ 'code': 1, 'errmsg': '缺少参数"dest=/path/to/"' }) tmp_dir = os.path.join(FILE_UPLOAD_TMP_DIR, request.user.username, str(task.id)) make_directory(tmp_dir) for u_file in upload_files: file_path = os.path.join(tmp_dir, u_file.name) with open(file_path, 'wb') as f: for chunk in u_file.chunks(): f.write(chunk) data.update({ "module_name": ansible_module, "module_args": "src={} {}".format(file_path, upload_args) }) async_func.delay(task.id, redis_key, host=host, **data) else: # paramiko task = Task.objects.create(name=date_now + "-" + task_name, user=request.user, exec_type=program) except Exception as e: send_msg_to_admin(traceback.print_exc()) return self.render_json_response({'code': 1, 'errmsg': str(e)}) return self.render_json_response({'code': 0, 'result': '命令已提交!'})
cont = list() if is_disabled is True: # 员工已离职,统一身份系统返回状态为"禁用",此处也禁用堡垒机账户 r = requests.post(blj_update.format(work_no), data={'status': 0}, headers=headers, verify=False) print("disable ", work_no, r.text) User.objects.filter(username=work_no).update(is_active=False) cont.append('{}({}) 已离职,已禁用其堡垒机账户。'.format(work_no, fullname)) RetiredEmployeeRecord.objects.create(work_no=work_no, display=fullname, comment=cont) send_msg_to_admin( '\n'.join(cont), "[email protected],[email protected]") elif department_id is not None: if User.objects.filter(username=work_no).exists(): user = User.objects.get(username=work_no) if user.ding_dept_id: if user.ding_dept_id != department_id: # 用户更换了部门,发告警信息给管理员 cont.append('{}({}) 更换了部门,请询问是否还需要使用堡垒机!'.format( work_no, user.display)) # RetiredEmployeeRecord.objects.create( # work_no=work_no, display=fullname, comment=cont # ) # send_msg_to_admin('\n'.join(cont), "[email protected],[email protected]")
def post(self, request, *args, **kwargs): data = json.loads(request.body.decode('utf-8')) try: print(data) if "release_date" in data: release_date = data.pop("release_date") if re.search(r'(\d\d/\d\d/\d\d\d\d)$', release_date, re.I): # 12/14/2018 release_date = re.findall(r'(\d\d/\d\d/\d\d\d\d)$', release_date, re.I)[0] data["release_date"] = datetime.datetime.strptime(release_date, "%m/%d/%Y").strftime("%Y-%m-%d") elif re.search(r'(\d\d\d\d\d\d\d\d)$', release_date, re.I): # 20181214 data["release_date"] = datetime.datetime.strptime(release_date, "%Y%m%d").strftime("%Y-%m-%d") elif release_date: # 2018-12-14 data["release_date"] = release_date if "disk" in data: data["disk"] = "\n".join(data.pop("disk")) if "nic_mac_ip" in data: nic_mac_ip_dict = data.pop("nic_mac_ip") if isinstance(nic_mac_ip_dict, str): nic_mac_ip_dict = json.loads(nic_mac_ip_dict) else: nic_mac_ip_dict = {} if "time" in data: send_msg_to_admin("还在跑老cmdb_agent脚本:" + data.get('hostname') + ' sn:' + data.get('sn')) data["date_last_checked"] = data.pop("time") if "tomcat_dirs" in data: data.pop("tomcat_dirs") if "tomcat" in data: tomcat_info = data.pop("tomcat") else: tomcat_info = list() if "vendor" in data: data["manufacturer"] = data.pop("vendor") # data['is_vm'] = False if "manage_address" in data: seg = get_segment_by_ip(data['manage_address']) if seg: get_or_create_ip_obj(seg.vlan.idc.idc_name, seg.vlan.vlan_num, data['manage_address']) if "product_name" in data: if re.search(r'OpenStack|KVM|Virtual', data['product_name'], re.I): data['is_vm'] = True else: data['is_vm'] = False if "uuid" in data: if "vm_uuid" in data: # {"vm_uuid": vm_uuid, "uuid": uuid} parent_host = Server.objects.get(uuid=data['uuid']) Server.objects.filter(uuid=data["vm_uuid"]).update(**{'parent_id': parent_host.id}) return JsonResponse({'code': 0, 'result': 'update server success'}) if data["uuid"] == "": if "hostname" in data: server_query = Server.objects.filter(hostname=data["hostname"]) if server_query.count() == 1: server_query.update(**data) server = Server.objects.get(hostname=data["hostname"]) else: return JsonResponse({'code': 1, 'errmsg': 'hostname:{} 不唯一!'.format(data["hostname"])}) else: return JsonResponse({'code': 1, 'errmsg': 'uuid和hostname都为空!'}) else: server_query = Server.objects.filter(uuid=data["uuid"]) if server_query.count() == 0: # server 不存在,则新建 server = Server.objects.create(**data) elif server_query.count() == 1: server_query.update(**data) server = Server.objects.get(uuid=data["uuid"]) else: # server uuid重复 return JsonResponse({'code': 1, 'errmsg': 'uuid:{} 不唯一!'.format(data["uuid"])}) else: # 无 uuid,直接退出 return JsonResponse({'code': 1, 'errmsg': 'uuid is null!'}) # 录入资源使用率 ServerResource.objects.create(s=server, cpu_used=data['cpu_used'], mem_used=data['mem_used']) tomcat_dir_prod = ['{}-{}'.format(str(a.tomcat_port), a.app_code.lower()) for a in server.app.all()] tomcat_dir_pre = ['{}-{}'.format(str(a.tomcat_port), a.app_code.lower()) for a in server.pre_app.all()] tomcat_dir_now = ['{}-{}'.format(str(t[0]), t[1].lower()) for t in tomcat_info] # 重新绑定该服务器 和 应用 app_ids, unknown_app = list(), list() for t in tomcat_info: tomcat_port, app_code, jdk = t[0], t[1], t[2] app = App.objects.filter(tomcat_port=tomcat_port, app_code=app_code) if app: if jdk != "" and jdk != app[0].jdk: app.update(jdk=jdk) app_ids.append(app[0].id) if len(t) > 3: xms = re.findall(r'xms(\d+\w)', t[3], re.I)[0] xmx = re.findall(r'xmx(\d+\w)', t[3], re.I)[0] AppResource.objects.update_or_create(s=server, app=app[0], defaults={'xms': xms, 'xmx': xmx}) else: unknown_app.append("{}-{}".format(tomcat_port, app_code)) server.app.set(App.objects.filter(id__in=app_ids)) for app in App.objects.filter(id__in=app_ids): server.pre_app.remove(app) if re.match(r'^jf-prod-|^jf-pre-', data['hostname'], re.I): # 之前存在,这次不存在。说明该应用已下线 yixiaxian = [_dir for _dir in tomcat_dir_prod if _dir not in tomcat_dir_now] # 之前不存在,这次存在。说明该应用刚上线 yufenpeishangxian, weifenpeishangxian = list(), list() for _dir in tomcat_dir_now: if _dir not in tomcat_dir_prod and _dir in tomcat_dir_pre: yufenpeishangxian.append(_dir) if _dir not in tomcat_dir_prod and _dir not in tomcat_dir_pre: weifenpeishangxian.append(_dir) if yixiaxian or yufenpeishangxian or weifenpeishangxian: msg = """应用变动告警:{}\n下线:{}\n预分配应用上线:{}\n未预分配应用上线:{}\n未知应用:{}""".format( server.hostname, " ".join(yixiaxian), " ".join(yufenpeishangxian), " ".join(weifenpeishangxian), " ".join(unknown_app) ) send_msg_to_admin(msg) if re.match(r'^(JF|wry)-prod-(?!beta)', data['hostname'], re.I): server.app_env = 'prod' elif re.match(r'^(JF|wry)-prod-beta-', data['hostname'], re.I): server.app_env = 'beta' elif re.match(r'^(JF|wry)-pre-', data['hostname'], re.I): server.app_env = 'pre' elif re.match(r'^mdc-|wry-stable-', data['hostname'], re.I): server.app_env = 'test' else: server.app_env = 'unknown' if re.search(r'-it\d?', data['hostname'], re.I): server.department = BizMgtDept.objects.get(dept_code='it') elif re.search(r'-yunwei\d?', data['hostname'], re.I): server.department = BizMgtDept.objects.get(dept_code='yunwei') elif re.search(r'-bigdata\d?', data['hostname'], re.I): server.department = BizMgtDept.objects.get(dept_code='bigdata') elif re.search(r'-zhifu\d?', data['hostname'], re.I): server.department = BizMgtDept.objects.get(dept_code='zhifu') elif re.search(r'-zichan\d?', data['hostname'], re.I): server.department = BizMgtDept.objects.get(dept_code='zichan') elif re.search(r'-zhongjianjian\d?', data['hostname'], re.I): server.department = BizMgtDept.objects.get(dept_code='zhongjianjian') elif re.search(r'-zijin\d?', data['hostname'], re.I): server.department = BizMgtDept.objects.get(dept_code='zijin') idc = None if nic_mac_ip_dict: # 取出nic表所有该 server 的记录,下面会将该server 不存在的nic 删除。 last_nic_ids = [n.id for n in Nic.objects.filter(server=server)] """ data = { ["mac1"]:[ {"eth0": [ip1, ip2]}, {"eth0.1": [ip3]} ], ["mac2"]:..., } """ print(type(nic_mac_ip_dict), nic_mac_ip_dict) ip_total = list() for (mac, nic_ips_list) in nic_mac_ip_dict.items(): print(type(nic_ips_list), nic_ips_list) for nic_ips in nic_ips_list: for (nic, ips) in nic_ips.items(): print(mac, nic, ips, type(ips)) if mac == "00-00-00-00-00-00-00-E0" and not ips: continue if nic == mac: # vmware host if Nic.objects.filter(nic_name=mac).exists(): # vmware host nic = Nic.objects.get(nic_name=mac) last_nic_ids.remove(nic.id) if nic.id in last_nic_ids else None else: nic_data = {'nic_name': nic, 'mac_address': mac, 'server': server, 'date_last_checked': datetime.datetime.now()} nic = Nic.objects.create(**nic_data) else: # 网卡处理,先解绑该网卡绑定的所有ip。然后再给该网卡绑定 本次扫描到的ip。 nic_query = Nic.objects.filter(nic_name=nic, mac_address=mac.lower().replace('-', ':')) if nic_query.exists(): # 网卡已存在,则更新其 nic_name和server nic_query.update(**{'server': server, 'date_last_checked': datetime.datetime.now()}) nic = nic_query[0] last_nic_ids.remove(nic.id) if nic.id in last_nic_ids else None else: # 根据mac查不到网卡,则创建网卡记录,并绑定server nic_data = {'nic_name': nic, 'mac_address': mac.lower().replace('-', ':'), 'server': server, 'date_last_checked': datetime.datetime.now()} nic = Nic.objects.create(**nic_data) # ip 处理 for ip in ips: ip_query = Ip.objects.filter(ip=ip) if ip_query: ip_total.append(ip) ip = ip_query[0] idc = ip.segment.vlan.idc # IP已存在,则更新last_detected 最后一次检测到的时间 ip_query.update(**{'last_detected': datetime.datetime.now()}) # 删除nic表中该ip的记录,下面会重新创建绑定 for n in Nic.objects.filter(ip=ip): n.ip.remove(ip) else: # IP 不存在,则新建 seg = get_segment_by_ip(ip) if seg is None: continue ip = get_or_create_ip_obj(seg.vlan.idc.idc_name, seg.vlan.vlan_num, ip, seg.netmask) idc = seg.vlan.idc if isinstance(ip, Ip): # 重新绑定nic和ip nic.ip.add(ip) if len(ip_total) == 1: if not server.login_address or server.login_address == '127.0.0.1:22': server.login_address = ip_total[0] elif re.match(r'^\d{,3}\.\d{,3}\.\d{,3}\.\d{,3}$', server.login_address): server.login_address = server.login_address + ':22' elif not re.match(r'\d{,3}\.\d{,3}\.\d{,3}\.\d{,3}:\d{,5}', server.login_address): send_msg_to_admin('Login_address error: {} {}!'.format(server.hostname, server.login_address)) # 在脚本取到网卡的前提下,上一次记录last_nic_ids,这次还未重新绑定的,表示它不再与server 有关联,需删除该条垃圾数据 if last_nic_ids and nic_mac_ip_dict: Nic.objects.filter(id__in=last_nic_ids).delete() if idc: # 根据ip推出主机所在的机房 server.idc = idc server.save() return JsonResponse({'code': 0, 'result': 'create server success'}) except Exception as e: print(traceback.print_exc()) return JsonResponse({'code': 1, 'errmsg': str(e)})