├── 3장 ├── 3.1 기본 │ ├── 3.1.1. Window │ │ ├── info.py │ │ └── socket_module_sample.py │ ├── 3.1.2. Linux │ │ ├── info.py │ │ ├── mymessages.log │ │ └── sample.py │ └── 3.1.3. 관리서버에서 파이썬 서버 접속 │ │ └── connection.py ├── 3.2 응용 │ ├── 3.2.1. vmstat _ 엑셀 │ │ ├── xlsx_test.py │ │ ├── xlsx_vmstat.py │ │ ├── xlsx_vmstat_header.py │ │ └── 엑셀 결과 파일 │ │ │ ├── test.xlsx │ │ │ ├── vmstat.xlsx │ │ │ └── vmstat_merge_header.xlsx │ └── 3.2.2. Linux_log │ │ ├── a. 리눅스 로그에서 찾고 싶은 로그 출력하기 │ │ ├── exec_mylog.py │ │ ├── exec_mylog_argu4.py │ │ ├── exec_mylog_argu5.py │ │ ├── mylog (1차) │ │ │ └── mylog.py │ │ ├── mylog (2차) │ │ │ └── mylog.py │ │ ├── mylog (3차) │ │ │ └── mylog.py │ │ ├── mylog (4차) │ │ │ └── mylog.py │ │ ├── mylog (5차) │ │ │ └── mylog.py │ │ ├── mylog - 기본 │ │ │ └── mylog.py │ │ └── 주의사항.txt │ │ └── b. 메시지 알람 │ │ ├── monitoring.py │ │ ├── monitoring_color_alert.py │ │ ├── monitoring_color_alert_logging.py │ │ ├── monitoring_comp.py │ │ ├── mylog.py │ │ ├── test_main.py │ │ └── test_main_add.py └── 예외 사항 처리 │ ├── a. connection.py (원본) │ └── connection.py │ ├── b. connection.py (1차 수정) │ └── connection.py │ └── b. connection.py (2차 수정) │ └── connection.py ├── 4장 ├── 4.1 RAID │ ├── exec_megacli.py │ ├── exec_megacli_adapter.py │ ├── exec_megacli_raid_infos.py │ ├── exec_megacli_raid_remove.py │ └── exec_megacli_raid_support_tar_gz.py ├── 4.2 IPMI │ ├── exec_ipmi.py │ ├── exec_ipmi_set.py │ ├── exec_ipmi_variable_cmd.py │ ├── fan_monitoring.py │ └── fan_re.py ├── 4.3 OID │ └── oid_easyrun.py ├── 4.4 History │ ├── history_all.py │ ├── history_highest.py │ ├── history_newest.py │ ├── history_time.py │ └── user_list.py ├── 4.5 CDP │ ├── auto_add_description_cdp.py │ ├── auto_add_description_mac.py │ └── auto_add_description_mac_사용시 주의점.txt ├── 4.6 Interface 별 증감량 │ ├── interface_data_variation.py │ ├── interface_data_variation_graph.py │ ├── interface_get_data.py │ └── interface_get_port_type.py └── 예외 사항 처리 │ ├── exec_megacli_raid_infos.py │ └── exec_megacli_raid_infos_advanced.py ├── 5장 ├── 5.1 배시와 파이썬 │ └── combination_cli_bash.py ├── 5.2 스케쥴러와 파이썬 │ ├── auto_add_description_mac.py │ ├── cdp_scheduler.py │ └── intStDesc.py ├── 5.3 크론과 파이썬 │ ├── cron_sys_chk.py │ ├── reqular_chk.sh.sh │ └── run_reqular_chk.sh ├── 5.4 CoPP 모니터링 │ ├── copp_check.py │ └── copp_logging.py ├── 5.5 EEM과 파이썬 │ ├── EEM 실행 명령어 입력.txt │ └── high_cpu.py ├── 5.6 EEM과 파이썬 응용 │ ├── a. FTP로 이미지 내려받기 _ 내려받은 이미지 파일로 부트 환경을 자동으로 재구성하기 │ │ ├── auto_provisioning.py │ │ └── ftp.py │ └── b. EEM을 통해 이미지 업그레이드 자동화 구현하기 │ │ ├── EEM으로 작성한 Auto-Provisioning.txt │ │ ├── auto_provisioning.py │ │ └── eem_config.py └── 예외 사항처리 │ ├── intStDesc.py │ └── intStDesc_advanced.py ├── 6장 (Hoon Jo) ├── 6.2.1 UCS 매니저 에뮬레이터 │ ├── ucs_image_downloader.py │ ├── ucsm_backup_n_import.py │ ├── ucsm_gui_launcher.py │ ├── ucsm_handle.py │ ├── ucsm_lable.py │ └── ucsm_mometa.py ├── 6.2.2 실제 UCS 매니저 │ ├── ucsm_techsupport.py │ └── ucsm_vkvm_launcher.py └── 6.2.3 실제 UCS 랙 서버 │ ├── general_vkvm_launcher.py │ ├── imc_backup_n_import.py │ ├── imc_backup_n_import_adv.py │ └── imc_techsupport.py ├── 7장 ├── 7.1 원격지 장비 │ ├── 7.1.1 시스템 종류 자동 인식 │ │ ├── ssh_check_type.py │ │ ├── ssh_connect.py │ │ └── ssh_exec_cmd.py │ ├── 7.1.2 원격지 명령 실행 │ │ ├── ssh_check_cpu_status.py │ │ ├── ssh_check_mgmt_route.py │ │ └── ssh_get_status_file.py │ └── 7.1.3 여러 원격지 │ │ └── ssh_get_status_file_ip_range.py ├── 7.2 스마트 로그 수집기 │ ├── 7.2.1 CPU 상태 감지 │ │ ├── cpu_usage_monitoring.py │ │ └── hana_cpu.py │ ├── 7.2.2 인터페이스 감지 │ │ ├── check_interface_pk.py │ │ ├── check_interface_pk_monitoring.py │ │ └── check_interface_ui.py │ └── 7.2.3 캡쳐 툴 │ │ ├── ethanalyzer.py │ │ ├── ethanalyzer_monitoring.py │ │ ├── tcpdump.py │ │ └── tcpdump_monitoring.py ├── 7.3 유용한 기능 │ ├── 7.3.1 메일 │ │ ├── send_config.py │ │ ├── smtp.py │ │ ├── ucsm_backup_n_import.py │ │ └── 주의사항.txt │ ├── 7.3.2 엑셀 차트 │ │ ├── exec_ipmi_any_platform.py │ │ ├── fan_monitoring_chart.py │ │ ├── fan_re_any_platform.py │ │ └── xlsx_chart.py │ ├── 7.3.3 vKVM │ │ └── vkvm_launch_cfg.py │ └── 7.3.4 구성파일 백업 │ │ ├── a. scp_backup (원본) │ │ └── scp_backup.py │ │ ├── b. scp_backup (SSH) │ │ ├── scp_backup.py │ │ ├── scp_backup_console.txt │ │ └── scp_backup_pts.txt │ │ ├── scp_diff.py │ │ └── scp_diff_analyze.py ├── 7.4 예외 │ ├── 7.4.1. 프로세스 모니터링 │ │ ├── cpu_load.py │ │ └── other_cpu.py │ └── 7.4.2 도움말 │ │ └── other_cpu_arg.py ├── cpu_load.py └── other_cpu.py └── 부록 ├── Install Package (PyQt, py2exe) ├── PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x32.exe └── py2exe-0.6.9.win32-py2.7.exe ├── bat 파일 ├── convert.bat └── setup.bat ├── cfg 파일 └── environment.cfg ├── exe package 파일 ├── blank.png ├── environment.cfg ├── green.png ├── grey.png ├── kvm │ ├── 32BitLibs │ │ ├── VMAPI_DLL.dll │ │ ├── avctKVMIO.dll │ │ ├── libVMAPI_DLL.so │ │ └── libavctKVMIO.so │ ├── VMAPI_DLL.dll │ ├── avctKVMIO.dll │ ├── launchkvm.bat │ ├── launchkvm.sh │ ├── libVMAPI_DLL.jnilib │ ├── libVMAPI_DLL.so │ ├── libavctKVMIO.jnilib │ ├── libavctKVMIO.so │ ├── libs │ │ ├── avctKVMIOLinux32.jar │ │ ├── avctKVMIOLinux64.jar │ │ ├── avctKVMIOMac64.jar │ │ ├── avctKVMIOWin32.jar │ │ ├── avctKVMIOWin64.jar │ │ ├── avctNuova.jar │ │ ├── avctVMLinux32.jar │ │ ├── avctVMLinux64.jar │ │ ├── avctVMMac64.jar │ │ ├── avctVMWin32.jar │ │ ├── avctVMWin64.jar │ │ └── lzvcnt.jar │ └── vkvm_launch_dialog.py ├── library.zip ├── orange.png ├── red.png └── vkvm_launch_dialog.exe ├── kvm lib (From ucsm 3.0.x version) ├── 32BitLibs │ ├── VMAPI_DLL.dll │ ├── avctKVMIO.dll │ ├── libVMAPI_DLL.so │ └── libavctKVMIO.so ├── VMAPI_DLL.dll ├── avctKVMIO.dll ├── launchkvm.bat ├── launchkvm.sh ├── libVMAPI_DLL.jnilib ├── libVMAPI_DLL.so ├── libavctKVMIO.jnilib ├── libavctKVMIO.so ├── libs │ ├── avctKVMIOLinux32.jar │ ├── avctKVMIOLinux64.jar │ ├── avctKVMIOMac64.jar │ ├── avctKVMIOWin32.jar │ ├── avctKVMIOWin64.jar │ ├── avctNuova.jar │ ├── avctVMLinux32.jar │ ├── avctVMLinux64.jar │ ├── avctVMMac64.jar │ ├── avctVMWin32.jar │ ├── avctVMWin64.jar │ └── lzvcnt.jar └── vkvm_launch_dialog.py ├── resource.py ├── run_dialog.py ├── run_dialog_language.py ├── setup.py ├── ssh_check_type.py ├── ssh_exec_cmd.py ├── ui 파일 └── vkvm_dialog.ui ├── vkvm_dialog.py ├── vkvm_launch_cfg.py ├── vkvm_launch_dialog.py └── 이미지 파일 (png format) ├── blank.png ├── green.png ├── grey.png ├── orange.png └── red.png /3장/3.1 기본/3.1.1. Window/info.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | # platform 모듈은 파이썬 코드를 실행하고 있는 운영체제의 환경 정보를 알려줍니다. 5 | # multiprocessing은 CPU의 개수를 알기 위해 사용합니다. 6 | import platform 7 | import multiprocessing 8 | 9 | # print는 화면에 글자를 출력하라는 함수입니다. 10 | print "운영체제: ", platform.system() 11 | print "운영체제의 상세정보: ", platform.platform() 12 | print "운영체제 버전: ", platform.version() 13 | print "프로세서: ", platform.processor() 14 | print "CPU 수: ", multiprocessing.cpu_count() 15 | -------------------------------------------------------------------------------- /3장/3.1 기본/3.1.1. Window/socket_module_sample.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import socket 5 | host= socket.gethostbyname_ex("www.google.com") 6 | 7 | #gethostbyname_ex로 전달받은 값 출력 8 | print "\n---------Host 정보를 출력---------" 9 | print host 10 | 11 | # for 문을 이용해 값을 한 줄씩 출력 12 | print "\n---------Host 정보를 한 줄씩 출력---------" 13 | for i in host : 14 | print i 15 | 16 | # 값에서 마지막 데이터가 IP 목록이므로 그중 첫 번째 주소를 IP로 선택 17 | (hostname, aliaslist, ipaddrlist) = host 18 | print "\n---------IP 주소 선택---------" 19 | print "ip :", ipaddrlist[0] # 배열의 첫 번째 값은 컴퓨터 세계에서는 0번째입니다! 20 | -------------------------------------------------------------------------------- /3장/3.1 기본/3.1.2. Linux/info.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | # platform 모듈은 파이썬 코드를 실행하고 있는 운영체제의 환경 정보를 알려줍니다. 5 | # multiprocessing는 CPU의 개수를 알기 위해 사용합니다. 6 | import platform 7 | import multiprocessing 8 | 9 | # print는 화면에 글자를 출력하라는 함수입니다. 10 | print "운영체제: ", platform.system() 11 | print "운영체제의 상세정보: ", platform.platform() 12 | print "운영체제 버전: ", platform.version() 13 | print "프로세서: ", platform.processor() 14 | print "CPU 수: ", multiprocessing.cpu_count() 15 | -------------------------------------------------------------------------------- /3장/3.1 기본/3.1.2. Linux/mymessages.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/3장/3.1 기본/3.1.2. Linux/mymessages.log -------------------------------------------------------------------------------- /3장/3.1 기본/3.1.2. Linux/sample.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | mymessages = open("mymessages.log") 5 | print mymessages.read() 6 | mymessages.close() 7 | -------------------------------------------------------------------------------- /3장/3.1 기본/3.1.3. 관리서버에서 파이썬 서버 접속/connection.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import os 5 | 6 | print "어떤 파이썬 서버에 연결하시겠습니까?" 7 | select = input("연결하고자 하는 파이썬 서버를 선택하세요(1,2) : ") 8 | 9 | if select ==1: 10 | os.system("ssh 10.10.10.100") 11 | elif select ==2: 12 | os.system("ssh 10.10.10.200") 13 | else: 14 | print "1 또는 2가 아닌 값입니다. 프로그램을 다시 시작해주세요." 15 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.1. vmstat _ 엑셀/xlsx_test.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from xlsxwriter import * 5 | 6 | # 엑셀 파일 생성 7 | workbook = Workbook('test.xlsx') 8 | 9 | # 엑셀 시트(sheet) 추가 10 | worksheet = workbook.add_worksheet() 11 | data = "1 2 3 4 5" 12 | 13 | columns = data.split() 14 | for col_idx, col in enumerate(columns) : 15 | worksheet.write(0, col_idx, col) 16 | 17 | workbook.close() 18 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.1. vmstat _ 엑셀/xlsx_vmstat.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from subprocess import * 5 | from xlsxwriter import * 6 | 7 | cmd = "vmstat 1 5 | awk '{now=strftime(\"%Y-%m-%d %T \"); print now $0}'" 8 | p = Popen(cmd, shell=True, stdout=PIPE) 9 | (ret, err) = p.communicate() 10 | 11 | workbook = Workbook('vmstat.xlsx') 12 | worksheet = workbook.add_worksheet() 13 | 14 | # 데이터를 줄 단위로 만듭니다. 15 | rows = ret.split("\n") 16 | 17 | for row_idx, row in enumerate(rows) : 18 | columns = row.split() 19 | for col_idx, col in enumerate(columns) : 20 | worksheet.write(row_idx, col_idx, col) 21 | 22 | workbook.close() 23 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.1. vmstat _ 엑셀/xlsx_vmstat_header.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from subprocess import * 5 | from xlsxwriter import * 6 | 7 | cmd = "vmstat 1 5 | awk '{now=strftime(\"%Y-%m-%d %T \"); print now $0}'" 8 | p = Popen(cmd, shell=True, stdout=PIPE) 9 | (ret, err) = p.communicate() 10 | 11 | workbook = Workbook('vmstat_merge_header.xlsx') 12 | worksheet = workbook.add_worksheet() 13 | rows = ret.split("\n") 14 | 15 | for row_idx, row in enumerate(rows) : 16 | if row_idx == 0 : # 첫 번째 헤더는 엑셀 파일에 쓰지 않음 17 | continue 18 | columns = row.split() 19 | for col_idx, col in enumerate(columns) : 20 | worksheet.write(row_idx, col_idx, col) 21 | 22 | # 첫번째 헤더를 병합한 셀에 직접 작성 23 | merge_format = workbook.add_format({ "bold" : 1, "align" : "center"}) # 포맷 설정 24 | worksheet.merge_range("A1:B1", "datetime", merge_format) # 하위 열 2개 25 | worksheet.merge_range("C1:D1", "procs", merge_format) # 하위 열 2개 26 | worksheet.merge_range("E1:H1", "memory", merge_format) # 하위 열 4개 27 | worksheet.merge_range("I1:J1", "swap", merge_format) # 하위 열 2개 28 | worksheet.merge_range("K1:L1", "io", merge_format) # 하위 열 2개 29 | worksheet.merge_range("M1:N1", "system", merge_format) # 하위 열 2개 30 | worksheet.merge_range("O1:S1", "cpu", merge_format) # 하위 열 5개 31 | 32 | workbook.close() 33 | print "vmstat_merge_header.xlsx 파일에 저장됐습니다." 34 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.1. vmstat _ 엑셀/엑셀 결과 파일/test.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/3장/3.2 응용/3.2.1. vmstat _ 엑셀/엑셀 결과 파일/test.xlsx -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.1. vmstat _ 엑셀/엑셀 결과 파일/vmstat.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/3장/3.2 응용/3.2.1. vmstat _ 엑셀/엑셀 결과 파일/vmstat.xlsx -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.1. vmstat _ 엑셀/엑셀 결과 파일/vmstat_merge_header.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/3장/3.2 응용/3.2.1. vmstat _ 엑셀/엑셀 결과 파일/vmstat_merge_header.xlsx -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/a. 리눅스 로그에서 찾고 싶은 로그 출력하기/exec_mylog.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import mylog 5 | mylog.printlog("/var/log/messages", "fail") 6 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/a. 리눅스 로그에서 찾고 싶은 로그 출력하기/exec_mylog_argu4.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import mylog 5 | mylog.printlog("/var/log/messages", "fail", 3, 5) 6 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/a. 리눅스 로그에서 찾고 싶은 로그 출력하기/exec_mylog_argu5.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import mylog 5 | import os 6 | 7 | logfile = "/var/log/messages" 8 | file_length = os.path.getsize(logfile) 9 | 10 | mylog.printlog("/var/log/messages", "fail", int(file_length/2), 3, 5) 11 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/a. 리눅스 로그에서 찾고 싶은 로그 출력하기/mylog (1차)/mylog.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | def printlog(logfile, search_word): 5 | f = open(logfile) # 파일 열기 6 | logdata = f.read() # 파일 읽기 7 | f.close() # 파일 닫기 8 | 9 | index = logdata.find(search_word) 10 | 11 | if index >= 0 : 12 | print "-" * 70 13 | print "Log file : ", logfile 14 | print "Find this word : ", search_word 15 | print index 16 | print "-" * 70 17 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/a. 리눅스 로그에서 찾고 싶은 로그 출력하기/mylog (2차)/mylog.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | def printlog(logfile, search_word): 5 | f = open(logfile) 6 | logdata = f.read() 7 | f.close() 8 | 9 | index = logdata.find(search_word) 10 | 11 | if index >= 0 : 12 | print "-" * 70 13 | print "Log file : ", logfile 14 | print "Find this word : ", search_word 15 | print "-" * 70 16 | 17 | # 함수를 호출할 때의 변수명( index)은 실제 함수의 변수명(start_index)과 달라도 됩니다. 18 | print get_log_data(logdata, index) 19 | print "-" * 70 20 | 21 | # 함수 추가(찾으려는 단어가 포함된 문장 한 줄을 뽑아내도록 추가할 부분) 22 | def get_log_data(logdata, start_index) : 23 | # 찾은 단어의 위치보다 앞에 있는 줄 바꿈 문자 찾기 24 | enter_index = max(0, logdata.rfind("\n", 0, start_index)) 25 | 26 | enter_index2 = logdata.find("\n", start_index, len(logdata)) 27 | return logdata[enter_index : enter_index2] 28 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/a. 리눅스 로그에서 찾고 싶은 로그 출력하기/mylog (3차)/mylog.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | # 인자를 4개로 수정 5 | def printlog(logfile, search_word, pre_rowcount, next_rowcount): 6 | f = open(logfile) 7 | logdata = f.read() 8 | f.close() 9 | 10 | index = logdata.find(search_word) 11 | 12 | if index >= 0 : 13 | print "-" * 70 14 | print "Log file : ", logfile 15 | print "Find this word : ", search_word 16 | print "-" * 70 17 | print get_log_data(logdata, index, pre_rowcount, next_rowcount) 18 | print "-" * 70 19 | 20 | def get_log_data(logdata, start_index, pre_rowcount, next_rowcount) : 21 | enter_index = max(0, logdata.rfind("\n", 0, start_index)) 22 | 23 | # 코드 수정 시작 24 | for i in range(0, pre_rowcount): 25 | enter_index = max(0, logdata.rfind("\n", 0, enter_index)) 26 | 27 | enter_index2 = logdata.find("\n", start_index, len(logdata)) 28 | for i in range(0, next_rowcount): 29 | next_end_index2 = logdata.find("\n", enter_index2 + 1, len(logdata)) 30 | if next_end_index2 == -1 : 31 | next_end_index2 = enter_index2 32 | break 33 | else : 34 | enter_index2 = next_end_index2 35 | 36 | # 코드 수정 완료 37 | return logdata[enter_index : enter_index2] 38 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/a. 리눅스 로그에서 찾고 싶은 로그 출력하기/mylog (4차)/mylog.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | def printlog(logfile, search_word, pre_rowcount, next_rowcount): 5 | f = open(logfile) 6 | logdata = f.read() 7 | f.close() 8 | 9 | index = logdata.find(search_word) 10 | 11 | if index >= 0 : 12 | print "-" * 70 13 | print "Log file : ", logfile 14 | print "Find this word : ", search_word 15 | print "-" * 70 16 | 17 | # 코드 수정 시작 (찾으려는 단어가 포함된 로그와 단어가 발견된 개수를 가져오도록 수정할 부분) 18 | (data, count) = get_log_data(logdata, search_word, index, pre_rowcount, next_rowcount) 19 | print data 20 | print "추출한 로그 개수 :", count 21 | # 코드 수정 완료 22 | 23 | def get_log_data(logdata, search_word, start_index, pre_rowcount, next_rowcount) : 24 | # 코드 수정 시작 25 | count = 0 26 | ret = "" 27 | 28 | while start_index >= 0 : 29 | # 코드 수정 완료 30 | enter_index = max(0, logdata.rfind("\n", 0, start_index)) 31 | for i in range(0, pre_rowcount): 32 | enter_index = max(0, logdata.rfind("\n", 0, enter_index)) 33 | 34 | enter_index2 = logdata.find("\n", start_index, len(logdata)) 35 | for i in range(0, next_rowcount): 36 | next_end_index2 = logdata.find("\n", enter_index2 + 1, len(logdata)) 37 | if next_end_index2 == -1 : 38 | next_end_index2 = enter_index2 39 | break 40 | else : 41 | enter_index2 = next_end_index2 42 | 43 | # 코드 수정 시작 44 | ret = ret + logdata[enter_index : enter_index2] # 로그 누적 45 | ret = ret + "\n" + ("-" * 70) # 구분하기 위해 엔터를 출력하고 '-'를 70번 출력 46 | 47 | # 한 번 출력한 로그의 마지막 줄 바꿈 위치(enter_index2) 뒤부터 찾고자 하는 단어를 찾습니다. 48 | # 따라서 index가 재조정되며 여러 번 반복한 다음에는 index가 -1이 되어 while 문을 종료합니다. 49 | start_index = logdata.find(search_word, enter_index2 + 1) 50 | count = count +1 # 로그를 찾은 횟수 갱신 51 | 52 | return (ret, count) 53 | # 코드 수정 완료 54 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/a. 리눅스 로그에서 찾고 싶은 로그 출력하기/mylog (5차)/mylog.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | # 인자를 5개로 수정 5 | def printlog(logfile, search_word, start_index, pre_rowcount, next_rowcount): 6 | f = open(logfile) 7 | logdata = f.read() 8 | f.close() 9 | 10 | # 코드 수정 시작 11 | index = logdata.find(search_word, start_index) 12 | # 코드 수정 완료 13 | 14 | if index >= 0 : 15 | print "-" * 70 16 | print "Log file : ", logfile 17 | print "Find this word : ", search_word 18 | print "-" * 70 19 | 20 | (data, count) = get_log_data(logdata, search_word, index, pre_rowcount, next_rowcount) 21 | print data 22 | print "추출한 로그 개수 :", count 23 | 24 | def get_log_data(logdata, search_word, start_index, pre_rowcount, next_rowcount) : 25 | count = 0 26 | ret = "" 27 | 28 | while start_index >= 0 : 29 | enter_index = max(0, logdata.rfind("\n", 0, start_index)) 30 | 31 | for i in range(0, pre_rowcount): 32 | enter_index = max(0, logdata.rfind("\n", 0, enter_index)) 33 | 34 | enter_index2 = logdata.find("\n", start_index, len(logdata)) 35 | for i in range(0, next_rowcount): 36 | next_end_index2 = logdata.find("\n", enter_index2 + 1, len(logdata)) 37 | if next_end_index2 == -1 : 38 | next_end_index2 = enter_index2 39 | break 40 | else : 41 | enter_index2 = next_end_index2 42 | 43 | ret = ret + logdata[enter_index : enter_index2] 44 | ret = ret + "\n" + ("-" * 70) 45 | 46 | start_index = logdata.find(search_word, enter_index2 + 1) 47 | count = count +1 48 | 49 | return (ret, count) -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/a. 리눅스 로그에서 찾고 싶은 로그 출력하기/mylog - 기본/mylog.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | def printlog(logfile, search_word): 5 | print "-" * 70 # '-'를 70개 그립니다. 6 | print "Log file : ", logfile 7 | print "Find this word : ", search_word 8 | print "-" * 70 9 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/a. 리눅스 로그에서 찾고 싶은 로그 출력하기/주의사항.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/3장/3.2 응용/3.2.2. Linux_log/a. 리눅스 로그에서 찾고 싶은 로그 출력하기/주의사항.txt -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/b. 메시지 알람/monitoring.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from mylog import get_log_data 5 | from time import sleep 6 | import os 7 | import sys 8 | import datetime 9 | 10 | # 로그 전체 내용을 보고 단어의 위치를 알아봅니다. 11 | def check(file_name, search_word) : 12 | if os.path.exists(file_name): 13 | print "모니터링 시작 :", file_name 14 | print "대상 : ", search_word 15 | print "-" * 70 16 | else : 17 | print "찾으려는 파일이 없습니다 :", file_name 18 | 19 | index = 0 20 | while os.path.exists(file_name) : 21 | # 파일에 찾을 단어('FATAL')가 있는지 확인 22 | fp = open(file_name) 23 | file_data =fp.read() 24 | index = file_data.find(search_word, index) 25 | fp.close() 26 | 27 | # 찾았다면 alert 함수로 메시지를 출력하고, 관련 로그의 앞으로 1줄, 뒤로 2줄을 출력 28 | # 찾지 못했다면 ...을 출력 29 | if index >= 0 : 30 | alert() 31 | (data, count) = get_log_data(file_data, search_word, index, 2, 2) 32 | print data 33 | else : 34 | sys.stdout.write("...") 35 | sys.stdout.flush() 36 | 37 | index = len(file_data) 38 | sleep(5) # 5초 동안 쉬기 39 | 40 | def alert() : 41 | print "\n", datetime.datetime.now(), "문제가 발생했습니다!!" 42 | 43 | # 메인 함수 44 | if __name__ == "__main__": 45 | check("/var/log/messages", "FATAL") 46 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/b. 메시지 알람/monitoring_color_alert.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from mylog import get_log_data 5 | from time import sleep 6 | import os 7 | import sys 8 | import datetime 9 | 10 | # 색상 코드 11 | errcolor_fatal= '\033[31m' 12 | errcolor_none = '\033[0m' 13 | errcolor_except = '\x1b[36m' 14 | 15 | def check(file_name, search_word) : 16 | if os.path.exists(file_name): 17 | print "모니터링 시작 :", file_name 18 | print "대상 : ", search_word 19 | print "-" * 70 20 | else : 21 | print "찾으려는 파일이 없습니다 :", file_name 22 | 23 | index = 0 24 | while os.path.exists(file_name) : 25 | fp = open(file_name) 26 | file_data =fp.read() 27 | index = file_data.find(search_word, index) 28 | fp.close() 29 | 30 | if index >= 0 : 31 | alert(search_word) # 코드 수정 32 | (data, count) = get_log_data(file_data, search_word, index, 2, 2) 33 | print data 34 | else : 35 | sys.stdout.write("...") 36 | sys.stdout.flush() 37 | 38 | index = len(file_data) 39 | sleep(5) 40 | 41 | # search_word 인자 추가 및 색상 적용(검색한 단어의 종류에 따라 다른 글자색을 적용하도록 수정) 42 | def alert(search_word) : 43 | now = datetime.datetime.now() 44 | if search_word == "FATAL" : 45 | print errcolor_fatal + "\n", now, "심각한 문제가 발생했습니다!!" +errcolor_none 46 | elif search_word == "except" : 47 | print errcolor_except + "\n", now, "문제가 발견됐습니다!!" +errcolor_none 48 | 49 | if __name__ == "__main__": 50 | check("/var/log/messages", "FATAL") 51 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/b. 메시지 알람/monitoring_color_alert_logging.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from mylog import get_log_data 5 | from time import sleep 6 | import os 7 | import sys 8 | import datetime 9 | 10 | errcolor_fatal= '\033[31m' 11 | errcolor_none = '\033[0m' 12 | errcolor_except = '\x1b[36m' 13 | 14 | # 로그를 저장하기 위한 파일명(out_file_name) 인자 추가 수정 15 | def check(file_name, search_word, out_file_name) : 16 | if os.path.exists(file_name): 17 | print "모니터링 시작 :", file_name 18 | print "대상 : ", search_word 19 | print "-" * 70 20 | else : 21 | print "찾으려는 파일이 없습니다 :", file_name 22 | 23 | index = 0 24 | while os.path.exists(file_name) : 25 | fp = open(file_name) 26 | file_data =fp.read() 27 | index = file_data.find(search_word, index) 28 | fp.close() 29 | 30 | if index >= 0 : 31 | alert(search_word) 32 | (data, count) = get_log_data(file_data, search_word, index, 2, 2) 33 | 34 | # 코드 수정 시작 35 | out_file = open(out_file_name, "a") 36 | out_file.write("\n" + ("*" * 70) ) 37 | out_file.write("\n문제(" + search_word +")가 모니터링된 시각 : ") 38 | out_file.write(str(datetime.datetime.now())) 39 | out_file.write("\n" +("-" * 70) + "\n") 40 | out_file.write(data) 41 | print "로그가 기록된 파일을 확인하세요 :", out_file_name 42 | out_file.close() 43 | # 코드 수정 완료 44 | else : 45 | sys.stdout.write("...") 46 | sys.stdout.flush() 47 | 48 | index = len(file_data) 49 | sleep(5) 50 | 51 | def alert(search_word) : 52 | now = datetime.datetime.now() 53 | if search_word == "FATAL" : 54 | print errcolor_fatal + "\n", now, "심각한 문제가 발생했습니다!!" +errcolor_none 55 | elif search_word == "except" : 56 | print errcolor_except + "\n", now, "문제가 발견됐습니다!!" +errcolor_none 57 | 58 | if __name__ == "__main__": 59 | check("/var/log/messages", "FATAL", "/var/log/customized_warn") 60 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/b. 메시지 알람/monitoring_comp.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from mylog import get_log_data 5 | from time import sleep 6 | import os 7 | import sys 8 | import datetime 9 | 10 | # 로그 전체 내용을 보고 단어의 위치를 알아봅니다. 11 | def check(file_name, search_word) : 12 | if os.path.exists(file_name): 13 | print "모니터링 시작 :", file_name 14 | print "대상 : ", search_word 15 | print "-" * 70 16 | else : 17 | print "찾으려는 파일이 없습니다 :", file_name 18 | 19 | index = 0 20 | while os.path.exists(file_name) : 21 | # 파일에 찾을 단어('FATAL')가 있는지 확인 22 | fp = open(file_name) 23 | file_data =fp.read() 24 | index = file_data.find(search_word, index) 25 | fp.close() 26 | 27 | # 찾았다면 alert 함수로 메시지를 출력하고, 관련 로그의 앞으로 1줄, 뒤로 2줄을 출력 28 | # 찾지 못했다면 ...을 출력 29 | if index >= 0 : 30 | alert() 31 | (data, count) = get_log_data(file_data, search_word, index, 2, 2) 32 | print data 33 | else : 34 | sys.stdout.write("...") 35 | sys.stdout.flush() 36 | 37 | index = len(file_data) 38 | sleep(5) # 5초 동안 쉬기 39 | 40 | def alert() : 41 | print "\n", datetime.datetime.now(), "문제가 발생했습니다!!" 42 | 43 | # 메인 함수 44 | if __name__ == "__main__": 45 | print "==코드가 직접 실행됩니다.==" 46 | print "/var/log/messages에서 FATAL이라는 단어를 검색합니다." 47 | check("/var/log/messages", "FATAL") 48 | else: 49 | print "임포트에 성공했습니다." 50 | print "check 함수를 사용하려면 다음과 같은 문법으로 실행하세요." 51 | print "<문 법> : check(file_name, search_word)" 52 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/b. 메시지 알람/mylog.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | # 인자를 5개로 수정 5 | def printlog(logfile, search_word, start_index, pre_rowcount, next_rowcount): 6 | f = open(logfile) 7 | logdata = f.read() 8 | f.close() 9 | 10 | # 코드 수정 시작 11 | index = logdata.find(search_word, start_index) 12 | # 코드 수정 완료 13 | 14 | if index >= 0 : 15 | print "-" * 70 16 | print "Log file : ", logfile 17 | print "Find this word : ", search_word 18 | print "-" * 70 19 | 20 | (data, count) = get_log_data(logdata, search_word, index, pre_rowcount, next_rowcount) 21 | print data 22 | print "추출한 로그 개수 :", count 23 | 24 | def get_log_data(logdata, search_word, start_index, pre_rowcount, next_rowcount) : 25 | count = 0 26 | ret = "" 27 | 28 | while start_index >= 0 : 29 | enter_index = max(0, logdata.rfind("\n", 0, start_index)) 30 | 31 | for i in range(0, pre_rowcount): 32 | enter_index = max(0, logdata.rfind("\n", 0, enter_index)) 33 | 34 | enter_index2 = logdata.find("\n", start_index, len(logdata)) 35 | for i in range(0, next_rowcount): 36 | next_end_index2 = logdata.find("\n", enter_index2 + 1, len(logdata)) 37 | if next_end_index2 == -1 : 38 | next_end_index2 = enter_index2 39 | break 40 | else : 41 | enter_index2 = next_end_index2 42 | 43 | ret = ret + logdata[enter_index : enter_index2] 44 | ret = ret + "\n" + ("-" * 70) 45 | 46 | start_index = logdata.find(search_word, enter_index2 + 1) 47 | count = count +1 48 | 49 | return (ret, count) -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/b. 메시지 알람/test_main.py: -------------------------------------------------------------------------------- 1 | print __name__ 2 | -------------------------------------------------------------------------------- /3장/3.2 응용/3.2.2. Linux_log/b. 메시지 알람/test_main_add.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | print "무조건 출력합니다" 5 | 6 | if __name__ == "__main__": 7 | print "직접 실행할 때만 출력합니다" 8 | else: 9 | print "임포트 할 때만 출력합니다." 10 | -------------------------------------------------------------------------------- /3장/예외 사항 처리/a. connection.py (원본)/connection.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import os 5 | 6 | print "어떤 파이썬 서버에 연결하시겠습니까?" 7 | select = input("연결하고자 하는 파이썬 서버를 선택하세요(1,2) : ") 8 | 9 | if select ==1: 10 | os.system("ssh 10.10.10.100") 11 | elif select ==2: 12 | os.system("ssh 10.10.10.200") 13 | else: 14 | print "1 또는 2가 아닌 값입니다. 프로그램을 다시 시작해주세요." 15 | -------------------------------------------------------------------------------- /3장/예외 사항 처리/b. connection.py (1차 수정)/connection.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import os 5 | 6 | print "어떤 파이썬 서버에 연결하시겠습니까?" 7 | 8 | while True: 9 | select = raw_input("연결하고자 하는 파이썬 서버를 선택하세요(1,2) : ") 10 | 11 | if select =="1": 12 | os.system("ssh 10.10.10.100") 13 | break 14 | elif select =="2": 15 | os.system("ssh 10.10.10.200") 16 | break 17 | else: 18 | print "1 또는 2가 아닌 값입니다. 정확한 값을 선택해주세요.\n" 19 | continue 20 | -------------------------------------------------------------------------------- /3장/예외 사항 처리/b. connection.py (2차 수정)/connection.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import os 5 | 6 | print "어떤 파이썬 서버에 연결하시겠습니까?" 7 | 8 | while True: 9 | print "1. 파이썬 서버 1호기" 10 | print "2. 파이썬 서버 2호기" 11 | select = raw_input("숫자를 입력하세요 (종료는 q) : ") 12 | if select =="1": 13 | os.system("ssh 10.10.10.100") 14 | break 15 | elif select =="2": 16 | os.system("ssh 10.10.10.200") 17 | break 18 | elif select =="q": 19 | break 20 | else: 21 | print "1 또는 2가 아닌 값입니다. 정확한 값을 선택해주세요.\n" 22 | continue 23 | -------------------------------------------------------------------------------- /4장/4.1 RAID/exec_megacli.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from subprocess import os 5 | from subprocess import Popen 6 | 7 | def megacli(args): 8 | os.chdir('/opt/lsi/MegaCLI') 9 | cmd = './MegaCli ' + args 10 | Popen(cmd, shell=True) 11 | 12 | if __name__ == "__main__": 13 | megacli('-AdpGetTime -aAll') 14 | -------------------------------------------------------------------------------- /4장/4.1 RAID/exec_megacli_adapter.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from subprocess import os 5 | from subprocess import Popen 6 | 7 | def megacli(args): 8 | os.chdir('/opt/lsi/MegaCLI') 9 | cmd = './MegaCli ' + args 10 | Popen(cmd, shell=True) 11 | 12 | if __name__ == "__main__": 13 | megacli('-AdpAllInfo -aAll') # 옵션만 바꿔 실행 14 | -------------------------------------------------------------------------------- /4장/4.1 RAID/exec_megacli_raid_infos.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from subprocess import os 5 | from subprocess import Popen 6 | 7 | def megacli(args): 8 | os.chdir('/opt/lsi/MegaCLI') 9 | cmd = './MegaCli ' + args 10 | Popen(cmd, shell=True) 11 | 12 | def check_raid_info() : 13 | print "a. Check the Raid Adapter Time." 14 | print "b. Check the Raid Adapter Information." 15 | print "c. Save the Information of Adapter as a file." 16 | print "d. Save the Status of Battery as a file." 17 | 18 | # 문자를 입력받을 때는 다음과 같이 raw_input을 사용합니다. 19 | abc = raw_input("Select to execute[a-d] : ") 20 | if abc =='a' : 21 | megacli("-AdpGetTime -aAll") 22 | elif abc =='b' : 23 | megacli("-AdpAllInfo -aAll") 24 | elif abc =='c': 25 | megacli("-AdpAllInfo -aAll >> /tmp/Adapall.txt") 26 | print "Success to save : /tmp/Adpall.txt" 27 | elif abc =='d' : 28 | megacli("-AdpBbuCmd -GetBbuStatus -aAll >> /tmp/bbu.txt") 29 | print "Success to save : /tmp/bbu.txt" 30 | 31 | def check_raid_disk() : 32 | print "a. Save the Physical Disk Status as a file." 33 | print "b. Save the Cache Policy as a file." 34 | 35 | # 숫자를 입력받을 때는 다음과 같이 input을 사용합니다. 36 | abc = raw_input("Select to execute[a-b] : ") 37 | if abc =='a' : 38 | megacli("-PDList aALL >> /tmp/pd.txt") 39 | print "Success to save : /tmp/pd.txt" 40 | elif abc =='b' : 41 | megacli("-LDGetProp -Cache -LALL -aAll >> /tmp/VD.txt") 42 | print "Success to save : /tmp/VD.txt" 43 | 44 | def collect_raid_log() : 45 | print "a. Save the adapter event log as a file." 46 | print "b. Save the firmware event log as a file." 47 | abc = raw_input("Select to execute[a-b] : ") 48 | if abc =='a' : 49 | megacli("-AdpEventLog -GetEvents -f /tmp/eventlog.txt -aAll >> /dev/null") 50 | print "Success to save : /tmp/eventlog.txt" 51 | elif abc =='b' : 52 | megacli("-fwtermlog -dsply -aAll > /tmp/lsi-fwterm.log") 53 | print "Success to save : /tmp/lsi-fwterm.log" 54 | 55 | if __name__ == "__main__": 56 | print "1. Check & Collect the General Raid Adapter Information." 57 | print "2. Collect the Raid Disk Information." 58 | print "3. Collect the Raid Event Log." 59 | 60 | inputValue = input("Select to execute[1-3] : ") 61 | if inputValue == 1: 62 | check_raid_info() 63 | elif inputValue == 2: 64 | check_raid_disk() 65 | elif inputValue == 3: 66 | collect_raid_log() 67 | -------------------------------------------------------------------------------- /4장/4.1 RAID/exec_megacli_raid_remove.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from subprocess import Popen 5 | from subprocess import os 6 | from subprocess import PIPE 7 | 8 | def megacli(args): 9 | os.chdir('/opt/lsi/MegaCLI') 10 | cmd = './MegaCli ' + args 11 | p = Popen(cmd, shell=True, stdout=PIPE) 12 | (ret, err) = p.communicate() 13 | return ret 14 | 15 | def get_slot_list(raid_info) : 16 | rows = status.split('\n') 17 | slot_list = {} 18 | encl_id = '' 19 | slot_num = '' 20 | media_err = 0 21 | other_err = 0 22 | firmware_state = '' 23 | for row in rows : 24 | cols = row.split(':') 25 | if cols[0].find('Enclosure Device ID') >= 0 : 26 | encl_id = cols[1].strip() 27 | elif cols[0].find('Slot Number') >= 0 : 28 | # 화면에 표시할 때, 슬롯 번호를 기준으로 숫자 단위 정렬. 따라서 숫자로 변환 29 | slot_num = int(cols[1].strip()) 30 | elif cols[0].find('Media Error Count') >= 0 : 31 | media_err = cols[1].strip() 32 | elif cols[0].find('Other Error Count') >= 0 : 33 | other_err = cols[1].strip() 34 | elif cols[0].find('Firmware state') >= 0 : 35 | firmware_state = cols[1].strip() 36 | slot_list[slot_num] = (encl_id, media_err, other_err, firmware_state) 37 | else : 38 | continue 39 | return slot_list 40 | 41 | def set_off_line(device_id, slot_num) : 42 | ret = "" 43 | ret = ret + megacli('-PDOffline -PhysDrv [%s:%d] -aAll' % (device_id, slot_num)) 44 | ret = ret + "\n" + megacli('-PDMarkMissing -PhysDrv [%s:%d] -aAll' % (device_id, slot_num)) 45 | ret = ret + "\n" + megacli(' -PDGetMissing -aALL') 46 | return ret 47 | 48 | def set_ready_remove(device_id, slot_num) : 49 | return megacli('-PDPrpRmv -PhysDrv [%s:%d] -aAll' % (device_id, slot_num)) 50 | 51 | if __name__ == "__main__": 52 | cmd_args = '-PDList -aAll | egrep ' 53 | cmd_args = cmd_args + '"Enclosure Device ID:|Slot Number:|In quiry data:|Error Count:|state"' 54 | status = megacli(cmd_args) 55 | 56 | # 슬롯 정보를 화면에 출력 57 | slot_list = get_slot_list(status) 58 | print "="*50 59 | print "Slot\tDvice\tMedia\tOther\tFirmware" 60 | print "Num\tID\tError\tError\tState" 61 | print "="*50 62 | slot_num_list = slot_list.keys() # 딕셔너리에서 키가 되는 슬롯 번호 리스트를 가져옵니다. 63 | slot_num_list.sort() # 슬롯 번호 리스트를 정렬합니다. 64 | 65 | for slot_num in slot_num_list : # 정렬된 슬롯 번호 순서대로 관련 데이터를 화면에 출력 66 | (encl_id, media_err, other_err, firmware_state) = slot_list[slot_num] 67 | print "%s\t%s\t%s\t%s\t%s" % (slot_num, encl_id, media_err, other_err, firmware_state) 68 | 69 | # 사용자에게 슬롯 번호를 입력받음 70 | slot_num = input("Select a slot to remove : ") 71 | 72 | # 선택한 레이드 정보 하나를 가져옴 73 | # 가져온 레이드 정보는 (드라이브 ID, 미디어 에러, 기타 에러, 펌웨어 상태) 튜플 형태임 74 | (dv_id, media_err, other_err, firmware_state) = slot_list[slot_num] 75 | print set_off_line(dv_id, slot_num) 76 | print set_ready_remove(dv_id, slot_num) 77 | print megacli(cmd_args) 78 | -------------------------------------------------------------------------------- /4장/4.1 RAID/exec_megacli_raid_support_tar_gz.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import tarfile 5 | import os 6 | import shutil 7 | from exec_megacli_raid_infos import * 8 | 9 | def make_tar(tar_name, files): 10 | tar = tarfile.open(tar_name, "w:gz") 11 | for name in files: 12 | tar.add(name) 13 | tar.close() 14 | 15 | def collect_all_log() : 16 | print "Collecting logs .. " 17 | import time 18 | time.sleep(2) 19 | 20 | dirname = '/tmp/megacli' 21 | if not os.path.isdir(dirname): 22 | os.mkdir(dirname) 23 | 24 | megacli("-AdpGetTime -aAll >> %s/AdapTime.txt" % dirname ) 25 | megacli("-AdpAllInfo -aAll >> %s/Adapall.txt" % dirname ) 26 | megacli("-AdpBbuCmd -GetBbuStatus -aAll >> %s/bbu.txt" % dirname ) 27 | megacli("-PDList aALL >> %s/pd.txt" % dirname ) 28 | megacli("-LDGetProp -Cache -LALL -aAll >> %s/VD.txt" % dirname ) 29 | megacli("-AdpEventLog -GetEvents -f %s/eventlog.txt -aAll >> /dev/null" % dirname ) 30 | megacli("-fwtermlog -dsply -aAll > %s/lsi-fwterm.log" % dirname ) 31 | 32 | log_files = [dirname + "/AdapTime.txt", 33 | dirname + "/Adapall.txt", 34 | dirname + "/bbu.txt", 35 | dirname + "/pd.txt", 36 | dirname + "/VD.txt", 37 | dirname + "/eventlog.txt", 38 | dirname + "/lsi-fwterm.log" ] 39 | time.sleep(5) 40 | make_tar("/tmp/MegaRaid.tar.gz",log_files ) 41 | shutil.rmtree(dirname) 42 | print "Success to save : /tmp/MegaRaid.tar.gz" 43 | 44 | if __name__ == "__main__": 45 | print "1. Check & Collect the General Raid Adapter Information." 46 | print "2. Collect the Raid Disk Information." 47 | print "3. Collect the Raid Event Log." 48 | print "4. Save the All Raid Logs as a tar.gz file." 49 | 50 | inputValue = input("Select to execute[1-4] : ") 51 | if inputValue == 1: 52 | check_raid_info() 53 | elif inputValue == 2: 54 | check_raid_disk() 55 | elif inputValue == 3: 56 | collect_raid_log() 57 | elif inputValue == 4: 58 | collect_all_log() -------------------------------------------------------------------------------- /4장/4.2 IPMI/exec_ipmi.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from subprocess import Popen 5 | from subprocess import PIPE 6 | 7 | def get_ipmi(args): 8 | cmd = 'ipmitool ' + args 9 | p = Popen(cmd, shell=True, stdout=PIPE) 10 | (ret, err) = p.communicate() 11 | return ret 12 | 13 | def get_server_input() : 14 | ip = raw_input ("서버 관리 모듈 IP를 입력하세요 :") 15 | id = raw_input ("관리자 ID를 입력하세요 :") 16 | pw = raw_input ("암호를 입력하세요 :") 17 | args = '-I lanplus -H ' + ip + ' -U ' + id + ' -P ' +pw 18 | return args 19 | 20 | if __name__ == "__main__": 21 | args = get_server_input() 22 | 23 | print get_ipmi( args + ' fru print | grep "Product Name"') 24 | print get_ipmi( args + ' fru print | grep "Chassis Serial"') 25 | -------------------------------------------------------------------------------- /4장/4.2 IPMI/exec_ipmi_set.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from exec_ipmi import * 5 | 6 | def ipmitool(args): 7 | ret = get_ipmi(args) 8 | rows = ret.split('\n') 9 | item_set =set(rows) # 여기서 중복되는 내용이 제거됩니다. 10 | item_set.remove('') # 내용이 없으면 삭제함 11 | for item in item_set: 12 | print item 13 | 14 | if __name__ == "__main__": 15 | args = get_server_input() 16 | 17 | ipmitool( args + ' fru print | grep "Product Name"') 18 | ipmitool( args + ' fru print | grep "Chassis Serial"') 19 | -------------------------------------------------------------------------------- /4장/4.2 IPMI/exec_ipmi_variable_cmd.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from exec_ipmi_set import ipmitool 5 | from exec_ipmi_set import get_server_input 6 | import time 7 | 8 | def check_hw(args) : 9 | ipmitool( args + ' fru print | grep "Product Name"') 10 | ipmitool( args + ' fru print | grep "Chassis Serial"') 11 | 12 | def check_sensor(args) : 13 | print "a. 전체 내용 조회" 14 | print "b. 팬과 온도 상태 조회" 15 | abc = raw_input("무엇을 실행하시겠습니까? : ") 16 | 17 | if abc =='a' : 18 | ipmitool( args + ' sdr list') 19 | ipmitool( args + ' sensor') 20 | elif abc =='b' : # IPMI 명령 실행 후에 10초씩 여유를 둡니다. 21 | ipmitool( args + ' sensor | grep FAN"[1-9]"_SPEED') 22 | time.sleep(10) 23 | ipmitool( args + ' sensor | grep FAN"[1-6]"_TACH"[1-2]"') 24 | time.sleep(10) 25 | ipmitool( args + ' sensor | grep PSU"[1-9]"_TEMP') 26 | time.sleep(10) 27 | ipmitool( args + ' sensor | grep FP_TEMP_SENSOR') 28 | time.sleep(10) 29 | 30 | def check_event_log(args) : 31 | print "a. 사용량 조회" 32 | print "b. 전체 내용 조회" 33 | abc = raw_input("무엇을 실행하시겠습니까? : ") 34 | 35 | if abc =='a' : 36 | ipmitool( args + ' sel info | grep "Percent Used"') 37 | elif abc =='b' : 38 | ipmitool( args + ' sel list > /tmp/sellist.txt') 39 | print '/tmp/sellist.txt에 저장하였습니다.' 40 | 41 | def check_power(args) : 42 | print "a. 파워 상태 조회" 43 | print "b. 파워 켜기" 44 | print "c. 파워 끄기" 45 | print "d. 파워 사이클 실행" 46 | abc = raw_input("무엇을 실행하시겠습니까? : ") 47 | 48 | if abc =='a' : 49 | ipmitool( args + ' power status') 50 | elif abc =='b' : 51 | ipmitool( args + ' power on') 52 | elif abc =='c' : 53 | ipmitool( args + ' power off') 54 | elif abc =='d' : 55 | ipmitool( args + ' power cycle') 56 | 57 | if __name__ == "__main__": 58 | args = get_server_input() 59 | 60 | print "1. 시스템 하드웨어 정보" 61 | print "2. 시스템 센서 정보" 62 | print "3. 시스템 이벤트 로그(SEL)" 63 | print "4. 시스템 파워" 64 | inputValue = input("어떤 정보를 조회하시겠습니까? : ") 65 | 66 | # if와 elif를 사용하지 않고 if만으로도 동일하게 구현 가능합니다. 67 | # 하지만 성능면으로는 elif를 쓰는 것이 좋습니다. 68 | if inputValue == 1: 69 | check_hw(args) 70 | if inputValue == 2: 71 | check_sensor(args) 72 | if inputValue == 3: 73 | check_event_log(args) 74 | if inputValue == 4: 75 | check_power(args) 76 | -------------------------------------------------------------------------------- /4장/4.2 IPMI/fan_monitoring.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from fan_re import * 5 | import time 6 | import os 7 | import shutil 8 | 9 | def write_header(file_path, key_list) : 10 | fp = open(file_path, "w") 11 | text_data = "Count" # 1번째 헤더는 횟수이며 2번째부터는 키 값 12 | for key in key_list : 13 | text_data = "%s\t%s" % (text_data, key) # 헤더를 탭(\t)으로 구분해 작성 14 | 15 | text_data = text_data + "\n" 16 | fp.write(text_data) 17 | fp.close() 18 | 19 | def append_value(file_path, count, value_list) : 20 | fp = open(file_path, "a") 21 | text_data = str(count) # 1번째 값은 횟수이며 2번째부터는 상태 값 22 | for value in value_list : 23 | text_data = "%s\t%s" % (text_data, value) # 값을 탭(\t)으로 구분해 작성 24 | 25 | text_data = text_data + "\n" 26 | fp.write(text_data) 27 | fp.close() 28 | 29 | if __name__ == "__main__": 30 | args = get_server_input() 31 | (count, sleep_time) = get_input() 32 | 33 | file_dir = "./fan" 34 | if os.path.isdir(file_dir) : 35 | shutil.rmtree(file_dir) 36 | if not os.path.isdir(file_dir) : 37 | os.mkdir(file_dir) 38 | 39 | c = 1 40 | file_path = "" 41 | file_separator = 10 42 | while c <= count or count == 0: 43 | # 팬 정보(상태 키, 상태 값)에 대한 리스트 추출 44 | (key_list, value_list) = check_fan(args) 45 | 46 | # 파일 분할 기준값에 따라 파일 이름을 계산하며 파일 기본 이름은 현재 시각을 포함 47 | if c % file_separator == 1 : 48 | now = time.localtime() 49 | file_path = "%s/%04d%02d%02d_%02d%02d%02d_FanLog.txt" % ( 50 | file_dir, now.tm_year, now.tm_mon, now.tm_mday, 51 | now.tm_hour, now.tm_min, now.tm_sec) 52 | 53 | print "팬과 온도 상태 기록 파일 생성 : %s" % file_path 54 | print "[%d회] 팬과 온도 상태 기록 중..." % c 55 | 56 | # 파일 분할 기준값에 따라 새로운 파일에 작성하게 되면 헤더를 씀 57 | if c % file_separator == 1 : 58 | write_header(file_path, key_list) 59 | 60 | # 상태 값을 헤더 아래에 작성 61 | append_value(file_path, c, value_list) 62 | 63 | time.sleep(sleep_time) 64 | c = c + 1 65 | -------------------------------------------------------------------------------- /4장/4.2 IPMI/fan_re.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from exec_ipmi import get_ipmi 5 | from exec_ipmi import get_server_input 6 | import time 7 | import re 8 | 9 | def check_fan(args) : 10 | ipmi_result = get_ipmi('%s sensor' % args) 11 | 12 | # 찾으려는 데이터는 "FAN숫자_SPEED"로 시작하는 문자열입니다. 13 | # 찾은 데이터를 리스트로 가져옵니다. 14 | (key_list, value_list) = get_data_list("FAN[1-9]_SPEED.*", ipmi_result) 15 | 16 | # 찾으려는 데이터는 "FAN숫자_TACH"로 시작하는 문자열입니다. 17 | (key_list2, value_list2) = get_data_list("FAN[1-9]_TACH.*",ipmi_result) 18 | 19 | # 찾으려는 데이터는 "PSU숫자_TEMP"로 시작하는 문자열입니다. 20 | (key_list3, value_list3) = get_data_list("PSU[1-9]_TEMP.*",ipmi_result) 21 | 22 | # 찾으려는 데이터는 "FP_TEMP_SENSOR"로 시작하는 문자열입니다. 23 | (key_list4, value_list4) = get_data_list("FP_TEMP_SENSOR.*",ipmi_result) 24 | 25 | # 찾은 데이터를 리스트로 가져와서 key_list와 합칩니다. 26 | key_list = key_list + key_list2 + key_list3 + key_list4 27 | value_list = value_list + value_list2 + value_list3 + value_list4 28 | 29 | return (key_list, value_list) 30 | 31 | def get_data_list(pattern_str, source_data) : 32 | str_list = re.findall(pattern_str, source_data) 33 | key_list = [] 34 | value_list = [] 35 | for str in str_list : 36 | array = str.split("|") # ipmitool에서 반환한 데이터는"|"로 데이터 열이 구분돼 있습니다. 37 | 38 | if len(array) < 2 : # 0번째 열이 상태 키, 1번째 열이 상태에 대한 값입니다. 39 | return "" 40 | 41 | key = array[0].strip() 42 | value = array[1].strip() 43 | key_list.append(key) 44 | value_list.append(value) 45 | 46 | return (key_list, value_list) # (상태 키 리스트, 상태 값 리스트)의 튜플로 반환합니다. 47 | 48 | def get_input() : 49 | count = input("몇 회 체크하시겠습니까? [무한대 체크는 0]:") 50 | if count < 0 : 51 | count = 0 52 | 53 | sleep_time = 10 54 | sleep_time = input("몇 초 단위로 체크하시겠습니까? [최소 30]:") 55 | 56 | if sleep_time < 30 : 57 | sleep_time = 30 58 | 59 | return (count, sleep_time) 60 | 61 | if __name__ == "__main__": 62 | args = get_server_input() 63 | (count, sleep_time) = get_input() 64 | 65 | c = 1 66 | while c <= count or count == 0: 67 | print "[%d회] 팬과 온도 상태 조회 중 ..." % c 68 | # 팬 정보 (상태 키, 상태 값)에 대한 리스트 추출 69 | (key_list, value_list) = check_fan(args) 70 | 71 | # 첫 회에만 키 리스트를 출력하고, 그다음에는 상태 값에 관한 리스트를 출력 72 | if c == 1 : 73 | print key_list 74 | print value_list 75 | 76 | # 입력받은 대기 시간만큼 sleep 77 | time.sleep(sleep_time) 78 | c = c + 1 79 | -------------------------------------------------------------------------------- /4장/4.3 OID/oid_easyrun.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from subprocess import Popen 5 | from subprocess import PIPE 6 | 7 | def exec_cmd(cmd) : 8 | p = Popen(cmd, shell=True) 9 | p.wait() 10 | 11 | def already_setup() : 12 | p = Popen("rpm -qa | grep net-snmp-utils", shell=True, stdout = PIPE) 13 | (ret, err) = p.communicate() 14 | 15 | if ret.strip()== "": 16 | return False 17 | return True 18 | 19 | def setup(default_setupYN) : 20 | setupYN = raw_input( 21 | "snmpwalk 유틸리티 패키지를 설치하시겠습니까? (Y/N) [%s]:" %default_setupYN ) 22 | if (setupYN !='Y' and setupYN != 'y' and setupYN !='N' and setupYN != 'n'): 23 | setupYN = default_setupYN 24 | 25 | if (setupYN =='Y' or setupYN == 'y'): 26 | exec_cmd("yum install -y net-snmp-utils") 27 | print "*** 설치를 완료했습니다 ***" 28 | 29 | # 재정의된 설정값 반환 30 | return setupYN 31 | 32 | def snmpwalk(default_version, default_community): 33 | version = raw_input("Version [%s]:" % default_version ) 34 | if (version ==''): 35 | version = default_version 36 | 37 | community = raw_input("Community [%s] :" % default_community ) 38 | if (community ==''): 39 | community = default_community 40 | 41 | ip = raw_input("IP Address :") 42 | oid = raw_input("OID :") 43 | 44 | exec_cmd("snmpwalk -v %s -c %s %s %s" % (version, community, ip, oid)) 45 | 46 | # 재정의된 설정값 반환 47 | return (version, community, ip, oid) 48 | 49 | if __name__ == "__main__": 50 | setupYN = 'Y' 51 | version = '2C' 52 | community = 'public' 53 | 54 | print "OID 요청을 시작합니다." 55 | if already_setup() == False : 56 | setupYN = setup(setupYN) 57 | else : 58 | print "snmpwalk 유틸리티 패키지가 이미 설치돼 있습니다." 59 | 60 | # 설치를 완료한 경우(이미 설치되어 설치 단계를 스킵한 경우 포함) 실행됨 61 | if (setupYN =='Y' or setupYN == 'y'): 62 | snmpwalk(version, community) 63 | -------------------------------------------------------------------------------- /4장/4.4 History/history_all.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from user_list import * 5 | from datetime import datetime 6 | 7 | def remove_num(string): 8 | tmp = string.strip() # 예를 들어 string 이 ' 10 dir'라고 한다면 strip()을 적용한 후 '10 dir'이 되고, 9 | first_space = tmp.find(" ") # '10 dir'에서 첫 번째 공백은 10뒤에 있습니다. 10 | if first_space < 0 : 11 | return string 12 | tmp = tmp[first_space : len(tmp)] 13 | return tmp.strip() 14 | 15 | def history(account) : 16 | # 이력 조회를 위한 명령어 실행 17 | ret = exec_cmd("sudo -H -u %s bash -i -c 'history -r;history'" % account) 18 | ret_split = ret.strip().split("\n") 19 | i = len (ret_split) - 1 20 | 21 | # 실행 결과로부터 (명령어 수행 시간, 명령어) 형식의 이력 정보를 최신부터 추출해서 반환 22 | history_list = [] 23 | while i > 0 : 24 | cmd = ret_split[i].strip() 25 | timestamp = ret_split[i-1] 26 | i = i - 2 27 | 28 | if timestamp.find("#") < 0 : 29 | break 30 | 31 | # 명령어를 cmd 변수에, 타임스탬프를 timestamp 변수로 추출 32 | cmd = remove_num(cmd) 33 | timestamp = remove_num(timestamp) 34 | 35 | timestamp = timestamp.replace("#", "") 36 | date = str(datetime.fromtimestamp(float(timestamp))) 37 | history_list.append((date, cmd)) 38 | return history_list 39 | 40 | if __name__ == "__main__": 41 | accounts = get_accounts() 42 | for account in accounts : 43 | print "계정 :", account 44 | history_list = history(account) 45 | if len(history_list) == 0: 46 | print "\t기록된 이력 없음" 47 | for h in history_list : 48 | print "\t%s\t%s" % h 49 | print "-" * 70 50 | -------------------------------------------------------------------------------- /4장/4.4 History/history_highest.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from history_all import * 5 | 6 | def history_usage(history_list) : 7 | # (명령어, 사용 횟수)의 리스트 작성 - 가장 많이 사용된 명령어 순서로 만든 리스트 8 | cmd_list = [] 9 | for h in history_list : 10 | cmd_list.append(h[1]) # h는 (시간, 명령어)의 튜플이므로 명령어는 h[1]입니다. 11 | 12 | # 중복된 내용을 제거한 명령어 리스트 13 | cmd_key_list = list(set(cmd_list)) # cmd_list에는 같은 명령어가 많으므로 중복 제거 14 | 15 | # 원본 cmd_list에서 명령어 개수 체크하기 16 | cnt_list = [] 17 | for cmd in cmd_key_list : 18 | cnt_list.append(cmd_list.count(cmd)) 19 | 20 | # 명령어 사용 횟수가 가장 많은 순서대로 재정렬 21 | usage_sort = [] 22 | i = 0 23 | while len(cnt_list) > 0: 24 | max_cnt = max(cnt_list) 25 | max_index = cnt_list.index(max_cnt) 26 | cmd = cmd_key_list.pop(max_index) 27 | cnt = cnt_list.pop(max_index) 28 | usage_sort.append((cmd, cnt)) 29 | 30 | return usage_sort 31 | 32 | if __name__ == "__main__": 33 | accounts = get_accounts() 34 | for account in accounts : 35 | print "계정 :", account 36 | history_list = history(account) 37 | if len(history_list) == 0: 38 | print "\t기록된 이력 없음" # 이력이 없을 때 39 | else : 40 | # history_usage 함수를 이용해 많이 사용한 순서의 명령어 리스트로 3건의 이력 정보 출력 41 | usage = history_usage(history_list) 42 | i = 0 43 | while i < min(3, len(usage)) : # 이력이3 건보다 적으면 이력 수만큼 출력 44 | (cmd, cnt) = usage[i] 45 | if i == 0: 46 | print "\t가장 많이 사용한 명령어 : %s (%d번)" % (cmd, cnt) 47 | else : 48 | print "\t%d번째 많이 사용한 명령어 : %s (%d번)" % ((i + 1), cmd, cnt) 49 | i = i + 1 50 | print "-" * 70 51 | -------------------------------------------------------------------------------- /4장/4.4 History/history_newest.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from history_all import * 5 | 6 | if __name__ == "__main__": 7 | accounts = get_accounts() 8 | 9 | for account in accounts : 10 | history_list = history(account) 11 | 12 | newest_cnt = min(5, len(history_list)) 13 | print "계정 : %s의 최근 사용 명령어 : % d개" % (account, newest_cnt) 14 | if newest_cnt == 0: 15 | print "\t기록된 이력 없음" 16 | 17 | i = 0 18 | while i < newest_cnt: 19 | print "\t%s\t%s" % history_list[i] 20 | i = i + 1 21 | print "-" * 70 22 | -------------------------------------------------------------------------------- /4장/4.4 History/history_time.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from history_all import * 5 | import datetime 6 | 7 | def get_datetime(date_str) : 8 | # 문자열 형식의 날짜를 datetime 형식으로 변환 9 | return datetime.datetime.strptime(date_str, '%Y-%m-%d %H:%M:%S') 10 | 11 | def history_by_date(history_list, start_date, end_date) : 12 | # 특정 시간 범위의 명령어 실행 이력만 추출해서 반환 13 | cmd_list = [] 14 | for h in history_list : 15 | history_date = get_datetime(h[0]) 16 | if(history_date >= start_date and history_date <= end_date) : 17 | cmd_list.append(h) 18 | return cmd_list 19 | 20 | if __name__ == "__main__": 21 | # 사용자에게 시간대를 입력받습니다. 22 | print "어느 시간에 실행한 명령어를 조회하시겠습니까?" 23 | input_date = raw_input("년-월-일 시각을 입력하세요(예, 2016-08-11 14) :") 24 | input_date = input_date + ":00:00" 25 | 26 | date = get_datetime(input_date) 27 | start_date = date - datetime.timedelta(hours=1) # 입력 시각 1시간 전 28 | end_date = date + datetime.timedelta(hours=1) # 입력 시각 1시간 후 29 | 30 | print start_date, "~", end_date, "동안 입력된 명령어" 31 | print "-" * 70 32 | 33 | accounts = get_accounts() 34 | for account in accounts : 35 | history_list = history(account) 36 | if len(history_list) == 0: # 계정에 이력 정보가 없으면 건너뜀 37 | continue 38 | 39 | # history_by_date 함수를 이용해 계정별로 특정 시간대에 입력한 명령어 리스트를 출력합니다. 40 | # 입력한 시각을 기준으로 앞/뒤 1시간 사이의 이력 정보를 확인 41 | history_list = history_by_date(history_list, start_date, end_date) 42 | if len(history_list) == 0: 43 | continue 44 | 45 | # 이력 정보가 확인되면 출력 46 | print "계정 :", account 47 | for h in history_list : 48 | print "\t%s\t%s" % h 49 | print "-" * 70 50 | -------------------------------------------------------------------------------- /4장/4.4 History/user_list.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from subprocess import * 5 | 6 | def exec_cmd(cmd): 7 | p = Popen(cmd, shell=True, stdout=PIPE) 8 | (ret, err) = p.communicate() 9 | return ret 10 | 11 | def grep_login_defs(keyword) : 12 | # 사용자 계정 정보에서 필요한 값을 추출 13 | ret = exec_cmd("grep '%s' /etc/login.defs" % keyword) 14 | return ret.split()[1] 15 | 16 | def get_accounts() : 17 | # grep_login_defs 함수로 일반 사용자 ID의 계정 범위 정보 추출 18 | min_u = grep_login_defs("^UID_MIN") 19 | max_u = grep_login_defs("^UID_MAX") 20 | 21 | # 일반 사용자 계정 범위 정보를 조합한 명령어로 계정 리스트를 작성해서 반환 22 | cmd = "awk -F':' -v 'min=%s'" % min_u 23 | cmd = cmd + " -v 'max=%s'" % max_u 24 | cmd = cmd + " '{ if ( $3 >= min && $3 <= max ) print $1}' /etc/passwd" 25 | return exec_cmd(cmd).split() 26 | 27 | if __name__ == "__main__": 28 | accounts = get_accounts() 29 | for account in accounts : 30 | print account 31 | -------------------------------------------------------------------------------- /4장/4.5 CDP/auto_add_description_cdp.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from cli import * 5 | import re 6 | 7 | def get_cdp_info() : 8 | str = cli("show cdp neighbors detail") 9 | cdp_list = [] 10 | 11 | # 정규식으로 인터페이스 리스트 추출 12 | p = re.compile("Interface: .*,") # 정규식을 정의 13 | interface_list = p.findall(str) # 정규식과 매치되는 모든 단어를 리스트로 반환 14 | 15 | # 정규식으로 디바이스 ID 리스트 추출 16 | p = re.compile("Device ID:.*") 17 | device_list = p.findall(str) 18 | 19 | # 정규식으로 추출한 리스트를 (interface, Device ID) 튜플 형태의 리스트로 반환 20 | i = 0 21 | while i < len(interface_list): 22 | interface_id = interface_list[i].split(':')[1].strip() 23 | if interface_id.find("Ethernet1/") >= 0 : 24 | interface_id = interface_id.replace(",", "") 25 | platform_id = device_list[i].split(':')[1].strip() 26 | cdp_list.append((interface_id, platform_id)) 27 | i = i + 1 28 | return cdp_list 29 | 30 | def add_description(cdp_list): 31 | # cdp 인터페이스 리스트 개수만큼 반복해서 설명 정보를 조회합니다. 32 | for (interface_id, platform_id) in cdp_list : 33 | cli("configure terminal ; interface %s ; description *auto* %s"% (interface_id, platform_id)) 34 | 35 | def show_description(cdp_list): 36 | for (interface_id, platform_id) in cdp_list : 37 | print cli("show interface %s description" % interface_id) 38 | 39 | if __name__ == "__main__": 40 | cdp_list = get_cdp_info() 41 | add_description(cdp_list) 42 | show_description(cdp_list) 43 | -------------------------------------------------------------------------------- /4장/4.5 CDP/auto_add_description_mac.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from cli import * 5 | import httplib 6 | 7 | def get_mac_info() : 8 | str = cli("show mac address-table | grep 'Eth1/'") 9 | mac_info = {} 10 | 11 | for line in str.split("\n") : # 명령 결과를 한 줄씩 읽습니다. 12 | data = line.split() # 한 줄을 스페이스 단위로 나눠 리스트로 작성 13 | if len(data) < 2 : # 2번째 열의 MAC 주소가 없으면 동작하지 않음 14 | continue 15 | 16 | mac_addr = data[2] # MAC 주소 추출 17 | mac_port = data[len(data)-1] # 인터페이스 정보 추출(마지막 열) 18 | 19 | mac_list = [] 20 | if mac_info.get(mac_port) != None: # 딕셔너리에 인터페이스가 기존에 있는지 확인 21 | mac_list = mac_info.get(mac_port) # 이미 있다면 MAC 주소 리스트를 가져옴 22 | 23 | mac_list.append(mac_addr) # MAC 주소를 추가함 24 | mac_info[mac_port] = mac_list # 딕셔너리에 인터페이스의 MAC 주소 리스트 적용 25 | 26 | return mac_info 27 | 28 | def add_description(mac_info): 29 | for mac_port in mac_info : # 인터페이스(mac_port) 수만큼 반복해서 동작 30 | mac_list = mac_info.get(mac_port) # 인터페이스 MAC 주소 리스트 조회 31 | 32 | mac_addr = "" 33 | if len(mac_list) > 1 : # MAC 주소가 여러 개일 때 34 | i = 0 35 | print "*"* 30 36 | print "Num", "MAC Address" 37 | print "="* 30 38 | while i < len(mac_list) : # MAC 주소 리스트를 출력 39 | print i, mac_list[i] 40 | i = i + 1 41 | print "%s 의 MAC Address가 1개 이상입니다." % mac_port 42 | select = input("중복된 내용 중 상세 내용에 입력하고자 하는 MAC을 선택하세요 : ") 43 | mac_addr = mac_list[select] # 선택한 MAC 주소를 mac_addr 변수에 지정 44 | else : 45 | mac_addr = mac_list[0] 46 | 47 | mac = mac_addr[0:7] # MAC 주소 중 앞의 7자리 추출 48 | mac = mac.replace(".", "").upper() # MAC 주소 중 .(dot)을 제거 49 | 50 | # 웹 페이지에서 데이터 추출하는 코드 51 | try : 52 | conn = httplib.HTTPConnection("aruljohn.com") # 해당 웹 페이지에 접속 53 | conn.request("GET", "/mac/%s"% mac) # /mac/를 url에 추가 54 | res = conn.getresponse() # 웹페이지의 HTML 소스를 받음 55 | data = res.read() 56 | description = "*auto* " 57 | 58 | oui = "%s:%s:%s"% (mac[0:2],mac[2:4],mac[4:6]) # OUI -> 00:00:00 형식의 MAC 59 | search_word = "%s"% oui # OUI의 앞뒤 태그를 포함해서 찾기 60 | 61 | index = data.find(search_word) + len(search_word) # OUI 뒤에 제조사 정보가 있음 62 | if index >= 0 : 63 | vender = data[index : data.find("", index)].strip() # 앞뒤의 HTML 태그를 제거 64 | 65 | # 제조사 정보를 찾으면 설명 항목에 입력할 데이터를 작성합니다. 66 | description = "*auto* %s - %s" % (vender , mac_addr) 67 | 68 | # configure terminal 모드에서 설명 항목에 수정하는 명령을 수행합니다. 69 | cmd = "configure terminal ; interface %s ; " % mac_port 70 | cmd = cmd + "description %s" % description 71 | cli(cmd) 72 | except IOError as e: 73 | print "%s(%s)의 정보는 조회할 수 없습니다." % (mac_port, mac_addr) 74 | 75 | def show_description(mac_list): 76 | for mac_port in mac_info : 77 | print cli("show interface %s description" % mac_port) 78 | 79 | if __name__ == "__main__": 80 | mac_info = get_mac_info() 81 | add_description(mac_info) 82 | show_description(mac_info) 83 | -------------------------------------------------------------------------------- /4장/4.5 CDP/auto_add_description_mac_사용시 주의점.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/4장/4.5 CDP/auto_add_description_mac_사용시 주의점.txt -------------------------------------------------------------------------------- /4장/4.6 Interface 별 증감량/interface_data_variation.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from interface_get_data import * 5 | import time 6 | 7 | def get_rate_change(interface_num, measure, seconds) : 8 | # 각 인터페이스의 포트 타입 리스트 조회 9 | port_types = [] 10 | i = 1 11 | while i <= interface_num : 12 | # 인터페이스 개수만큼 배열에 적재합니다. 13 | port_types.append(get_port_type(i)) 14 | i = i + 1 15 | 16 | # 최초 레이트 값 17 | (start_input_pks, start_output_pks) = get_rate_list(interface_num, measure) 18 | 19 | time.sleep(seconds) 20 | 21 | (input_pks, output_pks) = get_rate_list(interface_num, measure) 22 | 23 | return (port_types, 24 | start_input_pks, input_pks, subtract(start_input_pks, input_pks), 25 | start_output_pks, output_pks, subtract(start_output_pks, output_pks)) 26 | 27 | def get_rate_list(interface_num, measure): 28 | input_pks = [] 29 | output_pks = [] 30 | i = 1 31 | while i <= interface_num : 32 | # 각 레이트 값은 일반 byte 단위이므로 기준 데이터 단위로 바꿉니다. 33 | input_pk = get_rate("input rate", i) / measure 34 | output_pk = get_rate("output rate", i) / measure 35 | 36 | # 인터페이스 개수만큼 배열에 적재합니다 37 | input_pks.append(input_pk) 38 | output_pks.append(output_pk) 39 | i = i + 1 40 | 41 | return (input_pks, output_pks) 42 | 43 | def subtract(start_rate_list, end_rate_list): 44 | i = 0 45 | change_list = [] 46 | while i < len(start_rate_list) : 47 | change_list.append(end_rate_list[i] - start_rate_list[i]) 48 | i = i + 1 49 | return change_list 50 | 51 | if __name__ == "__main__": 52 | print "데이터 증감량을 확인하기 위해 다음을 선택하십시오." 53 | interface_num = input("몇 개의 인터페이스를 확인하시겠습니까? : ") 54 | seconds = input("몇 초 후의 데이터 증감량을 확인하시겠습니까? : ") 55 | (port_types,start_input_pks, end_input_pks, change_input_pks, 56 | start_output_pks, end_output_pks, change_output_pks) = get_rate_change( 57 | interface_num, get_byte_num("M"), seconds) 58 | 59 | print "Input Rate(bps)" 60 | print "시작 값 : ", start_input_pks 61 | print "종료 값 : ", end_input_pks 62 | print "증감량 : ", change_input_pks 63 | print "=" * 70 64 | 65 | print "Output Rate(bps)" 66 | print "시작 값 : ", start_output_pks 67 | print "종료 값 : ", end_output_pks 68 | print "증감량 : ", change_output_pks 69 | print "=" * 70 70 | print "포트타입 : ", port_types 71 | -------------------------------------------------------------------------------- /4장/4.6 Interface 별 증감량/interface_get_data.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from interface_get_port_type import * 5 | 6 | def get_rate(rate, interface_num) : 7 | # 네트워크 명령을 실행해서 인터페이스의 레이트 값을 구하고 byte 단위로 반환 8 | ret = cli("show interface ethernet 1/%i | in rate"%interface_num) 9 | last_str = ret.split("\n")[2] 10 | rate_index = last_str.find(rate) + len(rate) 11 | rate_end_index =last_str.find("bps", rate_index) 12 | rate_str = last_str[rate_index : rate_end_index].strip() 13 | str_list = rate_str.split() # input rate가 940.30 M 이라면, str_list = ['940.30', 'M'] 14 | 15 | # str_list의 0번째 문자열을 0의 자리에서 반올림해서 숫자로 바꿉니다. 16 | rate_num = round(float(str_list[0]), 0) 17 | unit = "" 18 | if len(str_list) > 1 : 19 | unit = str_list[1] 20 | return rate_num * get_byte_num(unit) 21 | 22 | def get_byte_num(unit): 23 | # 단위(unit)에 따라 실제 바이트 값을 반환: 예를 들어 단위가 K이면 2의 10승이므로 1024 24 | if unit == "": 25 | return 1 26 | elif unit == "K" : 27 | return pow(2, 10) 28 | elif unit == "M" : 29 | return pow(2, 20) 30 | elif unit == "G" : 31 | return pow(2, 30) 32 | 33 | if __name__ == "__main__": 34 | interface_num = 24 # 인터페이스 숫자를 24로 고정 35 | 36 | port_types = [] 37 | input_pks= [] 38 | output_pks= [] 39 | 40 | # 정해진 인터페이스 개수만큼 반복해서 포트 타입, input/output 레이트를 구하고 리스트에 적재 41 | i = 1 42 | while i <= interface_num : 43 | input_pk = get_rate("input rate", i) 44 | output_pk = get_rate("output rate", i) 45 | 46 | port_types.append(get_port_type(i)) 47 | input_pks.append(input_pk) 48 | output_pks.append(output_pk) 49 | i = i + 1 50 | 51 | # 화면에 출력 52 | print port_types 53 | print input_pks 54 | print output_pks 55 | -------------------------------------------------------------------------------- /4장/4.6 Interface 별 증감량/interface_get_port_type.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from cli import * 5 | 6 | def get_port_type(interface_num) : 7 | str = cli("show interface ethernet 1/%i"%interface_num) 8 | title_idx = str.find("Port mode is ") 9 | port_type = "None" 10 | if title_idx >= 0 : 11 | enter_idx = str.find("\n", title_idx) # 해당 줄의 마지막에 있는 줄 바꿈 문자를 찾습니다. 12 | 13 | # 명령어 실행 결과에 'Port mode is access'가 포함돼 있다면, 14 | # line_str의 결과는 'Port mode is access'입니다. 15 | # str[title_idx : enter_idx].split()의 결과는 ['Port', 'mode', 'is', 'access']입니다. 16 | line_str = str[title_idx : enter_idx].split() 17 | port_type = line_str[len(line_str)-1] 18 | return port_type 19 | 20 | 21 | if __name__ == "__main__": 22 | interface_num = 24 # 인터페이스 숫자를 24로 고정 23 | port_types = [] 24 | 25 | i = 1 26 | while i <= interface_num : 27 | port_types.append(get_port_type(i)) # 명령어 실행 28 | i = i + 1 29 | 30 | print port_types 31 | -------------------------------------------------------------------------------- /4장/예외 사항 처리/exec_megacli_raid_infos.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from subprocess import os 5 | from subprocess import Popen 6 | 7 | def megacli(args): 8 | os.chdir('/opt/lsi/MegaCLI') 9 | cmd = './MegaCli ' + args 10 | Popen(cmd, shell=True) 11 | 12 | def check_raid_info() : 13 | print "a. Check the Raid Adapter Time." 14 | print "b. Check the Raid Adapter Information." 15 | print "c. Save the Information of Adapter as a file." 16 | print "d. Save the Status of Battery as a file." 17 | 18 | # 문자를 입력받을 때는 다음과 같이 raw_input을 사용합니다. 19 | abc = raw_input("Select to execute[a-d] : ") 20 | if abc =='a' : 21 | megacli("-AdpGetTime -aAll") 22 | elif abc =='b' : 23 | megacli("-AdpAllInfo -aAll") 24 | elif abc =='c': 25 | megacli("-AdpAllInfo -aAll >> /tmp/Adapall.txt") 26 | print "Success to save : /tmp/Adpall.txt" 27 | elif abc =='d' : 28 | megacli("-AdpBbuCmd -GetBbuStatus -aAll >> /tmp/bbu.txt") 29 | print "Success to save : /tmp/bbu.txt" 30 | 31 | def check_raid_disk() : 32 | print "a. Save the Physical Disk Status as a file." 33 | print "b. Save the Cache Policy as a file." 34 | 35 | # 숫자를 입력받을 때는 다음과 같이 input을 사용합니다. 36 | abc = raw_input("Select to execute[a-b] : ") 37 | if abc =='a' : 38 | megacli("-PDList aALL >> /tmp/pd.txt") 39 | print "Success to save : /tmp/pd.txt" 40 | elif abc =='b' : 41 | megacli("-LDGetProp -Cache -LALL -aAll >> /tmp/VD.txt") 42 | print "Success to save : /tmp/VD.txt" 43 | 44 | def collect_raid_log() : 45 | print "a. Save the adapter event log as a file." 46 | print "b. Save the firmware event log as a file." 47 | abc = raw_input("Select to execute[a-b] : ") 48 | if abc =='a' : 49 | megacli("-AdpEventLog -GetEvents -f /tmp/eventlog.txt -aAll >> /dev/null") 50 | print "Success to save : /tmp/eventlog.txt" 51 | elif abc =='b' : 52 | megacli("-fwtermlog -dsply -aAll > /tmp/lsi-fwterm.log") 53 | print "Success to save : /tmp/lsi-fwterm.log" 54 | 55 | if __name__ == "__main__": 56 | print "1. Check & Collect the General Raid Adapter Information." 57 | print "2. Collect the Raid Disk Information." 58 | print "3. Collect the Raid Event Log." 59 | 60 | inputValue = input("Select to execute[1-3] : ") 61 | if inputValue == 1: 62 | check_raid_info() 63 | elif inputValue == 2: 64 | check_raid_disk() 65 | elif inputValue == 3: 66 | collect_raid_log() 67 | -------------------------------------------------------------------------------- /4장/예외 사항 처리/exec_megacli_raid_infos_advanced.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from subprocess import os 5 | from subprocess import Popen 6 | 7 | def megacli(args): 8 | os.chdir('/opt/lsi/MegaCLI') 9 | cmd = './MegaCli ' + args 10 | Popen(cmd, shell=True) 11 | 12 | def check_raid_info() : 13 | print "a. Check the Raid Adapter Time." 14 | print "b. Check the Raid Adapter Information." 15 | print "c. Save the Information of Adapter as a file." 16 | print "d. Save the Status of Battery as a file." 17 | 18 | # 문자를 입력받을 때는 다음과 같이 raw_input을 사용합니다. 19 | abc = raw_input("Select to execute[a-d] : ") 20 | 21 | while abc < "a" or abc > "d" : 22 | abc = raw_input("Wrong input. Select to execute[a-d] : ") 23 | 24 | if abc =='a' : 25 | megacli("-AdpGetTime -aAll") 26 | elif abc =='b' : 27 | megacli("-AdpAllInfo -aAll") 28 | elif abc =='c': 29 | megacli("-AdpAllInfo -aAll >> /tmp/Adapall.txt") 30 | print "Success to save : /tmp/Adpall.txt" 31 | elif abc =='d' : 32 | megacli("-AdpBbuCmd -GetBbuStatus -aAll >> /tmp/bbu.txt") 33 | print "Success to save : /tmp/bbu.txt" 34 | 35 | def check_raid_disk() : 36 | print "a. Save the Physical Disk Status as a file." 37 | print "b. Save the Cache Policy as a file." 38 | 39 | # 숫자를 입력받을 때는 다음과 같이 input을 사용합니다. 40 | abc = raw_input("Select to execute[a-b] : ") 41 | if abc =='a' : 42 | megacli("-PDList aALL >> /tmp/pd.txt") 43 | print "Success to save : /tmp/pd.txt" 44 | elif abc =='b' : 45 | megacli("-LDGetProp -Cache -LALL -aAll >> /tmp/VD.txt") 46 | print "Success to save : /tmp/VD.txt" 47 | 48 | def collect_raid_log() : 49 | print "a. Save the adapter event log as a file." 50 | print "b. Save the firmware event log as a file." 51 | abc = raw_input("Select to execute[a-b] : ") 52 | if abc =='a' : 53 | megacli("-AdpEventLog -GetEvents -f /tmp/eventlog.txt -aAll >> /dev/null") 54 | print "Success to save : /tmp/eventlog.txt" 55 | elif abc =='b' : 56 | megacli("-fwtermlog -dsply -aAll > /tmp/lsi-fwterm.log") 57 | print "Success to save : /tmp/lsi-fwterm.log" 58 | 59 | if __name__ == "__main__": 60 | print "1. Check & Collect the General Raid Adapter Information." 61 | print "2. Collect the Raid Disk Information." 62 | print "3. Collect the Raid Event Log." 63 | 64 | inputValue = input("Select to execute[1-3] : ") 65 | while inputValue < 1 or inputValue > 3 : 66 | inputValue = input("Wrong input. Select to execute[1-3] :") 67 | 68 | if inputValue == 1: 69 | check_raid_info() 70 | elif inputValue == 2: 71 | check_raid_disk() 72 | elif inputValue == 3: 73 | collect_raid_log() 74 | -------------------------------------------------------------------------------- /5장/5.1 배시와 파이썬/combination_cli_bash.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from cli import cli 5 | from subprocess import Popen 6 | from subprocess import PIPE 7 | import datetime 8 | import time 9 | import shutil 10 | import os 11 | import sys 12 | 13 | def write_brief(brief_path) : 14 | # show interface brief 명령어를 실행해 결과를 파일에 작성 15 | ret = cli("show interface brief") 16 | f = open(brief_path, "w") 17 | f.write(ret) 18 | f.close() 19 | 20 | def get_diff_data(path1, path2) : 21 | # diff 명령어를 실행해 두 파일을 비교함. 변경 전/후 데이터를 튜플 형태로 반환 22 | p = Popen("diff --context %s %s" % (path1, path2), shell=True, stdout=PIPE) 23 | (ret, err) = p.communicate() 24 | 25 | ret = ret.strip() 26 | if ret == "" : 27 | return None 28 | 29 | ret = ret.split("***************")[1] # '**************' 이후의 데이터 추출 30 | ret = ret.split("--- ") # '--- 줄 번호 ----' 이후는 변경된 데이터이므로 이 문자열로 분할 31 | ret_before = ret[0] # 앞의 데이터는 변경 전 데이터 32 | ret_after = ret[1] # 뒤의 데이터는 변경 후 데이터 33 | return (ret_before, ret_after) 34 | 35 | def get_change_data_list(ret) : 36 | # <두 파일의 변경 전후 데이터를 바탕으로 인터페이스 번호, 실제 변경된 줄의 전/후 정보 추출 37 | (ret_before, ret_after) = ret 38 | before_data_list = [] 39 | for line in ret_before.split("\n") : 40 | eth_index = line.find("! Eth1") # 변경된 줄 찾기 41 | if eth_index == 0 : 42 | eth_num = line.split()[1].split('/')[1] # 변경된 줄의 인터페이스 번호 찾기 43 | before_data_list.append((eth_num, line[2: len(line)])) # "!"를 제거한 변경 전 데이터 추출 44 | 45 | changed_data_list = [] 46 | for (eth_num, before_line)in before_data_list : # 변경된 인터페이스 번호로 47 | idx = ret_after.find("! Eth1/"+ eth_num) # 변경 후 데이터에서 탐색 48 | enter_idx = ret_after.find("\n", idx) 49 | after_line = ret_after[idx + 2 : enter_idx] # "! "를 제거한 변경 후 데이터 추출 50 | 51 | # (변경된 인터페이스 번호, 변경 전 데이터 내용, 변경 후 데이터 내용)의 튜플 적재 52 | changed_data_list.append((eth_num, before_line, after_line)) 53 | return changed_data_list 54 | 55 | def print_run_conf(changed_data_list) : 56 | # show running-config interface 명령으로 변경된 인터페이스의 현재 정보를 출력 57 | if len(changed_data_list) == 0 : 58 | print "변경된 데이터가 없습니다." 59 | 60 | for (eth_num, before_line, after_line) in changed_data_list : 61 | print "-" * 10, ("Eth1/%s 정보" % eth_num), "-" * 10 62 | print "[ 변경 전 인터페이스 간략 정보 ]" 63 | print " ", before_line 64 | print "[ 변경 후 인터페이스 간략 정보 ]" 65 | print " ", after_line 66 | print "[ 현재 인터페이스 구성 정보 ]" 67 | run_conf = cli("show running-config interface ethernet 1/%s" % eth_num) 68 | for line in run_conf.split("\n") : 69 | if line == "" : 70 | continue 71 | elif line.startswith("!Command:") or line.startswith("!Time:"): 72 | continue 73 | elif line.startswith("version ") : 74 | continue 75 | print line 76 | print "-" * 30 77 | 78 | if __name__ == '__main__': 79 | term = input("몇 초 단위로 비교하시겠습니까? : ") 80 | count = input("몇 번 비교하시겠습니까? : ") 81 | 82 | brief_dir = "/bootflash/tmp" 83 | if not os.path.isdir(brief_dir) : 84 | os.mkdir(brief_dir) 85 | 86 | cnt = 1 87 | while cnt <= count : 88 | start_time = datetime.datetime.now() 89 | end_time = start_time + datetime.timedelta(seconds = term) 90 | now = datetime.datetime.now() 91 | 92 | brief_path1 = "/bootflash/tmp/brief.txt" 93 | brief_path2 = "/bootflash/tmp/brief2.txt" 94 | 95 | # 최초 인터페이스 정보를 brief.txt에 기록합니다. 96 | write_brief(brief_path1) 97 | 98 | print cnt, "차 비교 중입니다." 99 | while now <= end_time: 100 | sys.stdout.write(".") 101 | sys.stdout.flush() 102 | time.sleep(1) # 1초 단위로 .을 출력 103 | 104 | now = datetime.datetime.now() 105 | 106 | # 시간이 지난 후의 인터페이스 정보를 brief2.txt에 기록합니다. 107 | write_brief(brief_path2) 108 | 109 | # 최초 인터페이스와 시간이 지난 후의 인터페이스 정보를 diff로 비교 110 | ret = get_diff_data(brief_path1, brief_path2) 111 | if ret == None : 112 | print "\n#### 변경된 정보 출력 (%d 번째) ####" % cnt 113 | print "변경된 데이터가 없습니다." 114 | cnt = cnt + 1 115 | continue 116 | 117 | changed_data_list = get_change_data_list(ret) 118 | 119 | print "\n#### 변경된 정보 출력 (%d 번째) ####" % cnt 120 | print_run_conf(changed_data_list) # 변경된 인터페이스의 상세 정보 출력 121 | 122 | cnt = cnt + 1 123 | 124 | shutil.rmtree("/bootflash/tmp") 125 | -------------------------------------------------------------------------------- /5장/5.2 스케쥴러와 파이썬/auto_add_description_mac.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from cli import * 5 | import httplib 6 | 7 | def get_mac_info() : 8 | str = cli("show mac address-table | grep 'Eth1/'") 9 | mac_info = {} 10 | 11 | for line in str.split("\n") : # 명령 결과를 한 줄씩 읽습니다. 12 | data = line.split() # 한 줄을 스페이스 단위로 나눠 리스트로 작성 13 | if len(data) < 2 : # 2번째 열의 MAC 주소가 없으면 동작하지 않음 14 | continue 15 | 16 | mac_addr = data[2] # MAC 주소 추출 17 | mac_port = data[len(data)-1] # 인터페이스 정보 추출(마지막 열) 18 | 19 | mac_list = [] 20 | if mac_info.get(mac_port) != None: # 딕셔너리에 인터페이스가 기존에 있는지 확인 21 | mac_list = mac_info.get(mac_port) # 이미 있다면 MAC 주소 리스트를 가져옴 22 | 23 | mac_list.append(mac_addr) # MAC 주소를 추가함 24 | mac_info[mac_port] = mac_list # 딕셔너리에 인터페이스의 MAC 주소 리스트 적용 25 | 26 | return mac_info 27 | 28 | def add_description(mac_info): 29 | for mac_port in mac_info : # 인터페이스(mac_port) 수만큼 반복해서 동작 30 | mac_list = mac_info.get(mac_port) # 인터페이스 MAC 주소 리스트 조회 31 | 32 | mac_addr = "" 33 | mac_addr = mac_list[0] 34 | mac = mac_addr[0:7] # MAC 주소 중 앞의 7자리 추출 35 | mac = mac.replace(".", "").upper() # MAC 주소 중 .(dot)을 제거 36 | 37 | # 웹 페이지에서 데이터 추출하는 코드 38 | try : 39 | conn = httplib.HTTPConnection("aruljohn.com") # 해당 웹 페이지에 접속 40 | conn.request("GET", "/mac/%s"% mac) # /mac/를 url에 추가 41 | res = conn.getresponse() # 웹페이지의 HTML 소스를 받음 42 | data = res.read() 43 | description = "*auto* " 44 | 45 | oui = "%s:%s:%s"% (mac[0:2],mac[2:4],mac[4:6]) # OUI -> 00:00:00 형식의 MAC 46 | search_word = "%s"% oui # OUI의 앞뒤 태그를 포함해서 찾기 47 | 48 | index = data.find(search_word) + len(search_word) # OUI 뒤에 제조사 정보가 있음 49 | if index >= 0 : 50 | vender = data[index : data.find("", index)].strip() # 앞뒤의 HTML 태그를 제거 51 | 52 | # 제조사 정보를 찾으면 설명 항목에 입력할 데이터를 작성합니다. 53 | description = "*auto* %s - %s" % (vender , mac_addr) 54 | 55 | # configure terminal 모드에서 설명 항목에 수정하는 명령을 수행합니다. 56 | cmd = "configure terminal ; interface %s ; " % mac_port 57 | cmd = cmd + "description %s" % description 58 | cli(cmd) 59 | except IOError as e: 60 | print "%s(%s)의 정보는 조회할 수 없습니다." % (mac_port, mac_addr) 61 | 62 | def show_description(mac_list): 63 | for mac_port in mac_info : 64 | print cli("show interface %s description" % mac_port) 65 | 66 | if __name__ == "__main__": 67 | from cisco.vrf import * ; set_global_vrf('default') 68 | mac_info = get_mac_info() 69 | add_description(mac_info) 70 | show_description(mac_info) 71 | -------------------------------------------------------------------------------- /5장/5.2 스케쥴러와 파이썬/cdp_scheduler.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from syslog import syslog 5 | from cli import cli,clip 6 | import sys 7 | import os 8 | 9 | def dirc(): 10 | try: 11 | cli("mkdir bootflash:cdp-history") 12 | except: 13 | pass 14 | 15 | def sche_conf(day,hour,minute): 16 | cli("configure terminal ; no feature scheduler") 17 | cli("configure terminal ; feature scheduler") 18 | cli("configure terminal ; \ 19 | scheduler job name cdp-log ; \ 20 | python bootflash:scripts/intStDesc.py ; \ 21 | python bootflash:scripts/auto_add_description_mac.py ; \ 22 | exit") 23 | cli("configure terminal ; \ 24 | scheduler schedule name cdp-log ; \ 25 | job name cdp-log ; \ 26 | time start now repeat %s:%s:%s"%(day,hour,minute)) 27 | 28 | def term_set(): 29 | log_mon = 'Y' 30 | log_mon = raw_input("로그를 화면에 출력하겠습니까?[Y]") 31 | if log_mon== 'y' or log_mon == 'Y' or log_mon =='': 32 | cli('terminal monitor') 33 | 34 | def show_set(): 35 | set_mon = 'Y' 36 | set_mon = raw_input("설정된 스케줄러를 확인하시겠습니까?[Y]") 37 | if set_mon== 'y' or set_mon == 'Y' or set_mon =='': 38 | clip('show scheduler schedule') 39 | 40 | if __name__ == '__main__': 41 | day = sys.argv[1] 42 | hour = sys.argv[2] 43 | minute = sys.argv[3] 44 | dirc() 45 | sche_conf(day,hour,minute) 46 | term_set() 47 | show_set() 48 | syslog(2,'스케줄러가 cdp-log를 bootflash:cdp-history디렉터리에 %s일 %s시간 %s분 \ 49 | 간격으로 기록합니다'%(day,hour,minute)) 50 | -------------------------------------------------------------------------------- /5장/5.2 스케쥴러와 파이썬/intStDesc.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from cli import cli 5 | import time 6 | 7 | def bef_run(): 8 | now = time.localtime() 9 | st= "%04d%02d%02d_%02d%02d%02d"%(now.tm_year, now.tm_mon, now.tm_mday, 10 | now.tm_hour, now.tm_min, now.tm_sec) 11 | cli("show interface status >> bootflash:cdp-history/%s_intStaNdesc.txt"%st) 12 | cli("show interface description >> bootflash:cdp-history/%s_intStaNdesc.txt"%st) 13 | 14 | if __name__ == '__main__': 15 | bef_run() 16 | -------------------------------------------------------------------------------- /5장/5.3 크론과 파이썬/cron_sys_chk.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from subprocess import * 5 | import os 6 | 7 | def dirc(): 8 | if not os.path.exists('/tmp/history'): 9 | os.makedirs('/tmp/history') 10 | 11 | def output(command): 12 | p = Popen(command, shell=True, stdout=PIPE) 13 | (ret, err) = p.communicate() 14 | nx_ret = ret.split("\n") 15 | return nx_ret 16 | 17 | def sche_conf(minute,hour,day): 18 | active_user = output('whoami')[0] 19 | cmd = "%s %s %s * * /root/run_reqular_chk.sh\n"%(minute,hour,day) 20 | with open("/var/spool/cron/%s"%active_user,"w") as out: 21 | out.write(cmd) 22 | call(['systemctl', 'restart','crond']) 23 | print "%s는 주기적으로 /root/reqular_chk.sh를 실행해 /tmp/history에 저장합니다."%active_user 24 | 25 | def show_set(): 26 | set_mon = 'Y' 27 | set_mon = raw_input("설정된 스케줄러를 확인하시겠습니까?[Y]") 28 | if set_mon== 'y' or set_mon == 'Y' or set_mon =='': 29 | print "설정된 crontab은 다음과 같습니다." 30 | print output('crontab -l') 31 | print "\n현재의 cron 데몬의 상태는 다음과 같습니다." 32 | sys_stat = output('systemctl status crond') 33 | for i in sys_stat: 34 | print i 35 | 36 | if __name__ == '__main__': 37 | minute = raw_input("설정할 분을 입력하세요 [Tip '*'을 입력하면 매분 실행됩니다.] :") 38 | hour = raw_input("설정할 시를 입력하세요 [Tip '*'을 입력하면 매시 실행됩니다.] :") 39 | day = raw_input("설정할 일을 입력하세요 [Tip '*'을 입력하면 매일 실행됩니다.] :") 40 | dirc() 41 | sche_conf(minute,hour,day) 42 | show_set() 43 | -------------------------------------------------------------------------------- /5장/5.3 크론과 파이썬/reqular_chk.sh.sh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/5장/5.3 크론과 파이썬/reqular_chk.sh.sh -------------------------------------------------------------------------------- /5장/5.3 크론과 파이썬/run_reqular_chk.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | /root/reqular_chk.sh >> /tmp/history/reqular_chk_$(date '+%Y-%m-%d-%H:%M').log -------------------------------------------------------------------------------- /5장/5.4 CoPP 모니터링/copp_check.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from cli import * 5 | import re 6 | 7 | def get_drop_packet() : 8 | ret = cli("show policy-map interface control-plane | in dropped") 9 | drop_packet_list = [] 10 | for line in ret.split("\n") : 11 | line = line.strip() 12 | str_array = line.split() 13 | if len(line) > 1 : 14 | drop_packet_list.append(int(str_array[1])) 15 | 16 | return drop_packet_list 17 | 18 | def get_policy_class_map() : 19 | ret = cli("show policy-map interface control-plane") 20 | find_list = re.findall("class-map .*match-any", ret) 21 | 22 | class_list = [] 23 | 24 | for data in find_list : 25 | str_list = data.split() 26 | class_list.append(str_list[1]) 27 | 28 | return class_list 29 | 30 | def get_copp_status() : 31 | ret = cli("show copp status") 32 | if ret.find("Policy-map attached to the control-plane: copp-system-p-policy-strict") < 0: 33 | find_list = re.findall("Policy-map attached to the control-plane: .*", ret) 34 | data = find_list[0] 35 | data = data.split(":")[1] 36 | return data 37 | return "기본값" 38 | 39 | if __name__ == "__main__": 40 | # 드랍량 출력 41 | print "드랍량 :", get_drop_packet() 42 | 43 | # 클래스맵 출력 44 | print "CoPP 클래스맵 :", get_policy_class_map() 45 | 46 | # CoPP 정책 출력 47 | print "CoPP 정책 :", get_copp_status() 48 | -------------------------------------------------------------------------------- /5장/5.4 CoPP 모니터링/copp_logging.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from copp_check import get_drop_packet 5 | from copp_check import get_policy_class_map 6 | from copp_check import get_copp_status 7 | from time import sleep 8 | from syslog import syslog 9 | 10 | def get_term_str(seconds) : 11 | # 초를 문자열(x시 x분 x초)로 변경 12 | hours = check_term / 3600 13 | minutes = (check_term % 3600) / 60 14 | seconds = check_term % 60 15 | 16 | check_term_str = "" 17 | if hours > 0 : 18 | check_term_str = "%d시 " % hours 19 | if minutes > 0 : 20 | check_term_str = check_term_str + ("%d분 " % minutes) 21 | if seconds > 0 : 22 | check_term_str = check_term_str + ("%d초 " % seconds) 23 | 24 | return check_term_str 25 | 26 | def subtract(packet_list1, packet_list2): 27 | i = 0 28 | change_list = [] 29 | while i < len(packet_list1) : 30 | change_list.append(packet_list2[i] - packet_list1[i]) 31 | i = i + 1 32 | return change_list 33 | 34 | def write_syslog(changed_pk_list, check_term_str) : 35 | class_list = get_policy_class_map() 36 | 37 | i = 0 38 | packet_changed = False 39 | for changed_pk in changed_pk_list : 40 | if changed_pk != 0 : 41 | log = "%s에서 %s동안 %d packets이 드랍이 발생하였습니다." % ( 42 | class_list[i], check_term_str, changed_pk) 43 | packet_changed = True 44 | syslog(2, log) 45 | i = i + 1 46 | 47 | if packet_changed : 48 | write_syslog_policy() 49 | 50 | def write_syslog_policy() : 51 | copp = get_copp_status() 52 | if copp == "기본값" : 53 | log = "추가로 현재 CoPP는 시스코에서 권고하는 기본값입니다." 54 | else : 55 | log = "추가로 CoPP 정책이 기본값이 아닙니다. (현재값 : %s)" % copp 56 | syslog(2, log) 57 | 58 | if __name__ == "__main__": 59 | check_term = 600 # 체크 시간은 초 단위로 60 | 61 | # 경과 시간을 문자열(x시 x분 x초)로 변경 62 | check_term_str = get_term_str(check_term) 63 | 64 | original_pk = get_drop_packet() 65 | sleep(check_term) 66 | changed_pk = subtract(original_pk, get_drop_packet()) 67 | 68 | #드랍량을 syslog에 남김 69 | write_syslog(changed_pk, check_term_str) 70 | -------------------------------------------------------------------------------- /5장/5.5 EEM과 파이썬/EEM 실행 명령어 입력.txt: -------------------------------------------------------------------------------- 1 | event manager applet HighCPU 2 | event snmp oid 1.3.6.1.4.1.9.9.109.1.1.1.1.6.1 get-type exact entry-op ge entry-val 50 poll-interval 5 3 | action 1.0 syslog priority notifications msg Run_HighCPU.log 4 | action 2.0 cli python bootflash:scripts/high_cpu.py 5 | action 3.0 syslog priority notifications msg Complete_HighCPU.log 6 | -------------------------------------------------------------------------------- /5장/5.5 EEM과 파이썬/high_cpu.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from cli import cli 5 | import time 6 | 7 | def collecting_items(out_file): 8 | tmps = ["show system resources", 9 | "show process cpu sort | exclude 0.0", 10 | "show processes cpu history", 11 | "show system internal processes cpu", 12 | "show policy-map interface control-plane", 13 | "show hardware rate-limiter", 14 | "show hardware internal cpu-mac inband counters", 15 | "show hardware internal cpu-mac inband stats", 16 | "show system inband queuing status", 17 | "show system inband queuing statistics", 18 | "show system internal pktmgr internal vdc global-stats"] 19 | for tmp in tmps: 20 | str = cli(tmp) 21 | out_file.write(str) 22 | 23 | def collect_log(): 24 | now = time.localtime() 25 | st= "%04d%02d%02d_%02d%02d%02d_"%(now.tm_year, now.tm_mon, now.tm_mday, 26 | now.tm_hour, now.tm_min, now.tm_sec) 27 | tmp_file = "/bootflash/%sHighCPU.log"%st 28 | out_file = open(tmp_file, "w") 29 | collecting_items(out_file) 30 | out_file.close() 31 | 32 | if __name__ == "__main__": 33 | collect_log() 34 | -------------------------------------------------------------------------------- /5장/5.6 EEM과 파이썬 응용/a. FTP로 이미지 내려받기 _ 내려받은 이미지 파일로 부트 환경을 자동으로 재구성하기/auto_provisioning.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import ftp 5 | import sys 6 | from cli import * 7 | import time 8 | 9 | def boot_image(host, id, pw, image_path) : 10 | cli("configure terminal ; interface ethernet 1/24 ; description python auto_provisioning") 11 | cli("configure terminal ; interface ethernet 1/24 ; switchport ; switchport mode trunk ; \ 12 | switchport trunk allowed vlan 500") 13 | 14 | print "Auto_provision을 위한 준비를 하고 있습니다." 15 | tm = 0 16 | while tm < 30: 17 | sys.stdout.write(".") 18 | sys.stdout.flush() 19 | time.sleep(1) 20 | tm +=1 21 | cli("ping %s count 1"%host) 22 | print "\n" 23 | 24 | file_index = image_path.rfind("/") + 1 25 | image_file_name = image_path[file_index: len(image_path)] 26 | ftp_image_dir = image_path[0: file_index] 27 | local_dir = "/bootflash/" 28 | ftp.download(host, id, pw, ftp_image_dir, local_dir, image_file_name ) 29 | 30 | cli("configure terminal ; no event manager applet Auto-Provisioning") 31 | cli("configure terminal ; interface ethernet 1/24 ; no description ; no switchport") 32 | cli("configure terminal ; boot nxos bootflash:///%s" % image_file_name) 33 | print "다음에 부팅될 nxos 버전 :", cli("show running-config | include nxos") 34 | 35 | if __name__ == "__main__": 36 | host = 37 | id = 38 | pw = 39 | image_path = "nxos.7.0.3.I4.1.bin" # 이미지 파일명 40 | 41 | if len(sys.argv) > 4 : 42 | host = sys.argv[1] 43 | id = sys.argv[2] 44 | pw = sys.argv[3] 45 | image_path = sys.argv[4] 46 | 47 | boot_image(host, id, pw, image_path) 48 | -------------------------------------------------------------------------------- /5장/5.6 EEM과 파이썬 응용/a. FTP로 이미지 내려받기 _ 내려받은 이미지 파일로 부트 환경을 자동으로 재구성하기/ftp.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | import ftplib 4 | import sys 5 | import os 6 | 7 | # 글로벌 변수 영역 8 | image_file_name = "" 9 | local_path = "/bootflash/" 10 | ftp_path = "" 11 | file_size = 0 12 | percent = 0 13 | view_unit = 10 14 | 15 | def ftp_down(host, id, pw): # FTP에 접속해 파일을 내려받는 함수입니다. 16 | ftp = ftplib.FTP(host=host, user=id, passwd=pw, timeout=3600) 17 | ftp.cwd(ftp_path) 18 | 19 | global file_size 20 | file_size = ftp.size(image_file_name) 21 | 22 | print "Start Download... ", file_size, "bytes" 23 | fd = open(local_path, "ab") 24 | fd.close() 25 | ftp.retrbinary("RETR " + image_file_name, write_file_callback, 1000000) 26 | print "100% - Complete." 27 | 28 | ftp.close() 29 | 30 | def write_file_callback(s) : # FTP에 접속해 내려받은 파일을 바이너리로 로컬 파일에 작성하는 함수입니다. 31 | global percent 32 | fd = open(local_path, "ab") 33 | fd.write(s) 34 | 35 | download_size = os.path.getsize(local_path); 36 | percent_now = round(download_size*(100/view_unit)/file_size) 37 | if percent != percent_now : 38 | print percent_now * view_unit, "% (", download_size, ") bytes" 39 | 40 | percent = percent_now 41 | fd.close() 42 | 43 | def download(host, id, pw, ftp_image_dir, local_dir, file_name) : 44 | # 글로벌 변수 중 ftp_path, image_file_name, local_path에 값을 지정합니다. 45 | global ftp_path 46 | global image_file_name 47 | global local_path 48 | 49 | image_file_name = file_name 50 | ftp_path = ftp_image_dir 51 | local_path = "%s%s" % (local_dir, file_name) 52 | 53 | # 로컬 파일로 작성하려는 경로에 있는 파일을 삭제합니다. 54 | try : 55 | os.remove(local_path) 56 | except : 57 | print "%s 파일이 없습니다."%local_path 58 | print "계속 진행합니다.\n" 59 | pass 60 | 61 | # 파일 내려받습니다. 62 | ftp_down(host, id, pw) 63 | 64 | if __name__ == "__main__": 65 | host = 66 | id = 67 | pw = 68 | ftp_path = "" 69 | local_dir = "/bootflash/" # 로컬 디렉터리 위치 70 | image_file_name = "nxos.7.0.3.I4.1.bin" # 이미지 파일명 71 | 72 | download(host, id, pw, ftp_path, local_dir, image_file_name) 73 | -------------------------------------------------------------------------------- /5장/5.6 EEM과 파이썬 응용/b. EEM을 통해 이미지 업그레이드 자동화 구현하기/EEM으로 작성한 Auto-Provisioning.txt: -------------------------------------------------------------------------------- 1 | event manager applet Auto-Provisioning 2 | event syslog pattern 'Interface Ethernet1/24 is up in mode access' 3 | action 1.0 syslog priority notifications msg Run_Python_Auto_Provisioning 4 | action 2.0 cli python bootflash:scripts/auto_provisioning.py 5 | action 3.0 syslog priority notifications msg Finish_Python_Auto_Provisioning -------------------------------------------------------------------------------- /5장/5.6 EEM과 파이썬 응용/b. EEM을 통해 이미지 업그레이드 자동화 구현하기/auto_provisioning.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import ftp 5 | import sys 6 | from cli import * 7 | import time 8 | 9 | def boot_image(host, id, pw, image_path) : 10 | cli("configure terminal ; interface ethernet 1/24 ; description python auto_provisioning") 11 | cli("configure terminal ; interface ethernet 1/24 ; switchport ; switchport mode trunk ; \ 12 | switchport trunk allowed vlan 500") 13 | 14 | print "Auto_provision을 위한 준비를 하고 있습니다." 15 | tm = 0 16 | while tm < 30: 17 | sys.stdout.write(".") 18 | sys.stdout.flush() 19 | time.sleep(1) 20 | tm +=1 21 | cli("ping %s count 1"%host) 22 | print "\n" 23 | 24 | file_index = image_path.rfind("/") + 1 25 | image_file_name = image_path[file_index: len(image_path)] 26 | ftp_image_dir = image_path[0: file_index] 27 | local_dir = "/bootflash/" 28 | ftp.download(host, id, pw, ftp_image_dir, local_dir, image_file_name ) 29 | 30 | cli("configure terminal ; no event manager applet Auto-Provisioning") 31 | cli("configure terminal ; interface ethernet 1/24 ; no description ; no switchport") 32 | cli("configure terminal ; boot nxos bootflash:///%s" % image_file_name) 33 | print "다음에 부팅될 nxos 버전 :", cli("show running-config | include nxos") 34 | 35 | if __name__ == "__main__": 36 | from cisco.vrf import * ; set_global_vrf('default') 37 | 38 | host = 39 | id = 40 | pw = 41 | image_path = "nxos.7.0.3.I4.1.bin" # 이미지 파일명 42 | 43 | if len(sys.argv) > 4 : 44 | host = sys.argv[1] 45 | id = sys.argv[2] 46 | pw = sys.argv[3] 47 | image_path = sys.argv[4] 48 | 49 | boot_image(host, id, pw, image_path) 50 | -------------------------------------------------------------------------------- /5장/5.6 EEM과 파이썬 응용/b. EEM을 통해 이미지 업그레이드 자동화 구현하기/eem_config.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from cli import cli,clip 5 | 6 | def eem_conf(interface): 7 | syslog_var1 = "configure terminal ; event manager applet Auto-Provisioning ;" 8 | syslog_var2 = "event syslog pattern 'Interface Ethernet%s is up in mode access'"%interface 9 | syslog_var_pattern = syslog_var1 + syslog_var2 10 | 11 | cli(syslog_var_pattern) 12 | cli("configure terminal ; event manager applet Auto-Provisioning ; \ 13 | action 1.0 syslog priority notifications msg Run_Python_Auto_Provisioning") 14 | cli("configure terminal ; event manager applet Auto-Provisioning ; \ 15 | action 2.0 cli python bootflash:scripts/auto_provisioning.py") 16 | cli("configure terminal ; event manager applet Auto-Provisioning ; \ 17 | action 3.0 syslog priority notifications msg Finish_Python_Auto_Provisioning") 18 | 19 | if __name__ == "__main__": 20 | interface='1/24' 21 | interface = raw_input("어떤 인터페이스로 nxos 이미지를 내려받으시겠습니까?[1/24]") 22 | if interface=='': 23 | interface='1/24' 24 | eem_conf(interface) 25 | clip("show running-config eem") 26 | -------------------------------------------------------------------------------- /5장/예외 사항처리/intStDesc.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from cli import cli 5 | import time 6 | 7 | def bef_run(): 8 | now = time.localtime() 9 | st= "%04d%02d%02d_%02d%02d%02d"%(now.tm_year, now.tm_mon, now.tm_mday, 10 | now.tm_hour, now.tm_min, now.tm_sec) 11 | cli("show interface status >> bootflash:cdp-history/%s_intStaNdesc.txt"%st) 12 | cli("show interface description >> bootflash:cdp-history/%s_intStaNdesc.txt"%st) 13 | 14 | if __name__ == '__main__': 15 | bef_run() 16 | -------------------------------------------------------------------------------- /5장/예외 사항처리/intStDesc_advanced.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | try : 5 | from cli import cli 6 | except : 7 | try : 8 | from cisco import cli 9 | except : 10 | print "cli 함수를 이용하기 위한 모듈이 설치되어 있지 않습니다." 11 | import time 12 | 13 | def bef_run(): 14 | now = time.localtime() 15 | st= "%04d%02d%02d_%02d%02d%02d"%(now.tm_year, now.tm_mon, now.tm_mday, 16 | now.tm_hour, now.tm_min, now.tm_sec) 17 | cli("show interface status >> bootflash:cdp-history/%s_intStaNdesc.txt"%st) 18 | cli("show interface description >> bootflash:cdp-history/%s_intStaNdesc.txt"%st) 19 | 20 | if __name__ == '__main__': 21 | bef_run() 22 | -------------------------------------------------------------------------------- /6장 (Hoon Jo)/6.2.1 UCS 매니저 에뮬레이터/ucs_image_downloader.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from ucsmsdk.utils.ccoimage import get_ucs_cco_image_list 5 | from ucsmsdk.utils.ccoimage import get_ucs_cco_image 6 | from subprocess import os 7 | 8 | def ucs_cco_image_search(cco_id,cco_password,keyword): 9 | global indexes 10 | global image_list 11 | 12 | # 이미지 리스트를 받아온 원본 13 | image_list = get_ucs_cco_image_list(cco_id,cco_password) 14 | 15 | # 이미지 리스트 중에 image_name이 포함된 줄만 추출 16 | i = 0 17 | str_img_list = [] 18 | for number in image_list: 19 | str_img = str(image_list[i]) 20 | idx = str_img.find("image_name") 21 | str_img = str_img[idx : str_img.find("\n", idx)].split()[1] 22 | str_img_list.append(str_img) 23 | i=i+1 24 | 25 | # 이미지를 검색해 다시 추출함 26 | indexes = [i for i, item in enumerate(str_img_list) if item.find(keyword)>=0] 27 | 28 | # 검색된 이미지 리스트 29 | i = 0 30 | print "=-"*20 31 | print "번호\t\t이미지 이름" 32 | print "-="*20 33 | for idx in indexes: 34 | print("%d") %i, str_img_list[idx] 35 | i=i+1 36 | 37 | def ucs_cco_image_download(selected_number): 38 | download_number = indexes[selected_number] 39 | get_ucs_cco_image(image=image_list[download_number], file_dir="/root/ccoimage") 40 | 41 | if __name__ == "__main__": 42 | print "=-"*30 43 | print "UCS 이미지를 내려받으려면 시스코 홈페이지에 로그인해야 합니다." 44 | print "-="*30 45 | cco_id = raw_input("로그인 ID를 입력하세요 : ") 46 | cco_password = raw_input("로그인 암호를 입력하세요 : ") 47 | keyword = raw_input("검색할 이미지 이름 또는 버전을 입력하세요 (예 : 3.1.1e) : ") 48 | print "검색 중입니다." 49 | ucs_cco_image_search(cco_id,cco_password,keyword) 50 | selected_number= input("내려받을 이미지 번호를 선택하세요 : ") 51 | try: 52 | os.mkdir('/root/ccoimage') # 디렉터리 생성 / 디렉터리가 있다면 생성되지 않음 53 | finally: 54 | print "내려받는 중입니다." 55 | ucs_cco_image_download(selected_number) # 디렉터리의 존재와 관계없이 실행됨 56 | -------------------------------------------------------------------------------- /6장 (Hoon Jo)/6.2.1 UCS 매니저 에뮬레이터/ucsm_backup_n_import.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from ucsmsdk.ucshandle import UcsHandle 5 | from ucsmsdk.utils.ucsbackup import backup_ucs 6 | from ucsmsdk.utils.ucsbackup import import_ucs_backup 7 | 8 | def ucsm_config_backup(ucsm_ip,user,password): 9 | handle = UcsHandle(ucsm_ip,user,password) 10 | handle.login() 11 | backup_ucs(handle,backup_type="config-all", file_dir=r"C:\py\config",file_name=ucsm_ip+"_"+"config-all.xml") 12 | handle.logout() 13 | 14 | def ucsm_config_import(ucsm_ip,user,password): 15 | handle = UcsHandle(ucsm_ip,user,password) 16 | handle.login() 17 | import_ucs_backup(handle, file_dir=r"C:\py\config",file_name=ucsm_ip+"_"+"config-all.xml") 18 | handle.logout() 19 | 20 | if __name__ == "__main__": 21 | ucsm_ip = raw_input("백업 또는 복원할 UCS 매니저의 IP를 입력해 주세요 : ") 22 | print "\n"+"=-"*30 23 | print "1. 설정 파일 백업" 24 | print "2. 설정 파일 복원" 25 | print "-="*30+"\n" 26 | 27 | while True: 28 | select = raw_input("작업을 선택해 주세요 : ") 29 | if select =='1': 30 | ucsm_config_backup(ucsm_ip,'ucspe','ucspe') 31 | break 32 | elif select =='2': 33 | ucsm_config_import(ucsm_ip,'ucspe','ucspe') 34 | break 35 | elif select =='exit': 36 | break 37 | else: 38 | print "1 또는 2가 아닌 값입니다. 프로그램을 종료하시려면 exit를 입력하세요 " 39 | continue 40 | -------------------------------------------------------------------------------- /6장 (Hoon Jo)/6.2.1 UCS 매니저 에뮬레이터/ucsm_gui_launcher.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from ucsmsdk.ucshandle import UcsHandle 5 | from ucsmsdk.utils.ucsguilaunch import ucs_gui_launch 6 | 7 | def ucsm_gui_launch(ucsm_ip,user,password): 8 | handle = UcsHandle(ucsm_ip,user,password) 9 | handle.login() 10 | ucs_gui_launch(handle) 11 | handle.logout() 12 | 13 | if __name__ == "__main__": 14 | ucsm_gui_launch('192.168.56.250','ucspe','ucspe') 15 | -------------------------------------------------------------------------------- /6장 (Hoon Jo)/6.2.1 UCS 매니저 에뮬레이터/ucsm_handle.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from ucsmsdk.ucshandle import UcsHandle 5 | 6 | global handle 7 | handle = UcsHandle('192.168.56.250','ucspe','ucspe') 8 | 9 | def standard_login(): 10 | handle.login() 11 | print "UCS 매니저(%s)에 로그인합니다. " % (handle.ucs) 12 | 13 | def standard_logout(): 14 | handle.logout() 15 | print "UCS 매니저에서 로그아웃합니다." 16 | 17 | if __name__ == "__main__": 18 | standard_login() 19 | print "UCS 매니저 접속 주소 : "+ handle.uri 20 | standard_logout() 21 | -------------------------------------------------------------------------------- /6장 (Hoon Jo)/6.2.1 UCS 매니저 에뮬레이터/ucsm_lable.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from ucsmsdk.ucshandle import UcsHandle 5 | 6 | def change_lable(ucsm_ip,user,password): 7 | handle = UcsHandle(ucsm_ip,user,password) 8 | handle.login() 9 | print "\n-----------모든 블레이드 서버의 이름. 변경 전---------------" 10 | blades = handle.query_classid(class_id="computeBlade") 11 | for blade in blades: 12 | print "Blade-" + blade.slot_id + " Lable:-" + blade.usr_lbl 13 | blade.usr_lbl = "Ironman" + blade.slot_id # 블레이드 이름 + 번호 14 | handle.set_mo(blade) 15 | handle.commit() 16 | 17 | print "\n-----------모든 블레이드 서버의 이름. 변경 후---------------" 18 | blades = handle.query_classid(class_id="computeBlade") 19 | for blade in blades: 20 | print "Blade-" + blade.slot_id + " Lable:-" + blade.usr_lbl 21 | handle.logout() 22 | 23 | if __name__ == "__main__": 24 | ucsm_ip = raw_input("블레이드 이름을 변경할 UCS 매니저의 IP를 입력해 주세요 : ") 25 | change_lable(ucsm_ip,'ucspe','ucspe') 26 | 27 | 28 | -------------------------------------------------------------------------------- /6장 (Hoon Jo)/6.2.1 UCS 매니저 에뮬레이터/ucsm_mometa.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from ucsmsdk.ucshandle import UcsHandle 5 | from time import sleep 6 | 7 | def create(): 8 | from ucsmsdk.mometa.vnic.VnicSanConnPolicy import VnicSanConnPolicy 9 | from ucsmsdk.mometa.vnic.VnicFc import VnicFc 10 | from ucsmsdk.mometa.vnic.VnicFcIf import VnicFcIf 11 | from ucsmsdk.mometa.vnic.VnicFcNode import VnicFcNode 12 | 13 | mo = VnicSanConnPolicy(parent_mo_or_dn="org-root", policy_owner="local", 14 | name="TestSANConPolicy", descr="TestSANConPolicy") 15 | mo_1 = VnicFc(parent_mo_or_dn=mo, addr="derived", name="TestWWPNForSAN", 16 | admin_host_port="ANY", admin_vcon="any", stats_policy_name="default", 17 | admin_cdn_name="", switch_id="A", pin_to_group_name="", 18 | pers_bind="disabled", pers_bind_clear="no", qos_policy_name="", 19 | adaptor_profile_name="", ident_pool_name="test001", order="1", 20 | nw_templ_name="", max_data_field_size="2048") 21 | mo_1_1 = VnicFcIf(parent_mo_or_dn=mo_1, name="default") 22 | mo_2 = VnicFcNode(parent_mo_or_dn=mo, ident_pool_name="WWNtestPool", 23 | addr="pool-derived") 24 | handle.add_mo(mo) 25 | handle.commit() 26 | 27 | 28 | def modify_FcNode(): 29 | from ucsmsdk.mometa.vnic.VnicSanConnPolicy import VnicSanConnPolicy 30 | from ucsmsdk.mometa.vnic.VnicFcNode import VnicFcNode 31 | 32 | mo = VnicSanConnPolicy(parent_mo_or_dn="org-root", policy_owner="local", 33 | name="TestSANConPolicy", descr="Test SAN Connectivity Policy") 34 | mo_1 = VnicFcNode(parent_mo_or_dn=mo, ident_pool_name="test", addr="pool-derived") 35 | handle.add_mo(mo, True) 36 | handle.commit() 37 | 38 | 39 | def modify_Fc(): 40 | from ucsmsdk.mometa.vnic.VnicSanConnPolicy import VnicSanConnPolicy 41 | from ucsmsdk.mometa.vnic.VnicFc import VnicFc 42 | 43 | mo = VnicSanConnPolicy(parent_mo_or_dn="org-root", policy_owner="local", 44 | name="TestSANConPolicy", 45 | descr="Test SAN Connectivity Policy Change Test") 46 | mo_1 = VnicFc(parent_mo_or_dn=mo, addr="derived", name="TestvHBA001", 47 | admin_host_port="ANY", admin_vcon="any", stats_policy_name="default", 48 | admin_cdn_name="", switch_id="A", pin_to_group_name="", 49 | pers_bind="disabled", pers_bind_clear="no", qos_policy_name="", 50 | adaptor_profile_name="", ident_pool_name="WWPNTEST001", order="1", 51 | nw_templ_name="", max_data_field_size="2048") 52 | handle.add_mo(mo, True) 53 | handle.commit() 54 | 55 | def modify_Group_StorageInit(): 56 | from ucsmsdk.mometa.storage.StorageIniGroup import StorageIniGroup 57 | from ucsmsdk.mometa.vnic.VnicFcGroupDef import VnicFcGroupDef 58 | from ucsmsdk.mometa.storage.StorageInitiator import StorageInitiator 59 | 60 | mo = StorageIniGroup(parent_mo_or_dn="org-root/san-conn-pol-TestSANConPolicy", 61 | name="Test01InitiatorG", descr="Test01InitiatorGroup Test", 62 | group_policy_name="", policy_name="", policy_owner="local", 63 | rmt_disk_cfg_name="") 64 | mo_1 = VnicFcGroupDef(parent_mo_or_dn=mo, storage_conn_policy_name="", 65 | policy_owner="local", name="", descr="", 66 | stats_policy_name="default") 67 | mo_2 = StorageInitiator(parent_mo_or_dn=mo, policy_owner="local", 68 | name="TestWWPNForSAN", descr="") 69 | handle.add_mo(mo) 70 | handle.commit() 71 | 72 | def remove(): 73 | obj = handle.query_dn("org-root/san-conn-pol-TestSANConPolicy") 74 | handle.remove_mo(obj) 75 | handle.commit() 76 | 77 | if __name__ == "__main__": 78 | global handle 79 | handle = UcsHandle("192.168.56.250", "ucspe", "ucspe") 80 | handle.login() 81 | 82 | print "****************************" 83 | print "1. Creation : Fc,Fclf,FcNoe" 84 | print "****************************" 85 | create() 86 | sleep(60) 87 | 88 | print "*****************************" 89 | print "2. Modification : VnicFcNode" 90 | print "*****************************" 91 | modify_FcNode() 92 | sleep(60) 93 | 94 | print "*************************" 95 | print "3. Modification : VnicFc" 96 | print "*************************" 97 | modify_Fc() 98 | sleep(60) 99 | 100 | print "***************************************************" 101 | print "4. Modification : VnicFcGroupsDef,StorageInitiator" 102 | print "***************************************************" 103 | modify_Group_StorageInit() 104 | sleep(60) 105 | 106 | print "**************************" 107 | print "5. Removal : SANConPolicy" 108 | print "**************************" 109 | remove() 110 | handle.logout() 111 | -------------------------------------------------------------------------------- /6장 (Hoon Jo)/6.2.2 실제 UCS 매니저/ucsm_techsupport.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from ucsmsdk.ucshandle import UcsHandle 5 | from ucsmsdk.utils.ucstechsupport import get_ucs_tech_support 6 | import time 7 | 8 | global s 9 | now = time.localtime() 10 | s= "%04d%02d%02d_%02d%02d%02d_"%(now.tm_year, now.tm_mon, now.tm_mday, 11 | now.tm_hour, now.tm_min, now.tm_sec) 12 | 13 | def fullGetTechSupport(ucsm_ip,user,password): 14 | print "블레이드 샤시 로그를 수집합니다" 15 | print "해당 수집 작업은 5분에서 20분 정도 소요될 예정입니다." 16 | handle = UcsHandle(ucsm_ip,user,password) 17 | handle.login() 18 | get_ucs_tech_support(handle,file_dir="/root/techsupport",file_name=s+'FI_UCSM.tar', 19 | timeout_in_sec=600, remove_from_ucs=True) 20 | handle.logout() 21 | 22 | def singleGetTechSupport(ucsm_ip,user,password,chassis,blade): 23 | print chassis+'-'+blade+"블레이드 로그를 수집합니다." 24 | print "해당 수집 작업은 5분에서 20분 정도 소요될 예정입니다." 25 | handle = UcsHandle(ucsm_ip,user,password) 26 | handle.login() 27 | get_ucs_tech_support(handle,file_dir="/root/techsupport", 28 | file_name=s+'FI_BL'+chassis+'-'+blade+'.tar', 29 | chassis_id=chassis,cimc_id=blade,timeout_in_sec=600, 30 | remove_from_ucs=True) 31 | handle.logout() 32 | 33 | if __name__ == "__main__": 34 | ucsm_ip = raw_input("UCS 매니저 IP 주소를 입력하세요 : ") 35 | user = raw_input("관리자 ID를 입력하세요 : ") 36 | password = raw_input("암호를 입력하세요: ") 37 | 38 | print "\n\t"+"#"*25 39 | print "\t1.블레이드 샤시 로그 수집" 40 | print "\t2.블레이드 서버 로그 수집" 41 | print "\t"+"#"*25 42 | 43 | while True: 44 | select = raw_input("\n어느 작업을 실행하시겠습니까? (1,2,exit): ") 45 | if select=='1': 46 | fullGetTechSupport(ucsm_ip,user,password) 47 | break 48 | elif select=='2': 49 | chassis = raw_input("샤시 번호를 입력하세요 : ") 50 | blade = raw_input("블레이드 번호를 입력하세요 : ") 51 | singleGetTechSupport(ucsm_ip,user,password,chassis,blade) 52 | break 53 | elif select=='exit': 54 | break 55 | else: 56 | print "-="*20 57 | print "1 또는 2가 아닌 값입니다.\n프로그램을 종료하시려면 exit를 입력하세요" 58 | print "=-"*20 59 | continue 60 | -------------------------------------------------------------------------------- /6장 (Hoon Jo)/6.2.2 실제 UCS 매니저/ucsm_vkvm_launcher.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from ucsmsdk.ucshandle import UcsHandle 5 | from ucsmsdk.utils.ucskvmlaunch import ucs_kvm_launch 6 | 7 | def vKVM_launch(ucsm_ip,user,password,chassis,blade): 8 | handle = UcsHandle(ucsm_ip,user,password) 9 | handle.login() 10 | mo = handle.query_dn("sys/chassis-{0}/blade-{1}".format(chassis,blade)) 11 | print mo 12 | ucs_kvm_launch(handle, blade=mo) 13 | handle.logout() 14 | 15 | if __name__ == "__main__": 16 | ucsm_ip = raw_input("UCS 매니저 IP를 입력하세요 : ") 17 | user = raw_input("관리자 ID를 입력하세요 : ") 18 | password = raw_input("암호를 입력하세요 : ") 19 | chassis = raw_input("접속할 샤시 번호를 입력하세요 : ") 20 | blade = raw_input("접속할 블레이드 서버 번호를 입력하세요 : ") 21 | vKVM_launch(ucsm_ip,user,password,chassis,blade) 22 | -------------------------------------------------------------------------------- /6장 (Hoon Jo)/6.2.3 실제 UCS 랙 서버/general_vkvm_launcher.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from subprocess import os 5 | 6 | def vKVM_launcher(cimc_ip,c_user,c_password): 7 | print "%s에 vKVM에 접속합니다."%cimc_ip 8 | os.chdir('c:\py\kvm') 9 | cmd = 'launchkvm.bat -u %s -p %s -h %s'%(c_user,c_password,cimc_ip) 10 | os.system(cmd) 11 | 12 | if __name__ == "__main__": 13 | cimc_ip = raw_input("vKVM에 접속할 랙 서버 매니저의 IP를 입력해 주세요 : ") 14 | c_user = raw_input("관리자 ID를 입력하세요 : ") 15 | c_password = raw_input("암호를 입력하세요 : ") 16 | vKVM_launcher(cimc_ip,c_user,c_password) 17 | -------------------------------------------------------------------------------- /6장 (Hoon Jo)/6.2.3 실제 UCS 랙 서버/imc_backup_n_import.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from ImcSdk import * 5 | 6 | def cimc_config_backup(cimc_ip,c_user,c_password,cb_ftpip,cb_ftpuser,cb_password, 7 | cb_passphrase): 8 | handle = ImcHandle() 9 | handle.login(cimc_ip,username=c_user,password=c_password) 10 | print "%s에 구성을 백업합니다"%cimc_ip 11 | backup_imc(handle,cb_ftpip,cimc_ip+"-config_backup.xml",protocol="ftp", 12 | username=cb_ftpuser, password=cb_password,passphrase=cb_passphrase) 13 | print "%s에 구성 백업이 %s에 %s로 완료되었습니다"%(cimc_ip,cb_ftpip, 14 | cimc_ip+"-config_backup.xml") 15 | handle.logout() 16 | 17 | def cimc_config_import(cimc_ip,c_user,c_password,ci_ftpip,ci_ftpuser,ci_password, 18 | ci_passphrase): 19 | handle = ImcHandle() 20 | handle.login(cimc_ip,username=c_user,password=c_password) 21 | print "%s에 구성 복원을 시작합니다"%cimc_ip 22 | import_imc_backup(handle,ci_ftpip,cimc_ip+"-config_backup.xml",protocol="ftp", 23 | username=ci_ftpuser, password=ci_password,passphrase=ci_passphrase) 24 | print "%s에 구성 복원이 완료되었습니다"%cimc_ip 25 | handle.logout() 26 | 27 | if __name__ == "__main__": 28 | cimc_ip = raw_input("백업 또는 복원할 랙 서버 매니저의 IP를 입력해 주세요 : ") 29 | c_user = raw_input("관리자 ID를 입력하세요 : ") 30 | c_password = raw_input("암호를 입력하세요 : ") 31 | 32 | print "\n"+"=-"*10 33 | print "1. 구성 파일 백업" 34 | print "2. 구성 파일 복원" 35 | print "-="*10+"\n" 36 | 37 | while True: 38 | select = raw_input("작업을 선택해 주세요 : ") 39 | if select =='1': 40 | cb_ftpip = raw_input("백업 파일을 저장할 FTP 주소를 입력하세요 : ") 41 | cb_ftpuser = raw_input("FTP 사용자 이름을 입력하세요 : ") 42 | cb_password = raw_input("FTP 사용자 암호를 입력하세요 : ") 43 | cb_passphrase = raw_input("새로 생성될 백업 파일의 암호를 입력하세요 : ") 44 | cimc_config_backup(cimc_ip,c_user,c_password,cb_ftpip,cb_ftpuser, 45 | cb_password,cb_passphrase) 46 | break 47 | elif select =='2': 48 | ci_ftpip = raw_input("복원할 파일이 위치한 FTP 주소를 입력하세요 : ") 49 | ci_ftpuser = raw_input("FTP 사용자 이름을 입력하세요 : ") 50 | ci_password = raw_input("FTP 사용자 암호를 입력하세요 : ") 51 | ci_passphrase = raw_input("복원할 백업 파일의 암호를 입력하세요 : ") 52 | print "복원은 백업에 비해 다소 많은 시간이 소요되며, 일반적으로 10분에서 20분 정도 소요됩니다." 53 | cimc_config_import(cimc_ip,c_user,c_password,ci_ftpip,ci_ftpuser, 54 | ci_password,ci_passphrase) 55 | break 56 | elif select =='exit': 57 | break 58 | else: 59 | print "1 또는 2가 아닌 값입니다. 프로그램을 종료하시려면 exit를 입력하세요 " 60 | continue 61 | -------------------------------------------------------------------------------- /6장 (Hoon Jo)/6.2.3 실제 UCS 랙 서버/imc_techsupport.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from ImcSdk import * 5 | import time 6 | 7 | def cimc_techsupport(cimc_ip,c_user,c_password,ftp_ip,ftp_user,ftp_password): 8 | now = time.localtime() 9 | s= "%04d%02d%02d_%02d%02d%02d_"%(now.tm_year, now.tm_mon, now.tm_mday, 10 | now.tm_hour, now.tm_min, now.tm_sec) 11 | 12 | handle = ImcHandle() 13 | handle.login(cimc_ip,username=c_user,password=c_password) 14 | filename = s+handle.imc+"_techsupport.tar.gz" 15 | 16 | print "%s에 로그를 받아서 %s에 %s 파일로 저장됩니다."%(cimc_ip,ftp_ip,filename) 17 | 18 | get_imc_techsupport(handle,ftp_ip,filename,protocol="ftp",username=ftp_user, 19 | password=ftp_password,timeout_sec=600,dump_xml=None) 20 | handle.logout() 21 | 22 | if __name__ == "__main__": 23 | cimc_ip = raw_input("로그 수집할 랙 서버 매니저의 IP를 입력해 주세요 : ") 24 | c_user = raw_input("관리자 ID를 입력하세요 : ") 25 | c_password = raw_input("암호를 입력하세요 : ") 26 | print "\n로그 파일은 원격지에 저장됩니다. 이번 예제에서는 FTP에 저장하겠습니다.\n" 27 | ftp_ip = raw_input("로그 파일을 저장할 FTP 주소를 입력하세요 : ") 28 | ftp_user = raw_input("FTP 사용자 이름을 입력하세요 : ") 29 | ftp_password = raw_input("FTP 사용자 암호를 입력하세요 : ") 30 | cimc_techsupport(cimc_ip,c_user,c_password,ftp_ip,ftp_user,ftp_password) 31 | -------------------------------------------------------------------------------- /7장/7.1 원격지 장비/7.1.1 시스템 종류 자동 인식/ssh_check_type.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from ssh_exec_cmd import * 5 | 6 | def check_type() : 7 | system_type = "Unknown" 8 | data = exec_cmd("uname -a") 9 | if data.find("Linux ") >= 0 : 10 | data = exec_cmd("grep . /etc/*-release") 11 | system_type = "Linux" 12 | elif data.find("VMkernel ") >=0 : 13 | system_type = "VMware" 14 | elif data.find("Cmd exec") >= 0 : 15 | data = exec_cmd("show version") 16 | if data.find("Cisco Nexus Operating System (NX-OS) Software") >=0: 17 | data = exec_cmd("show version | include version") 18 | system_type = "NX-OS_Switch" 19 | elif data.lower().find("invalid command") >= 0 : 20 | data = exec_cmd("show version") 21 | if data.find("Firmware Version") >=0 : 22 | system_type = "UCSC_MGMT_Port" 23 | elif data.find("System version") >=0: 24 | system_type = "UCSM_FI" # 현재 랩에서 NX-OS가 아닌 경우는 UCSM 입니다. 25 | return (system_type, data) # (시스템 종류, 화면 출력 메시지(버전 정보))를 반환 26 | 27 | def get_message(system_type, cmd_result) : 28 | if system_type == "Linux" : 29 | return "리눅스 시스템입니다. : %s" % get_line(cmd_result, 0) 30 | elif system_type == "VMware" : 31 | return "VMware 시스템입니다. : %s" % get_line(cmd_result, 0) 32 | elif system_type == "UCSC_MGMT_Port" : 33 | return "서버 관리 모듈입니다. : %s(%s)" % ( 34 | get_line(cmd_result, 0), get_line(cmd_result, 2)) 35 | elif system_type == "NX-OS_Switch" : 36 | return "네트워크 시스템입니다. : %s" % get_line(cmd_result, 3) 37 | elif system_type == "UCSM_FI" : 38 | return "UCS 매니저 시스템입니다. : %s" % get_line(cmd_result, 0) 39 | return "시스템 타입을 알 수 없습니다." 40 | 41 | def get_line(data, row) : 42 | lines = data.split("\n") 43 | return str(lines[row]).strip() 44 | 45 | if __name__ == '__main__': 46 | # ssh_exec_cmd의 get_connection_input, connect 함수를 사용할 수 있습니다. 47 | # 접속 정보를 입력받고, 원격지 시스템에 접속 48 | (host, port_num, user, pw) = get_connection_input() 49 | connnected = connect(host, port_num, user, pw) 50 | if connnected: 51 | close() 52 | else : 53 | print "원격지 시스템 접속에 실패하였습니다." 54 | if connnected : 55 | (system_type, cmd_result) = check_type() # check_type 함수로 시스템 종류를 판단 56 | print get_message(system_type, cmd_result) # 시스템 종류에 따른 버전 정보 출력 57 | -------------------------------------------------------------------------------- /7장/7.1 원격지 장비/7.1.1 시스템 종류 자동 인식/ssh_connect.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import paramiko 5 | 6 | client = paramiko.SSHClient() 7 | client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 8 | 9 | host =<원격지 시스템 주소> 10 | port_num = <원격지 시스템 포트> # host, user, pw는 문자열이지만 port_num은 숫자입니다. 11 | user = <관리자 ID> 12 | pw = <관리자 암호> 13 | client.connect(hostname=host, port=port_num, username=user, password=pw) 14 | print client 15 | client.close() 16 | -------------------------------------------------------------------------------- /7장/7.1 원격지 장비/7.1.1 시스템 종류 자동 인식/ssh_exec_cmd.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import paramiko 5 | import time 6 | 7 | client = None 8 | (host, port_num, user, pw) = ("", 22, "", "") 9 | def connect(host, port_num, user, pw) : 10 | # 접속에 성공하면 SSHClient를 client 변수로 생성하고 접속 결과를 True/False로 반환 11 | global client # 접속한 SSHClient를 global 변수 client로 설정 12 | client = paramiko.SSHClient() 13 | client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 14 | try : 15 | # 접속한 접속 정보를 모두 global 변수로 설정합니다. 16 | set_connection_info(host, port_num, user, pw) 17 | client.connect(hostname=host, port=port_num, username=user, password=pw) 18 | return True 19 | except : 20 | return False 21 | 22 | def close() : 23 | client.close() # SSH 접속을 해제 24 | 25 | def exec_cmd(cmd) : # 명령어를 수행한 결과를 읽습니다. 26 | if connect(host, port_num, user, pw) : 27 | try : 28 | (stdin, stdout, stderr) = client.exec_command(cmd) 29 | if stderr.read().strip() != "" : 30 | return invoke_shell(cmd) 31 | return stdout.read().strip() 32 | except : 33 | print "명령어를 수행할 수 없습니다. :", cmd 34 | close() 35 | 36 | def invoke_shell(cmd) : # 원격지 시스템과 상호 메시지를 주고받는 식으로 명령어를 수행한 결과를 읽어서 반환 37 | channel = client.invoke_shell() # invoke_shell로 SSH 채널을 설정합니다. 38 | response = channel.recv(9999) # 응답을 받습니다(접속과 관련된 응답 메시지). 39 | channel.send(cmd + "\n") # 실행할 명령어를 보냅니다("\n" 또는 "\r"을 붙여서 실행). 40 | while not channel.recv_ready(): # 명령어를 실행하고 응답할 준비가 됐는지 대기합니다. 41 | time.sleep(3) 42 | response = channel.recv(9999) # 명령어 실행 결과를 받습니다. 43 | out = response.decode("utf-8") # 명령어 실행 결과를 utf-8 문자열로 바꿉니다. 44 | 45 | # 첫 번째 줄은 제거합니다(2번째 줄부터 실제 명령어 실행 결과가 출력되기 때문입니다). 46 | first_enter_index = min(out.find("\r"), out.find("\n")) 47 | 48 | # "\r\n"을 일반 엔터로 바꾸어 표시합니다. 49 | # 바꾸지 않고 그대로 표시하면 \r이 화면에서는 알 수 없는 문자(♪)로 표시됩니다. 50 | out = out[first_enter_index : len(out)] 51 | out = out.replace("\r\n", "\n") 52 | return out.strip() 53 | 54 | def get_connection_input() : 55 | host = raw_input("원격지 시스템의 IP를 입력하세요. : ") 56 | port_num = 22 57 | try : 58 | port_num = input("원격지 시스템의 Port 번호를 입력하세요. [22] : ") 59 | except : 60 | port_num = 22 61 | user = raw_input("관리자 ID를 입력하세요. : ") 62 | pw = raw_input("암호를 입력하세요. : ") 63 | return (host, port_num, user, pw) 64 | 65 | def set_connection_info(input_host, input_port_num, input_user, input_pw): 66 | global host, port_num, user, pw 67 | host = input_host 68 | port_num = input_port_num 69 | user = input_user 70 | pw = input_pw 71 | 72 | if __name__ == '__main__': 73 | # 원격지 시스템 접속을 위한 접속 정보를 입력받음 74 | (host, port_num, user, pw) = get_connection_input() 75 | 76 | connnected = connect(host, port_num, user, pw) # 접속을 수행합니다. 77 | if connnected: 78 | close() 79 | else : 80 | print "원격지 시스템 접속에 실패하였습니다." 81 | if connnected: 82 | cmd = "dir" 83 | print "수행 명령어 :", cmd 84 | print exec_cmd(cmd) 85 | print "*" * 70 86 | cmd = "ls" 87 | print "수행 명령어 :", cmd 88 | print exec_cmd(cmd) 89 | print "*" * 70 90 | -------------------------------------------------------------------------------- /7장/7.1 원격지 장비/7.1.2 원격지 명령 실행/ssh_check_cpu_status.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from ssh_check_type import * 5 | 6 | def print_exec_cmd(cmd) : # 명령어 실행 결과를 화면에 출력 7 | print "*" * 70 8 | print exec_cmd(cmd) 9 | 10 | def print_cpu_mem_disk_status(system_type) : # 시스템별 CPU, 메모리, 디스크 상태를 출력하는 명령어 실행 11 | print "=" * 70 12 | print "CPU/메모리/디스크 정보 조회" 13 | if system_type == "Linux" : 14 | print_exec_cmd("top -b -n1") 15 | print_exec_cmd("free -mt") 16 | print_exec_cmd("ps aux --sort=-pcpu | head -5") 17 | print_exec_cmd("ps aux --sort=-pmem | head -5") 18 | print_exec_cmd("df -h") 19 | elif system_type == "NX-OS_Switch" : 20 | print_exec_cmd("show system resource") 21 | print_exec_cmd("show processes cpu sort | head") 22 | print_exec_cmd("show processes memory shared | head") 23 | print_exec_cmd("dir") 24 | 25 | if __name__ == '__main__': 26 | (host, port_num, user, pw) = get_connection_input() # 접속 정보를 입력받고, 27 | connnected = connect(host, port_num, user, pw) # 원격지 시스템에 접속합니다. 28 | if connnected: 29 | close() 30 | else : 31 | print "원격지 시스템 접속에 실패하였습니다." 32 | if connnected: 33 | (system_type, cmd_result) = check_type() 34 | if system_type == "Linux" or system_type == "NX-OS_Switch" : 35 | print_cpu_mem_disk_status(system_type) # 시스템별 CPU, 메모리, 디스크 상태를 출력 36 | else : 37 | print "리눅스/네트워크 시스템이 아니어서 실행할 수 없습니다." 38 | -------------------------------------------------------------------------------- /7장/7.1 원격지 장비/7.1.2 원격지 명령 실행/ssh_check_mgmt_route.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from ssh_check_cpu_status import * 5 | 6 | def print_mgmt_status(system_type) : # 관리 네트워크 정보를 출력하는 명령어 실행 7 | print "=" * 70 8 | print "관리 네트워크 정보 조회" 9 | if system_type == "Linux" : 10 | print_exec_cmd("hostname") 11 | print_exec_cmd("ip addr") 12 | elif system_type == "NX-OS_Switch" : 13 | print_exec_cmd("show hostname") 14 | print_exec_cmd("show interface mgmt0 ") 15 | print_exec_cmd("show running-config interface mgmt0") 16 | print_exec_cmd("show running-config | in \"ip route\"") 17 | 18 | def print_route_status(system_type) : # IP 경로 정보를 출력하는 명령어 실행 19 | print "=" * 70 20 | print "IP 경로 정보 조회" 21 | if system_type == "Linux" : 22 | print_exec_cmd("route") 23 | elif system_type == "NX-OS_Switch" : 24 | print_exec_cmd("show ip route") 25 | 26 | def print_status(system_type) : # 시스템별 CPU, 메모리, 디스크, 관리 네트워크, IP 경로 정보를 조회하고 화면에 출력 27 | if system_type == "Linux" or system_type == "NX-OS_Switch" : 28 | print_cpu_mem_disk_status(system_type) # ssh_check_cpu_status의 함수 29 | print_mgmt_status(system_type) 30 | print_route_status(system_type) 31 | else : 32 | print "리눅스/네트워크 시스템이 아니어서 실행할 수 없습니다." 33 | 34 | if __name__ == '__main__': 35 | # 접속 정보를 입력받고, 원격지 시스템에 접속합니다. 36 | (host, port_num, user, pw) = get_connection_input() 37 | connnected = connect(host, port_num, user, pw) 38 | if connnected: 39 | close() 40 | else : 41 | print "원격지 시스템 접속에 실패하였습니다." 42 | if connnected: 43 | # 시스템별 CPU, 메모리, 디스크 상태를 출력합니다. 44 | (system_type, cmd_result) = check_type() 45 | print_status(system_type) 46 | -------------------------------------------------------------------------------- /7장/7.1 원격지 장비/7.1.2 원격지 명령 실행/ssh_get_status_file.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from ssh_check_type import * 5 | import os 6 | import time 7 | from datetime import datetime 8 | 9 | def save_exec_cmd(cmd, file_name) : # 명령어를 실행한 결과를 파일로 저장 10 | data = exec_cmd(cmd) 11 | file_path = "%s/%s" %(dir_name, file_name) 12 | f = open(file_path, "w") 13 | f.write(data) 14 | f.close() 15 | print "파일 저장 완료 : ", os.path.abspath(file_path) 16 | 17 | def get_date_str() : # 현재 날짜를 문자열 yyyyMMdd_HHmmss 형식으로 반환 18 | now = time.localtime() 19 | return ("%04d%02d%02d_%02d%02d%02d" % ( 20 | now.tm_year, now.tm_mon, now.tm_mday, 21 | now.tm_hour, now.tm_min, now.tm_sec)) 22 | 23 | def save_cpu_mem_disk_status(system_type) : # CPU, 메모리, 디스크 상태를 저장하는 명령어 실행 24 | def_file_name = "%s_result.txt" % get_date_str() 25 | if system_type == "Linux" : 26 | save_exec_cmd("top -b -n1", "top_%s"%def_file_name) 27 | save_exec_cmd("free -mt", "free_%s"%def_file_name) 28 | save_exec_cmd("ps aux --sort=-pcpu | head -5", "ps_aux_pcpu_%s"%def_file_name) 29 | save_exec_cmd("ps aux --sort=-pmem | head -5", "ps_aux_pmpm_%s"%def_file_name) 30 | save_exec_cmd("df -h", "df_%s"%def_file_name) 31 | elif system_type == "NX-OS_Switch" : 32 | save_exec_cmd("show system resource", "sys_resource_%s"%def_file_name) 33 | save_exec_cmd("show processes cpu sort | head", "show_cpu_%s"%def_file_name) 34 | save_exec_cmd("show processes memory shared | head", "show_mem_%s"%def_file_name) 35 | save_exec_cmd("dir", "dir_%s"%def_file_name) 36 | 37 | def save_mgmt_route_status(system_type) : # 관리 네트워크 정보를 저장하는 명령어 실행 38 | def_file_name = "%s_result.txt" % get_date_str() 39 | if system_type == "Linux" : 40 | save_exec_cmd("hostname", "hostname_%s"%def_file_name) 41 | save_exec_cmd("ip addr", "ip_addr_%s"%def_file_name) 42 | elif system_type == "NX-OS_Switch" : 43 | save_exec_cmd("show hostname", "show_hostname_%s"%def_file_name) 44 | save_exec_cmd("show interface mgmt0","show_int_mgmt_%s"%def_file_name) 45 | save_exec_cmd("show running-config interface mgmt0", 46 | "show_run_int_mgmt0_%s"%def_file_name) 47 | save_exec_cmd("show running-config | in 'ip route'", 48 | "show_run_ip_route_%s"%def_file_name) 49 | 50 | def save_route_status(system_type) : # IP 경로 정보를 저장하는 명령어 실행 51 | def_file_name = "%s_result.txt" % get_date_str() 52 | if system_type == "Linux" : 53 | save_exec_cmd("route", "route_%s"%def_file_name) 54 | elif system_type == "NX-OS_Switch" : 55 | save_exec_cmd("show ip route", "show_ip_route_%s"%def_file_name) 56 | 57 | def save_status_files(system_type) : # 시스템별 CPU, 메모리, 디스크, 관리 네트워크, IP 경로 정보를 조회하고 파일에 저장 58 | if system_type == "Linux" or system_type == "NX-OS_Switch" : 59 | save_cpu_mem_disk_status(system_type) 60 | save_mgmt_route_status(system_type) 61 | save_route_status(system_type) 62 | else : 63 | print "리눅스/네트워크 시스템이 아니어서 실행할 수 없습니다." 64 | 65 | def prepare_dir(host) : # 로그를 작성할 디렉터리 준비 66 | global dir_name 67 | dir_name = "./logs" 68 | if not os.path.isdir(dir_name): # 디렉터리가 있는지 확인 69 | os.mkdir(dir_name) # 디렉터리 만들기 70 | dir_name = "./logs/%s" % host # 원격지 시스템 주소를 포함해서 디렉터리명을 정의 71 | if not os.path.isdir(dir_name): # 디렉터리가 있는지 확인 72 | os.mkdir(dir_name) # 디렉터리 만들기 73 | 74 | if __name__ == '__main__': 75 | (host, port_num, user, pw) = get_connection_input() 76 | connnected = connect(host, port_num, user, pw) 77 | if connnected: 78 | close() 79 | else : 80 | print "원격지 시스템 접속에 실패하였습니다." 81 | if connnected : 82 | (system_type, cmd_result) = check_type() 83 | 84 | # 파일을 작성할 디렉터리 생성 85 | prepare_dir(host) 86 | 87 | # CPU, 메모리, 디스크, 관리 네트워크, IP 경로 정보를 조회해서 저장 88 | save_status_files(system_type) 89 | -------------------------------------------------------------------------------- /7장/7.1 원격지 장비/7.1.3 여러 원격지/ssh_get_status_file_ip_range.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from ssh_get_status_file import * 5 | 6 | def get_host_list(host): # 입력받은 IP 범위 값 사이에 있는 모든 주소를 리스트로 작성 7 | hosts = [] 8 | ipv4_num = host.split('.') 9 | exist_ip_range = False 10 | for i,ip_range in enumerate(ipv4_num): 11 | exist_ip_range = "-" in ip_range 12 | if exist_ip_range: 13 | range1 = int(ip_range.split("-")[0]) # 범위 시작 값 14 | range2 = int(ip_range.split("-")[1]) + 1 # 범위 마지막 값(range로 사용하기 위해 1을 더함) 15 | for digit in range(range1, range2): 16 | ip = '.'.join(ipv4_num[:i] + [str(digit)] + ipv4_num[i+1:]) # IP 형식으로 바꿈 17 | hosts += get_host_list(ip) 18 | break 19 | if not exist_ip_range: # 범위값이 포함되지 않으면 더이상 재귀 호출을 하지 않습니다. 20 | hosts.append(host) 21 | return hosts 22 | 23 | def get_connection_range_input() : # 원격지 시스템에 접속하기 위한 IP(범위 값), 포트 번호, 관리자 ID, 암호를 입력받습니다. 24 | print "IP 범위 예시 " 25 | print "192.168.0.1-192.168.0.10\t\t192.168.0.1-10 까지" 26 | print "172.16.0.100-172.16.10.200\t\t172.16.0-10.100-200까지" 27 | host_list = [] 28 | while True : 29 | host = raw_input("원격지 시스템의 IP 범위를 입력하세요. : ") 30 | if host.find("-") < 0 : # "-"가 포함돼 있지 않다면 하나의IP 를 입력한 것입니다. 31 | host_list.append(host) 32 | break 33 | host_list = get_host_list(host) # 입력한 범위 사이의 IP 리스트를 찾습니다. 34 | if len(host_list) < 1 : 35 | print "IP 범위를 잘못 입력하였습니다." 36 | else : 37 | break 38 | port_num = 22 39 | try : 40 | port_num = input("원격지 시스템의 Port 번호를 입력하세요. [22] : ") 41 | except : 42 | port_num = 22 43 | user = raw_input("관리자 ID를 입력하세요. : ") 44 | pw = raw_input("암호를 입력하세요. : ") 45 | return (host_list, port_num, user, pw) 46 | 47 | if __name__ == '__main__': 48 | # get_connection_range_input 함수를 이용해 원격지 시스템에 접속하기 위한 접속 정보를 입력받음 49 | (host_list, port_num, user, pw) = get_connection_range_input() 50 | 51 | # 입력한 범위의 IP 주소로 각 시스템에 접속해 상태 정보를 파일로 출력 52 | for host in host_list : 53 | connnected = connect(host, port_num, user, pw) 54 | if connnected: 55 | close() 56 | else : 57 | print "*" * 50 58 | print "%s 에 접속할 수 없습니다." % host 59 | if connnected: 60 | print "*"* 50 61 | print "%s 에 접속하여 로그 기록 중..." % host 62 | (system_type, cmd_result) = check_type() 63 | prepare_dir(host) 64 | save_status_files(system_type) 65 | -------------------------------------------------------------------------------- /7장/7.2 스마트 로그 수집기/7.2.1 CPU 상태 감지/cpu_usage_monitoring.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from cli import cli 5 | from time import sleep 6 | import sys 7 | 8 | def get_proc_status_list() : 9 | # 'show processes cpu sort | head' 명령어의 실행 결과로부터 필요한 데이터 추출 10 | ret = cli("show processes cpu sort | head") 11 | ret = ret.strip() # 빈 행 제외 12 | proc_status_list = [] 13 | 14 | for i, line in enumerate(ret.split("\n")) : 15 | if i < 2 : # 헤더와 구분자 행 제외 16 | continue 17 | columns = line.split() # 한 줄 데이터를 공백 단위로 분리 18 | CPU_IDX = len(columns) - 2 19 | PROC_IDX = len(columns) - 1 20 | pid = columns[0] # 분리된 데이터 중 첫 번째는 PID 21 | cpu_usage = columns[CPU_IDX] # 뒤에서 두 번째 데이터는 CPU 사용량 22 | process = columns[PROC_IDX] # 마지막 데이터는 프로세스 이름 23 | proc_status_list.append((pid, cpu_usage, process)) 24 | return proc_status_list # (프로세스 ID, cpu 사용률, Process) 튜플의 리스트 반환 25 | 26 | def get_monitoring_input() : # 모니터링할 프로세스를 선택하기 위해 사용자의 입력을 받습니다. 27 | # 현재 동작 중인 프로세스의 리스트 출력 28 | mon_proc_status_list = get_proc_status_list() 29 | print "\n*********************[ 현재 동작 중인 프로세스 ]**********************\n" 30 | print "\t번호\tPID\tCPU\tProcess" 31 | print "\t" + ("-" * 40) 32 | for i, (pid, cpu_usage, process) in enumerate(mon_proc_status_list) : 33 | print "\t%i\t%s\t%s\t%s" % ((i + 1), pid, cpu_usage, process) 34 | print "\n" + ("*" * 70) 35 | 36 | proc_cnt = len(mon_proc_status_list) 37 | select_num = 0 38 | while True : 39 | try : 40 | select_num = input("1. 모니터링 프로세스의 번호를 선택하세요. [1-%i] : "% proc_cnt) 41 | if select_num <= proc_cnt : 42 | break 43 | except : 44 | continue 45 | (pid, cpu, process) = mon_proc_status_list[select_num-1] 46 | return process 47 | 48 | def get_user_input() : # 모니터링 조건(시간 단위, CPU 사용률 범위)을 지정하기 위해 사용자의 입력을 받습니다. 49 | sleep_time = 30 50 | try : 51 | sleep_time = input("\n2. 모니터링할 시간 단위(초)를 5초 이상으로 입력해 주세요 [30]: ") 52 | if sleep_time < 5 : 53 | sleep_time = 5 54 | except : 55 | sleep_time = 30 56 | print "\n3. 모니터링할 프로세스의 정상범위 CPU 사용률을 지정해주세요." 57 | print "\t소수점으로 입력할 수 있습니다." 58 | min_cpu_usage = input("\t최소 사용률 : ") 59 | max_cpu_usage = input("\t최대 사용률 : ") 60 | 61 | print "\n", sleep_time, "초 단위로", 62 | print min_cpu_usage,"~",max_cpu_usage,"사이의 CPU 사용률을 유지하는지 모니터링합니다." 63 | if min_cpu_usage > max_cpu_usage : 64 | max_cpu_usage = min_cpu_usage 65 | return (sleep_time, float(min_cpu_usage) , float(max_cpu_usage)) 66 | 67 | def monitoring(mon_process, sleep_time, min_cpu_usage, max_cpu_usage) : # 선택한 프로세스를 모니터링 68 | while True : 69 | alert_list = [] 70 | for (pid, cpu, process) in get_proc_status_list() : 71 | # 모니터링하려고 선택한 프로세스가 아니면 모니터링에서 제외합니다. 72 | if process != mon_process : 73 | continue 74 | cpu_usage = float(cpu.split("%")[0]) 75 | 76 | # 모니터링 조건에서 사용자가 입력한 CPU의 사용 범위에 맞는지 확인합니다 77 | if cpu_usage >= min_cpu_usage and cpu_usage <= max_cpu_usage : 78 | continue 79 | 80 | # CPU 사용 범위에서 벗어나면 사용자에게 알려줄 문제 프로세스 리스트로 추가합니다 81 | alert_list.append((pid, cpu, process)) 82 | if len(alert_list) > 0 : 83 | print "\n\n*********************[ 문제가 발견된 프로세스 ]**********************\n" 84 | print "\tPID\tProcess\tCPU" 85 | print "\t" + ("-" * 40) 86 | for (pid, cpu, process) in alert_list : 87 | print "\t%s\t%s\t%s" % (pid, cpu, process) 88 | if len(alert_list) > 0 : 89 | print "\t" + ("-" * 40) 90 | sys.stdout.write("...") 91 | sys.stdout.flush() 92 | sleep(sleep_time) 93 | 94 | if __name__ == "__main__": 95 | # 모니터링 조건 입력 96 | mon_process = get_monitoring_input() # 모니터링할 프로세스를 선택합니다. 97 | (sleep_time, min_cpu_usage, max_cpu_usage) = get_user_input() 98 | 99 | # 모니터링 실행 100 | monitoring(mon_process, sleep_time, min_cpu_usage, max_cpu_usage) 101 | -------------------------------------------------------------------------------- /7장/7.2 스마트 로그 수집기/7.2.2 인터페이스 감지/check_interface_pk.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from check_interface_ui import get_user_input 5 | from cli import cli 6 | import re 7 | 8 | def find_status(err_type, interface_data): # 데이터에서 하나의 에러 코드 타입의 상태 값을 추출 9 | # "[숫자] [선택한 에러 코드]" 문자열 탐색 10 | find_datas = re.findall("[0-9]* %s"% err_type, interface_data) 11 | 12 | # 정규식으로 찾은 문자열은 1건입니다. 13 | find_data = find_datas[0].strip() 14 | status = find_data.split()[0] # 찾은 문자열을 공백으로 잘라서 앞의 데이터인 상태 값을 추출 15 | return int(status) # 결과를 숫자 형태로 반환합니다. 16 | 17 | def get_interface_data_list(interface) : # interface(여러 개일 수 있음)의 상태 데이터에서 각 interface의 상태 데이터 추출 18 | ret = cli("show interface ethernet " + interface) 19 | find_datas = re.findall("Ethernet.* is *.", ret) # 'Ethernet<인터페이스 번호> is up(또는 down)' 규칙대로 인터페이스별 데이터 분할 20 | interface_data_list = [] 21 | start_idx = 0 22 | end_idx = 0 23 | for i, find_data in enumerate(find_datas): 24 | start_idx = ret.find(find_data) 25 | if i < len(find_datas) - 1 : 26 | end_idx = ret.find(find_datas[i+1]) 27 | else : 28 | end_idx = len(ret) 29 | interface_name = find_data.split(" is")[0] # is 앞의 값은 인터페이스 이름으로 함 30 | interface_data = ret[start_idx : end_idx] # 해당 인터페이스의 데이터 31 | interface_data_list.append((interface_name, interface_data)) 32 | return interface_data_list 33 | 34 | def get_status(interface_data, packet, err_type) : # interface 상태 데이터에서 패킷 타입, 에러 코드 타입으로 상태 값을 추출 35 | # packet은 "TX"나 "RX"입니다. 36 | title_idx = interface_data.index(" " + packet) 37 | 38 | # RX /TX 패킷을 기준으로 뒤따라 나오는 데이터 39 | interface_data = interface_data[title_idx : len(interface_data)] 40 | status_info = {} 41 | if isinstance(err_type, list) : # 선택한 에러 코드가 리스트 형태로 여러 개이면 반복합니다. 42 | for err in err_type : 43 | status = find_status(err, interface_data) 44 | status_info[err] = status 45 | else : 46 | status = find_status(err_type, interface_data) 47 | status_info[err_type] = status 48 | return status_info 49 | 50 | if __name__ == "__main__": 51 | (interface, packet, err_type, err_chk_range, log_type) = get_user_input() 52 | 53 | # 사용자 선택 결과 출력 54 | print "\n\t**********[ 사용자 선택 결과 ]**********" 55 | print "\t인터페이스 :", interface 56 | print "\t패킷 종류 :", packet 57 | print "\t[이 코드에서는 활용 안 함] 감지할 인지 범위 :", err_chk_range 58 | print "\t[이 코드에서는 활용 안 함] 기록할 로그 종류 선택 번호 :", log_type 59 | print "\t에러 종류와 상태 :" 60 | print "\t" + ("="*40) 61 | 62 | # 인터페이스별 상태 데이터 추출 63 | for (interface_name, interface_data) in get_interface_data_list(interface) : 64 | status_info = get_status(interface_data, packet, err_type) # 각 인터페이스의 에러 코드별 상태 정보 조회 65 | print "\t%s" % interface_name 66 | print "\t"+("-"*40) 67 | # 선택한 에러 종류로부터 추출한 상태 데이터 출력 68 | for status_err_type in status_info.keys() : 69 | print "\t%s\t%d" % (status_err_type, status_info[status_err_type]) 70 | print "\t"+("*"*40) 71 | -------------------------------------------------------------------------------- /7장/7.2 스마트 로그 수집기/7.2.2 인터페이스 감지/check_interface_pk_monitoring.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from check_interface_pk import get_user_input 5 | from check_interface_pk import get_interface_data_list 6 | from check_interface_pk import get_status 7 | from time import sleep 8 | from cli import cli 9 | import sys 10 | import time 11 | import os 12 | 13 | def monitoring(interface, packet, err_type, err_chk_range, log_type): # 특정 interface, 패킷 타입, 에러 코드 타입으로 얻은 상태 값이 변화하는지 모니터링 14 | past_status_list = {} 15 | while True : 16 | alert_list = [] 17 | interface_data_list = get_interface_data_list(interface) 18 | for (interface_name, interface_data) in interface_data_list : 19 | current_status = get_status(interface_data, packet, err_type) 20 | 21 | # 맨 처음 실행했을 때는 과거 데이터가 없으므로 현재 데이터로 대체 22 | past_status_exist = False 23 | for key in past_status_list.keys() : # past_status_list에서 키가 인터페이스 이름인 데이터가 적재된 적이 있는지 확인 24 | if key == interface_name : 25 | past_status_exist = True 26 | if past_status_exist == False : # 과거 데이터가 없으면 현재 데이터로 대체 27 | past_status_list[interface_name] = current_status 28 | 29 | # 현재 상태(current_status)와 과거 상태(past_status)를 비교해서 상태 값 변화를 확인 30 | past_status = past_status_list[interface_name] 31 | for err_key in current_status : # current_status는 {에러 코드:상태 값}을 포함합니다. 32 | current = current_status[err_key] # 현재 상태 값 33 | past = past_status[err_key] # 과거 상태 값 34 | gap = current - past # 현재와 과거의 상태 값 변화 확인 35 | if gap >= err_chk_range : # 상태 변화가 지정한 값보다 큰지 확인 36 | alert_list.append((interface_name, err_key, gap, past, current)) # 문제가 되는 에러 코드 확인 -> alert_list에 문제가 되는 내용 적재 37 | past_status_list[interface_name] = current_status # 과거/현재 데이터를 비교한 다음에는 현재 데이터를 과거 데이터로 변경 38 | 39 | # 문제가 되는 에러 코드가 있다면 상태 변화를 화면에 출력하고 로그 작성 40 | if len(alert_list) > 0: 41 | print "\n*********************[상태 변화]*********************" 42 | for (interface_name, err_key, gap, past, current) in alert_list : 43 | print "[%s] %s : %i 만큼 변화하였습니다. (%i->%i)" % ( 44 | interface_name, err_key, gap, past, current) 45 | if len(alert_list) > 0: 46 | print "-"*55 47 | write_logs(log_type, interface) 48 | 49 | sys.stdout.write ("...") 50 | sys.stdout.flush() 51 | sleep(5) 52 | 53 | def write_file(default_log_name, data) : # 로그 파일을 디렉터리별로 작성하는 함수입니다. 인자인 default_log_name은 명령어 종류가 넘어옵니다. 54 | now = time.localtime() 55 | dir_path = "/bootflash/%s" % default_log_name # bootflash 하위에 디렉터리를 작성합니다. 56 | if os.path.isdir(dir_path) == False : 57 | os.mkdir(dir_path) 58 | str_date = "%04d%02d%02d_%02d%02d%02d" % ( 59 | now.tm_year, now.tm_mon, now.tm_mday,now.tm_hour, now.tm_min, now.tm_sec) 60 | log_name = "/bootflash/%s/%s_%s.log" % ( 61 | default_log_name, default_log_name, str_date) # 날짜, 시각을 포함한 파일을 생성합니다. 62 | 63 | log_file = open(log_name, "w") 64 | log_file.write(data) 65 | log_file.close() 66 | print "작성된 로그 :", log_name # 로그 작성이 완료되면 파일 경로를 출력. 67 | 68 | def write_logs(log_type, interface) : # 사용자가 선택한 타입의 로그 작성 69 | if log_type == 'a' or log_type == "d" : 70 | write_file("sh_int_ethernet", cli("show interface ethernet %s" % interface)) 71 | if log_type == 'b'or log_type == "d" : 72 | write_file("sh_int_ethernet_detail", 73 | cli("show interface ethernet %s transceiver details" % interface)) 74 | if log_type == 'c' or log_type == "d" : 75 | write_file("sh_tech_support_pktmgr", cli("show tech-support pktmgr")) 76 | 77 | if __name__ == "__main__": 78 | (interface, packet, err_type, err_chk_range, log_type) = get_user_input() 79 | monitoring(interface, packet, err_type, err_chk_range, log_type) 80 | -------------------------------------------------------------------------------- /7장/7.2 스마트 로그 수집기/7.2.2 인터페이스 감지/check_interface_ui.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | def get_user_input() : 5 | interface = raw_input("1. 감지하고자 하는 인터페이스를 입력하세요 (예 : 1/1 , 1/1-10) : ") 6 | 7 | print "\n\t*************[ 패킷 종류 ]***************" 8 | print "\t\ta. RX\t\tb. TX\t\t" 9 | print "\t"+("*"*40) + "\n" 10 | packet = raw_input("2. 감지하고자 하는 패킷 종류를 선택하세요 [a/b]: " ) 11 | 12 | RX_ERR = ["jumbo packets","storm suppression packets","runts","giants", 13 | "CRC", "no buffer", "input error", "short frame", "overrun", 14 | "underrun", "ignored", "watchdog", "bad etype drop", "bad proto drop", 15 | "if down drop", "input with dribble", "input discard", "Rx pause" ] 16 | TX_ERR = ["jumbo packets","output error", "collision", "deferred", "late collision", 17 | "lost carrier", "no carrier", "babble ", "output discard", "Tx pause" ] 18 | 19 | if packet == "a": 20 | packet = "RX" 21 | error_kind_list = RX_ERR 22 | else : 23 | packet = "TX" 24 | error_kind_list = TX_ERR 25 | 26 | print "\n\t*************[ 에러 종류 ]***************" 27 | for index, err_code in enumerate(error_kind_list) : 28 | print "\t\t%d. %s" % ((index + 1), err_code) 29 | print "\t\t%d. all" % (index + 2) 30 | print "\t"+("*"*40) + "\n" 31 | 32 | index = input("3. 감지하고자 하는 에러 종류를 선택하세요 : ") 33 | while (index < 1 or index > len(error_kind_list) + 1) : 34 | print ("잘못 입력하셨습니다") 35 | index = input("3. 감지하고자 하는 에러 종류를 선택하세요 : ") 36 | 37 | if index <= len(error_kind_list) : 38 | err_type = error_kind_list[index - 1] # 에러 코드 리스트 중 1개 코드 선택 39 | else : 40 | err_type = error_kind_list # 모든 에러 코드 리스트 선택 41 | 42 | err_chk_range = input("\n4. 감지할 인지 범위를 입력하세요 (예 : 1, 10, 100) : ") 43 | 44 | print "\n\t********[ 에러가 감지됐을 때 기록할 로그 종류 ]*********" 45 | print "\t\ta. show interface ethernet %s" % interface 46 | print "\t\tb. show interface ethernet %s transceiver details" % interface 47 | print "\t\tc. show tech-support pktmgr" 48 | print "\t\td. All" 49 | print "\t"+("*"*50) + "\n" 50 | log_type = raw_input("5. 에러가 감지됐을 때 기록할 로그를 선택하세요 [d]: " ) 51 | if log_type != "a" and log_type != "b" and log_type != "c": 52 | log_type = "d" 53 | 54 | return (interface, packet, err_type, err_chk_range, log_type) 55 | 56 | if __name__ == "__main__": 57 | (interface, packet, err_type, err_chk_range, log_type) = get_user_input() 58 | print "\n\t******[ 사용자 선택 결과 ]******" 59 | print "\t인터페이스 :", interface 60 | print "\t패킷 종류 :", packet 61 | print "\t감지할 인지 범위 :", err_chk_range 62 | print "\t기록할 로그 종류 선택 번호 :", log_type 63 | print "\t감지할 에러 종류 :", err_type 64 | -------------------------------------------------------------------------------- /7장/7.2 스마트 로그 수집기/7.2.3 캡쳐 툴/ethanalyzer_monitoring.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from cli import cli 5 | from ethanalyzer import * 6 | import threading 7 | import time 8 | from datetime import datetime 9 | 10 | log_index_date = datetime.today() 11 | stop_ethanalyzer=False 12 | def check_log(check_word) : # 시스템 로그에서 특정 단어를 찾습니다. 13 | global log_index_date 14 | ret = cli("show logging log | include '%s'" % check_word) 15 | ret = ret.strip() 16 | lines = [] 17 | if ret == "" : 18 | return lines 19 | for line in ret.split("\n"): 20 | try : 21 | date_str = line[0:20] 22 | log_date = datetime.strptime(date_str, "%Y %b %d %H:%M:%S") 23 | if log_index_date < log_date : 24 | lines.append(line) 25 | except : 26 | continue 27 | log_index_date = datetime.today() 28 | return lines 29 | 30 | def write_syslog(check_word, log) : # 시스템 로그 작성 31 | log = "%s 로그가 발생해서 ethanalyzer를 종료합니다." % check_word 32 | print log 33 | cli("logit [Ethanalyzer] %s has been detected. - %s" % (check_word, log)) 34 | 35 | def remake_cmd_pcap_name(cmd, is_before) : 36 | # ethanalyzer 프로세스 실행 명령어에서 pcap 파일명을 바꾸어 반환 37 | pcap_index_start = cmd.find("write ") + 6 # 명령어 내용 중 "write " 뒤에서부터, 38 | pcap_index_end = cmd.find(".pcap") # ".pcap" 사이의 값이 파일명입니다. 39 | pcap_name = cmd[pcap_index_start : pcap_index_end] 40 | if is_before : 41 | return "%s%s_before.pcap"%(cmd[:pcap_index_start], pcap_name) 42 | else : 43 | return "%s%s_after.pcap"%(cmd[:pcap_index_start], pcap_name) 44 | 45 | class EthanalyzerThread(threading.Thread): # 덤프를 작성하는 클래스 46 | cmd = "" 47 | def run(self) : 48 | while not stop_ethanalyzer : # stop_ethanalyzer가 True로 설정되지 않으면 반복 49 | cli(self.cmd) 50 | time.sleep(0.01) 51 | 52 | def monitoring_log(cmd, check_time) : # 로그를 모니터링해서 수행할 동작을 정의한 함수 53 | global stop_ethanalyzer 54 | while True : 55 | log_list = check_log(check_word) 56 | if len(log_list) > 0 : 57 | stop_ethanalyzer= True # EthanalyzerThread의 동작을 중지시킵니다. 58 | print "로그가 발견되어 2차 실행 되는 ethanalyzer 입니다." 59 | cmd = remake_cmd_pcap_name(cmd, False) 60 | print "="*80,"\n",cmd 61 | cli(cmd) # 저장되는 이름에 after를 붙여서 저장 62 | log = log_list[len(log_list)-1] 63 | write_syslog(check_word, log) 64 | break 65 | time.sleep(check_time) 66 | 67 | if __name__ == "__main__": 68 | check_word = "" 69 | check_time = 1 70 | while True : 71 | # 로그에서 모니터링할 내용을 입력받습니다. 72 | check_word = raw_input("로그에서 모니터링할 내용을 입력하세요 : ") 73 | try : 74 | # 모니터링 주기를 입력받습니다. 75 | check_time = input("로그를 모니터링할 주기를 입력하세요 [10초] : ") 76 | except : 77 | check_time = 10 78 | if check_word != "": 79 | break 80 | disk_size = avail_disk_size() 81 | if avail_disk_size() < 1035 : 82 | print "\t현재 여유 공간 :", disk_size, "M" 83 | print "여유 공간이 1035M(여유공간 1024M와 ethanalyzer파일 11M) 미만으로 종료합니다." 84 | else : 85 | # 사용자의 입력을 받아 pcap 작성 명령어를 만듭니다. 86 | write_file_yn = get_user_input_file_write() # ethanalyzer 모듈의 get_user_input_file_write 함수 87 | filter_str = get_user_input_filter(write_file_yn) # ethanalyzer 모듈의 get_user_input_filter 함수 88 | cmd = get_cmd(write_file_yn, filter_str) # ethanalyzer 모듈의 get_cmd 함수 89 | if write_file_yn : 90 | print "1차 실행 명령어는 다음과 같습니다. 로그가 발생할 때까지 덮어 쓰기를 실행합니다." 91 | t = EthanalyzerThread() 92 | t.cmd = remake_cmd_pcap_name(cmd, True) 93 | print "="*80,"\n",t.cmd 94 | t.start() 95 | time.sleep(1) 96 | 97 | # 로그 모니터링 98 | monitoring_log(cmd, check_time) 99 | else : 100 | print "선택한 옵션이 포함된 ethanalyzer 실행 명령어는 다음과 같습니다." 101 | print cmd 102 | -------------------------------------------------------------------------------- /7장/7.2 스마트 로그 수집기/7.2.3 캡쳐 툴/tcpdump_monitoring.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from cli import cli 5 | from tcpdump import * 6 | import threading 7 | import time 8 | from datetime import datetime 9 | 10 | log_index_date = datetime.today() 11 | def check_log(check_word) : # 시스템 로그에서 특정 단어를 찾습니다. 12 | global log_index_date 13 | ret = cli("show logging log | include '%s'" % check_word) # 명령어로 로그 조회 14 | ret = ret.strip() 15 | lines = [] 16 | if ret == "" : 17 | return lines 18 | for line in ret.split("\n"): 19 | try : 20 | date_str = line[0:20] 21 | log_date = datetime.strptime(date_str, "%Y %b %d %H:%M:%S") # 조회된 로그 날짜 22 | if log_index_date < log_date : # 최신 로그만 모니터링 대상입니다. 23 | lines.append(line) 24 | except : 25 | continue 26 | log_index_date = datetime.today() 27 | return lines 28 | 29 | def write_syslog(check_word, log, wait_kill_time) : 30 | # 시스템 로그 작성 31 | log = "%s 로그가 발생해서 %d분 후 tcpdump를 종료합니다." % (check_word, wait_kill_time) 32 | print log 33 | cli("logit [tcpdump] %s has been detected. - %s" % (check_word, log)) 34 | 35 | def kill_tcpdump() : # TCP 덤프 작성 프로세스 중지 36 | ret = exec_bash("ps -ef | grep tcpdump") # tcpdump 프로세스를 조회 37 | lines = ret.split("\n") 38 | for line in lines : 39 | if line.find("grep tcpdump") >= 0 : # grep tcpdump 명령 실행으로 나타난 프로세스는 제외 40 | continue 41 | if line.find(".py") >= 0 : # 파이썬 코드 실행으로 나타난 프로세스는 제외 42 | continue 43 | if line.find("tcpdump ") >= 0 : 44 | pid = line.split()[1] 45 | exec_bash("kill -9 %s" % pid) # 동작 중인 프로세스를 중지하는 명령어 46 | 47 | class TCPThread(threading.Thread): # TCP 덤프를 작성하는 클래스 48 | cmd = "" 49 | def run(self) : 50 | exec_bash(self.cmd) # tcpdump.py의 exec_bash 이용 51 | 52 | if __name__ == "__main__": 53 | # 로그에서 모니터링할 내용을 입력받습니다. 54 | check_word = "" 55 | while True : 56 | check_word = raw_input("로그에서 모니터링할 내용을 입력하세요 : ") 57 | if check_word != "" : 58 | break 59 | 60 | # 모니터링할 내용이 검출됐을 때 tcpdump 프로세스를 중단할 대기 시간을 입력받습니다. 61 | wait_kill_time = 1 62 | try : 63 | wait_kill_time = input( 64 | "모니터링 로그가 발생한 이후로 로그를 더 수집할 기간(분)을 입력하십시오 [1] : ") 65 | except : 66 | wait_kill_time = 1 67 | 68 | # 사용자 입력을 받아 tcpdump 명령어를 만듭니다. 69 | (size_pcap, count_pcap) = get_user_input_size() 70 | if size_pcap > 0 and count_pcap > 0 : 71 | interface = get_user_input_interface() 72 | (filter_name, filter_option) = get_user_input_filter() 73 | cmd = get_cmd(size_pcap, count_pcap, interface, filter_name, filter_option) 74 | print "실행 명령어 :", cmd 75 | t = TCPThread() 76 | t.cmd = cmd # 조합한 명령어(cmd)를 스레드 클래스에 지정 77 | t.start() # TCP 덤프 수집 작업을 스레드에 맡김(스레드가 실행될 때 스레드가 명령어(cmd)를 실행시킵니다.) 78 | 79 | # 로그 모니터링 80 | log = "" 81 | while True : 82 | log_list = check_log(check_word) 83 | if len(log_list) > 0 : # 검출된 로그 내용이 있는지 확인 84 | log = log_list[len(log_list)-1] # 검출된 로그 리스트 중 최신 로그를 log 변수에 지정 85 | break # 모니터링 중지 86 | time.sleep(10) 87 | write_syslog(check_word, log, wait_kill_time) # 시스템 로그 작성 88 | time.sleep(wait_kill_time * 60) # 덤프 작성 중지까지 대기 89 | kill_tcpdump() # 덤프 작성 중지 90 | -------------------------------------------------------------------------------- /7장/7.3 유용한 기능/7.3.1 메일/send_config.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from smtp import send_mail 5 | from ucsm_backup_n_import import ucsm_config_backup 6 | from ucsm_backup_n_import import ucsm_config_import 7 | import time 8 | import os 9 | 10 | def get_config_file(file_dir, ucsm_ip) : 11 | # 환경 파일 경로를 가져옵니다. 12 | now = time.localtime() 13 | time_str = "%04d%02d%02d_%02d%02d%02d" % ( 14 | now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec) 15 | 16 | original_name = ucsm_ip+"_"+"config-all.xml" 17 | new_name = time_str + "_" + original_name 18 | 19 | original_path = file_dir + "/" + original_name 20 | new_path = file_dir + "/" + new_name 21 | os.rename(original_path, new_path) 22 | return new_path 23 | 24 | if __name__ == "__main__": 25 | ucsm_ip = raw_input("백업 또는 복원할 UCS 매니저의 IP를 입력해 주세요 : ") 26 | print "\n"+"=-"*30 27 | print "1. 설정 파일 백업" 28 | print "2. 설정 파일 복원" 29 | print "3. 설정 파일 백업 및 메일 전송" 30 | print "-="*30+"\n" 31 | 32 | while True: 33 | select = raw_input("작업을 선택해 주세요 : ") 34 | if select =='1': 35 | ucsm_config_backup(ucsm_ip,'ucspe','ucspe') 36 | break 37 | elif select =='2': 38 | ucsm_config_import(ucsm_ip,'ucspe','ucspe') 39 | break 40 | elif select =='3': 41 | host = 42 | port = 465 # SMTP 포트 : SSL로 보낼 때는 465, TLS로 보내려면 587 43 | login_id = 44 | login_pw = 45 | 46 | sender_addr = <보내는 사람 메일 주소> 47 | reciever_addr = raw_input("받는 사람 메일 주소를 입력해 주세요 :") 48 | subject = "[알림] %s의 설정 백업 파일이 도착했습니다." % ucsm_ip 49 | 50 | ucsm_config_backup(ucsm_ip,'ucspe','ucspe') 51 | 52 | config_file = get_config_file("c:/py/config", ucsm_ip) 53 | attach_list = [] 54 | attach_list.append(config_file) 55 | send_mail(host, port, login_id, login_pw, 56 | sender_addr, reciever_addr, subject, attach_list) 57 | print "%s를 %s로 전송했습니다." %(config_file,reciever_addr) 58 | os.remove(config_file) 59 | break 60 | elif select =='exit': 61 | break 62 | else: 63 | print "1-3이 아닌 값입니다. 프로그램을 종료하시려면 exit를 입력하세요 " 64 | continue 65 | -------------------------------------------------------------------------------- /7장/7.3 유용한 기능/7.3.1 메일/smtp.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import smtplib 5 | from email.MIMEMultipart import MIMEMultipart 6 | from email.MIMEBase import MIMEBase 7 | from email import Encoders 8 | import os 9 | import re 10 | 11 | def send_mail(host, port, login_id, login_pw, sender_addr, reciever_addr, subject, attach_list) : 12 | # 메일 메시지(msg) 작성 13 | msg = MIMEMultipart() 14 | msg["Subject"] = subject 15 | msg["From"] = sender_addr 16 | msg["To"] = reciever_addr 17 | 18 | # 메일 메시지(msg)에 첨부 파일 추가 19 | for file_path in attach_list: 20 | part = MIMEBase('application', 'octet-stream') 21 | part.set_payload(open(file_path, 'rb').read()) 22 | Encoders.encode_base64(part) 23 | 24 | split_path = os.path.split(file_path) 25 | file_name = split_path[len(split_path) - 1] 26 | part.add_header('Content-Disposition', 'attachment; filename="%s"' % file_name) 27 | msg.attach(part) 28 | 29 | # 메일 전송 30 | smtp_svr = smtplib.SMTP_SSL(host, port) # 서버/포트 설정(SSL일 때 SMTP_SSL() 함수 사용) 31 | smtp_svr.login(login_id, login_pw) # 메일 서버에 로그인 32 | smtp_svr.sendmail(sender_addr, reciever_addr, msg.as_string()) # 메일 전송 33 | smtp_svr.quit() # 메일 서버와 접속 종료 34 | 35 | def get_attach_list(file_dir, file_pattern) : # file_dir은 소스 코드와 같은 경로 36 | file_names = os.listdir(file_dir) 37 | attach_list = [] 38 | for file_name in file_names : 39 | if os.path.isfile(file_name) : # file_dir 하위의 파일 리스트를 확인 40 | match_file = re.match(file_pattern, file_name) 41 | if match_file == None : # 정규식으로 파일명 패턴을 확인 42 | continue 43 | attach_list.append(file_dir + "/" + file_name) # 패턴에 맞는 파일명만 리스트에 추가 44 | return attach_list 45 | 46 | if __name__ == "__main__": 47 | host = 48 | port = 465 # SMTP 포트 : SSL로 보낼 때는 465, TLS로 보내려면 587 49 | login_id = 50 | login_pw = 51 | 52 | sender_addr = <보내는 사람 메일 주소> 53 | reciever_addr = <받는 사람 메일 주소> 54 | subject = "[알림] 메일이 도착했습니다." 55 | 56 | attach_list = get_attach_list(".", ".*sample.*\.xml") 57 | send_mail(host, port, login_id, login_pw, sender_addr, reciever_addr, subject, attach_list) 58 | print reciever_addr, "로 메일을 전송했습니다." 59 | print "첨부 파일 :", attach_list 60 | -------------------------------------------------------------------------------- /7장/7.3 유용한 기능/7.3.1 메일/ucsm_backup_n_import.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from ucsmsdk.ucshandle import UcsHandle 5 | from ucsmsdk.utils.ucsbackup import backup_ucs 6 | from ucsmsdk.utils.ucsbackup import import_ucs_backup 7 | 8 | def ucsm_config_backup(ucsm_ip,user,password): 9 | handle = UcsHandle(ucsm_ip,user,password) 10 | handle.login() 11 | backup_ucs(handle,backup_type="config-all", file_dir=r"C:\py\config",file_name=ucsm_ip+"_"+"config-all.xml") 12 | handle.logout() 13 | 14 | def ucsm_config_import(ucsm_ip,user,password): 15 | handle = UcsHandle(ucsm_ip,user,password) 16 | handle.login() 17 | import_ucs_backup(handle, file_dir=r"C:\py\config",file_name=ucsm_ip+"_"+"config-all.xml") 18 | handle.logout() 19 | 20 | if __name__ == "__main__": 21 | ucsm_ip = raw_input("백업 또는 복원할 UCS 매니저의 IP를 입력해 주세요 : ") 22 | print "\n"+"=-"*30 23 | print "1. 설정 파일 백업" 24 | print "2. 설정 파일 복원" 25 | print "-="*30+"\n" 26 | 27 | while True: 28 | select = raw_input("작업을 선택해 주세요 : ") 29 | if select =='1': 30 | ucsm_config_backup(ucsm_ip,'ucspe','ucspe') 31 | break 32 | elif select =='2': 33 | ucsm_config_import(ucsm_ip,'ucspe','ucspe') 34 | break 35 | elif select =='exit': 36 | break 37 | else: 38 | print "1 또는 2가 아닌 값입니다. 프로그램을 종료하시려면 exit를 입력하세요 " 39 | continue 40 | -------------------------------------------------------------------------------- /7장/7.3 유용한 기능/7.3.1 메일/주의사항.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/7장/7.3 유용한 기능/7.3.1 메일/주의사항.txt -------------------------------------------------------------------------------- /7장/7.3 유용한 기능/7.3.2 엑셀 차트/exec_ipmi_any_platform.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from subprocess import * 5 | import platform 6 | 7 | def get_ipmi(args): 8 | if platform.system() == "Windows" : 9 | cmd = "ipmiutil " + args 10 | else : 11 | cmd = "ipmitool " + args 12 | p = Popen(cmd, shell=True, stdout=PIPE) 13 | (ret, err) = p.communicate() 14 | return ret 15 | 16 | def get_server_input() : 17 | ip = raw_input ("서버 관리 모듈 IP를 입력하세요 :") 18 | id = raw_input ("관리자 ID를 입력하세요 :") 19 | pw = raw_input ("암호를 입력하세요 :") 20 | if platform.system() == "Windows" : 21 | args = "-N %s -J 3 -U %s -P %s" % (ip, id, pw) 22 | else : 23 | args = "-I lanplus -H " + ip + " -U " + id + " -P " +pw 24 | return (args, ip, id, pw) 25 | 26 | if __name__ == "__main__": 27 | (args, ip, id, pw) = get_server_input() 28 | 29 | print get_ipmi( args + ' fru print | grep "Product Name"') 30 | print get_ipmi( args + ' fru print | grep "Chassis Serial"') 31 | -------------------------------------------------------------------------------- /7장/7.3 유용한 기능/7.3.2 엑셀 차트/fan_monitoring_chart.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from fan_re_any_platform import * 5 | import time 6 | import os 7 | import shutil 8 | from xlsx_chart import write_chart_xlsx 9 | 10 | def convert_number_list(value_list) : 11 | num_list = [] 12 | for val in value_list : 13 | if val == "na" : 14 | num_list.append(0) 15 | else : 16 | num_list.append(float(val)) 17 | return num_list 18 | 19 | if __name__ == "__main__": 20 | (args, ip, id, pw) = get_server_input() 21 | (count, sleep_time) = get_input() 22 | 23 | file_dir = "./fan" 24 | if not os.path.isdir(file_dir) : 25 | os.mkdir(file_dir) 26 | 27 | print "팬과 온도 상태 모니터링을 시작합니다.\n" 28 | c = 1 29 | file_path = "" 30 | file_separator = 10 31 | data = [] 32 | while c <= count or count == 0: 33 | # 팬 정보 (상태 키, 상태 값)에 대한 리스트 추출 34 | (key_list, value_list) = check_fan(args) 35 | 36 | # 파일 분할 기준값에 따라 파일 이름을 계산하며 파일 기본 이름은 현재 시각을 포함 37 | if c % file_separator == 1 : 38 | now = time.localtime() 39 | file_path = "%s/%04d%02d%02d_%02d%02d%02d_%s_FanLog.xlsx" % ( 40 | file_dir, now.tm_year, now.tm_mon, now.tm_mday, 41 | now.tm_hour, now.tm_min, now.tm_sec, ip) 42 | 43 | print "팬과 온도 상태 기록 파일 생성 : %s" % file_path 44 | print "[%d회] 팬과 온도 상태 기록 중..." % c 45 | 46 | # 파일 분할 기준값에 따라 새로운 파일에 작성하게 되면 헤더를 추가함 47 | if c % file_separator == 1 : 48 | data = [] 49 | data.append(key_list) 50 | 51 | # 상태 값을 추가 52 | num_value_list = convert_number_list(value_list) 53 | data.append(num_value_list) 54 | 55 | # 엑셀 파일에 차트를 포함하여 저장 56 | write_chart_xlsx(file_path, data) 57 | 58 | time.sleep(sleep_time) 59 | c = c + 1 60 | 61 | print "%d회 팬과 온도 상태 모니터링을 모두 완료하였습니다." % count 62 | -------------------------------------------------------------------------------- /7장/7.3 유용한 기능/7.3.2 엑셀 차트/fan_re_any_platform.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | # exec_ipmi 대신 exec_ipmi_any_platform 임포트 5 | from exec_ipmi_any_platform import get_ipmi 6 | from exec_ipmi_any_platform import get_server_input 7 | import time 8 | import re 9 | import platform 10 | 11 | def check_fan(args) : 12 | if platform.system() == "Windows" : # 윈도에서 실행할 때 13 | ipmi_result = get_ipmi(" sensor %s" % args) # 명령어 수정 14 | else : 15 | ipmi_result = get_ipmi("%s sensor" % args) 16 | 17 | # 찾으려는 데이터는 "FAN숫자_SPEED"로 시작하는 문자열입니다. 18 | # 찾은 데이터를 리스트로 가져옵니다. 19 | (key_list, value_list) = get_data_list("FAN[1-9]_SPEED.*", ipmi_result) 20 | 21 | # 찾으려는 데이터는 "FAN숫자_TACH"로 시작하는 문자열입니다. 22 | (key_list2, value_list2) = get_data_list("FAN[1-9]_TACH.*",ipmi_result) 23 | 24 | # 찾으려는 데이터는 "PSU숫자_TEMP"로 시작하는 문자열입니다. 25 | (key_list3, value_list3) = get_data_list("PSU[1-9]_TEMP.*",ipmi_result) 26 | 27 | # 찾으려는 데이터는 "FP_TEMP_SENSOR"로 시작하는 문자열입니다. 28 | (key_list4, value_list4) = get_data_list("FP_TEMP_SENSOR.*",ipmi_result) 29 | 30 | # 찾은 데이터를 리스트로 가져와서 key_list와 합칩니다. 31 | key_list = key_list + key_list2 + key_list3 + key_list4 32 | value_list = value_list + value_list2 + value_list3 + value_list4 33 | 34 | return (key_list, value_list) 35 | 36 | def get_data_list(pattern_str, source_data) : 37 | str_list = re.findall(pattern_str, source_data) 38 | key_list = [] 39 | value_list = [] 40 | for str in str_list : 41 | # 윈도에서 실행할 때와 분리하여 처리하는 코드로 수정 시작 42 | if str == "" : 43 | continue 44 | if platform.system() == "Windows" : # 윈도에서 실행할 때 45 | key = str[0 : str.find("=") ].strip() 46 | value = str[str.find("=") + 1 : len(str)].strip() 47 | array = key.split() 48 | key = array[len(array) - 1] 49 | array = value.split() 50 | value = array[2] 51 | else : 52 | array = str.split("|") # ipmitool에서 반환한 데이터는"|"로 데이터 열이 구분돼 있습니다. 53 | if len(array) < 2 : # 0번째 열이 상태 키, 1번째 열이 상태에 대한 값입니다. 54 | return "" 55 | key = array[0].strip() 56 | value = array[1].strip() 57 | # 여기까지 수정 58 | key_list.append(key) 59 | value_list.append(value) 60 | 61 | return (key_list, value_list) # (상태 키 리스트, 상태 값 리스트)의 튜플로 반환합니다. 62 | 63 | def get_input() : 64 | count = input("몇 회 체크하시겠습니까? [무한대 체크는 0]:") 65 | if count < 0 : 66 | count = 0 67 | 68 | sleep_time = 10 69 | sleep_time = input("몇 초 단위로 체크하시겠습니까? [최소 30]:") 70 | 71 | if sleep_time < 30 : 72 | sleep_time = 30 73 | 74 | return (count, sleep_time) 75 | 76 | if __name__ == "__main__": 77 | (args, ip, id, pw) = get_server_input() 78 | (count, sleep_time) = get_input() 79 | c = 1 80 | while c <= count or count == 0: 81 | print "[%d회] 팬과 온도 상태 조회 중 ..." % c 82 | # 팬 정보 (상태 키, 상태 값)에 대한 리스트 추출 83 | (key_list, value_list) = check_fan(args) 84 | 85 | # 첫 회에만 키 리스트를 출력하고, 그다음에는 상태 값에 관한 리스트를 출력 86 | if c == 1 : 87 | print key_list 88 | print value_list 89 | 90 | # 입력받은 대기 시간만큼 sleep 91 | time.sleep(sleep_time) 92 | c = c + 1 93 | -------------------------------------------------------------------------------- /7장/7.3 유용한 기능/7.3.2 엑셀 차트/xlsx_chart.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from xlsxwriter.workbook import Workbook 5 | 6 | def get_fan_logs() : 7 | data = [ 8 | ['Count', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N'], 9 | [1, 42, 531, 424, 424, 424, 424, 424,424,424,424,6, 0, 27], 10 | [2, 42, 531, 424, 424, 424,17, 424,424,424,424,6, 0, 27], 11 | [3, 42, 531, 424, 424, 424, 424, 424,424,424,424,6, 0, 27], 12 | [4, 42, 424, 424, 424, 424,17, 424,424,424,424,6, 0, 27], 13 | [5, 42, 531, 424, 424, 424,17, 424,424,424,424,6, 0, 27], 14 | [6, 42, 424, 424, 424, 424,17, 424,424,424,424,6, 0, 27], 15 | [7, 42, 424, 424, 424, 424, 424, 424,424,424,424,6, 0, 27], 16 | [8, 42, 531, 424, 424, 424, 424, 424,424,424,424,6, 0, 27], 17 | [9, 42, 424, 424, 424, 424,17, 424,424,424,424,6, 0, 28], 18 | [10, 42, 424, 424, 424, 424, 424, 424,424,424,424,6, 0, 28] 19 | ] 20 | return data 21 | 22 | def write_chart_xlsx(file_path, data) : 23 | workbook = Workbook(file_path) # 엑셀 파일 생성 24 | worksheet = workbook.add_worksheet() 25 | 26 | chart = workbook.add_chart({'type': 'line'}) # 엑셀 파일에 라인 차트 추가 27 | 28 | i = 0 29 | while i < len(data) : # A1행부터 A12행(11줄)까지 데이터 작성 30 | worksheet.write_row('A%i'%(i+1), data[i]) # 행마다 A~N열까지 데이터 리스트 작성 31 | i = i + 1 32 | 33 | # 엑셀 파일에 추가한 데이터를 바탕으로 차트 작성 34 | XLS_COL_NUM = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q'] 35 | i = 1 36 | while i < len(data[0]) : 37 | chart.add_series({ 38 | 'name' : 'Sheet1!$%s$1' % XLS_COL_NUM[i], 39 | 'categories': ('=Sheet1!$A$2:$A$%d'% len(data)), 40 | 'values': '=Sheet1!$%s$2:$%s$%d' % (XLS_COL_NUM[i], XLS_COL_NUM[i], len(data)), 41 | 'marker': {'type': 'automatic'}, 42 | }) 43 | i = i + 1 44 | 45 | # 차트 제목 설정 (X축 이름) 46 | chart.set_x_axis({ 47 | 'name': 'Sheet1!$A$1' 48 | }) 49 | 50 | worksheet.insert_chart('E13', chart) 51 | workbook.close() # 닫기 52 | 53 | if __name__ == "__main__": 54 | data = get_fan_logs() 55 | write_chart_xlsx('sample.xlsx', data) 56 | print "샘플 차트를 작성했습니다 : sample.xlsx" 57 | -------------------------------------------------------------------------------- /7장/7.3 유용한 기능/7.3.4 구성파일 백업/a. scp_backup (원본)/scp_backup.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from syslog import syslog 5 | import pexpect 6 | import time 7 | import os 8 | 9 | def scp_backup(): 10 | now = time.localtime() 11 | cur_time= "%04d%02d%02d_%02d%02d%02d"%(now.tm_year, now.tm_mon, now.tm_mday, 12 | now.tm_hour, now.tm_min, now.tm_sec) 13 | ip= 14 | backup_name ='n9k-running-config-%s'%cur_time 15 | 16 | child = pexpect.spawn("/isan/bin/vsh") 17 | child.sendline("copy running-config scp://root@%s/%s"%(ip,backup_name)) 18 | child.expect(":") 19 | child.sendline("management\n") 20 | if not os.path.isfile("/var/home/admin/.ssh/known_hosts"): 21 | child.expect("yes") 22 | child.sendline("yes\n") 23 | child.expect("assword:") 24 | child.sendline("<암호>\n") 25 | syslog(3,"구성정보(%s)가 %s에 성공적으로 백업되었습니다"%(backup_name,ip)) 26 | 27 | if __name__ == "__main__": 28 | scp_backup() 29 | 30 | -------------------------------------------------------------------------------- /7장/7.3 유용한 기능/7.3.4 구성파일 백업/b. scp_backup (SSH)/scp_backup.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from syslog import syslog 5 | import pexpect 6 | import time 7 | import os 8 | from cli import cli 9 | 10 | now = time.localtime() 11 | cur_time= "%04d%02d%02d_%02d%02d%02d"%(now.tm_year, now.tm_mon, now.tm_mday, 12 | now.tm_hour, now.tm_min, now.tm_sec) 13 | #### 백업 시스템 정보 (정확한 정보로 수정 필요)#### 14 | id='root' 15 | pw='password' 16 | ip=<백업 서버_IP> 17 | ######################## 18 | dir_name = cli('show switchname')[:-2] 19 | backup_dir = '/var/log/'+'scp_backup_from-'+dir_name 20 | backup_name ='n9k-running-config-%s'%cur_time 21 | 22 | def exist_chk(method): 23 | try: 24 | f = open("/var/home/admin/.ssh/known_hosts",'r') 25 | data = f.read() 26 | if method=='ssh': 27 | if data.find('%s ecdsa-sha2-nistp256'%ip) == -1: 28 | return -1 29 | elif method=='scp': 30 | if data.find('%s ssh-rsa'%ip) == -1: 31 | return -1 32 | except: 33 | return -1 34 | 35 | def mkdir_backup(): 36 | cmd ="ssh %s@%s mkdir %s"%(id,ip,backup_dir) 37 | child = pexpect.spawn(cmd) 38 | if exist_chk('ssh'): 39 | child.expect("yes") 40 | child.sendline("yes\n") 41 | child.expect("assword:") 42 | child.sendline("%s\n"%pw) 43 | 44 | def scp_backup(): 45 | child = pexpect.spawn("/isan/bin/vsh") 46 | child.sendline("copy running-config scp://%s@%s/%s/%s"%(id,ip,backup_dir,backup_name)) 47 | child.expect(":") 48 | child.sendline("management\n") 49 | if exist_chk('scp'): 50 | child.expect("yes") 51 | child.sendline("yes\n") 52 | child.expect("assword:") 53 | child.sendline("%s\n"%pw) 54 | syslog(3,"구성정보(%s)가 %s에 성공적으로 백업되었습니다"%(backup_name,ip)) 55 | 56 | if __name__ == "__main__": 57 | mkdir_backup() 58 | scp_backup() 59 | -------------------------------------------------------------------------------- /7장/7.3 유용한 기능/7.3.4 구성파일 백업/b. scp_backup (SSH)/scp_backup_console.txt: -------------------------------------------------------------------------------- 1 | n9k-2(config)# event manager applet scp_backup_console 2 | n9k-2(config-applet)# event syslog pattern "Configured from vty by admin on console*" 3 | Configuration accepted successfully 4 | n9k-2(config-applet)# action 1 cli python bootflash:scripts/scp_backup.py 5 | -------------------------------------------------------------------------------- /7장/7.3 유용한 기능/7.3.4 구성파일 백업/b. scp_backup (SSH)/scp_backup_pts.txt: -------------------------------------------------------------------------------- 1 | n9k-2(config)# event manager applet scp_backup_pts 2 | n9k-2(config-applet)# event syslog pattern "Configured from vty by admin on *.*.*.*@pts*" 3 | Configuration accepted successfully 4 | n9k-2(config-applet)# action 1 cli python bootflash:scripts/scp_backup.py 5 | -------------------------------------------------------------------------------- /7장/7.3 유용한 기능/7.3.4 구성파일 백업/scp_diff.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from datetime import datetime 5 | from subprocess import Popen 6 | from subprocess import PIPE 7 | import os 8 | 9 | def get_scp_back_dir(path) : 10 | # 구성 정보가 백업된 네트워크 장비 리스트를 가져옵니다. 11 | dir_list = [] 12 | for dir_name in os.listdir(path) : 13 | if dir_name.startswith("scp_backup_from-") : 14 | dir_list.append(dir_name) 15 | dir_list.sort() 16 | return dir_list 17 | 18 | def get_scp_back_date(path) : 19 | # 백업 파일이 작성된 날짜 리스트를 가져옵니다. 20 | date_list = [] 21 | for file_name in os.listdir(path) : 22 | if file_name.find("-running-config-") : 23 | date = file_name.split("-running-config-")[1] 24 | date = date.split("_")[0] 25 | date_list.append(date) 26 | date_list = list(set(date_list)) 27 | date_list.sort() 28 | return date_list 29 | 30 | def get_file_date(f_name) : 31 | # 파일명에 포함된 날짜를 datetime 형태로 변환합니다. 32 | first_str = f_name.split()[0] 33 | str_list = first_str.split("-") 34 | date_str = str_list[len(str_list) -1] 35 | date_str = date_str[0:15] 36 | return datetime.strptime(date_str , '%Y%m%d_%H%M%S') 37 | 38 | def get_file_list(file_dir, start_date, end_date) : # 특정 날짜 구간에 작성된 구성 정보 백업 파일을 가져옵니다. 39 | file_list = os.listdir(file_dir) 40 | file_list_range = [] 41 | for f_name in file_list : 42 | file_path = file_dir + "/" + f_name 43 | create_date = get_file_date(f_name) 44 | if create_date >= start_date and create_date <= end_date : 45 | file_list_range.append(file_path) 46 | file_list_range.sort() 47 | return file_list_range 48 | 49 | def diff(file_path1, file_path2) : 50 | # diff 명령어로 두 파일을 비교합니다. 51 | cmd = "diff --context %s %s" % (file_path1, file_path2) 52 | p = Popen(cmd, shell=True, stdout=PIPE) 53 | (ret, err) = p.communicate() 54 | return ret 55 | 56 | def get_input_data() : 57 | # 백업 파일이 저장된 네트워크 장비 목록을 출력합니다. 58 | dir_path = "/var/log" 59 | dir_list = get_scp_back_dir(dir_path) 60 | 61 | print "*****[ 백업 파일이 저장된 네트워크 장비 목록 ]*****" 62 | if len(dir_list) == 0 : 63 | print "\t\t없음\n" + ("*" * 50) 64 | return None 65 | 66 | for i, dir_name in enumerate(dir_list) : 67 | print "\t%d)%s" % ((i+1), dir_name.split("scp_backup_from-")[1]) 68 | print ("*" * 50) + "\n" 69 | 70 | # 네트워크 장비 목록 중에서 비교할 장비를 선택합니다. 71 | try : 72 | select_num= input("비교할 네트워크 장비를 선택해 주세요 [1-%d]: " % len(dir_list)) 73 | if select_num <= 0 or select_num > len(dir_list) : 74 | select_num = 1 75 | dir_path = dir_path + "/" + dir_list[select_num - 1] 76 | except : 77 | dir_path = dir_path + "/" + dir_list[0] 78 | 79 | print ">>> %s가 선택되었습니다" % dir_path.split("scp_backup_from-")[1] 80 | 81 | # 백업 파일이 저장된 날짜 목록을 출력합니다. 82 | date_list = get_scp_back_date(dir_path) 83 | print "*****[ 백업 파일이 저장된 날짜 목록 ]*****" 84 | if len(date_list) == 0 : 85 | print "\t\t없음\n" + ("*" * 50) 86 | return None 87 | 88 | for i, date in enumerate(date_list) : 89 | print "\t%d)%s" % ((i+1), date) 90 | print ("*" * 50) + "\n" 91 | 92 | # 백업 파일 중 비교를 시작할 구간을 선택합니다. 93 | print "\n선택한 기간 동안의 백업 파일을 비교합니다." 94 | while True : 95 | select_num = input("시작 기간을 선택하세요 [1-%d]: " % len(date_list)) 96 | select_num2 = input("종료 기간을 선택하세요 [%d-%d]: " % (select_num, len(date_list))) 97 | select_date = date_list[select_num - 1] 98 | select_date2 = date_list[select_num2 - 1] 99 | start_date = datetime.strptime(select_date + "_000000", '%Y%m%d_%H%M%S') 100 | end_date = datetime.strptime(select_date2 + "_235959", '%Y%m%d_%H%M%S') 101 | return (dir_path, start_date, end_date) # 네트워크 장비 백업 파일과 비교할 날짜 구간을 반환합니다. 102 | 103 | if __name__ == "__main__": 104 | # 사용자 입력을 받아서, 비교할 네트워크 장비와 비교할 날짜 구간을 선택받습니다. 105 | input_data = get_input_data() 106 | 107 | # 사용자 입력을 바탕으로 파일을 비교 108 | if input_data != None : 109 | (dir_path, start_date, end_date) = input_data 110 | scp_file_list = get_file_list(dir_path, start_date, end_date) 111 | if len(scp_file_list) == 0 : 112 | print "선택한 기간 동안 백업된 파일이 없습니다." 113 | elif len(scp_file_list) == 1 : 114 | print "선택한 기간 동안 백업된 파일이 1건이어서 변경 사항을 비교할 수 없습니다." 115 | else : 116 | i = 0 117 | while i < len(scp_file_list) - 1 : 118 | cmd_result = diff(scp_file_list[i], scp_file_list [i+1]) 119 | print cmd_result 120 | print "=" * 50 121 | i = i + 1 122 | -------------------------------------------------------------------------------- /7장/7.4 예외/7.4.1. 프로세스 모니터링/cpu_load.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import threading 5 | from time import sleep 6 | 7 | def prime_factors(x): 8 | factor_list=[] 9 | div=2 10 | while div<=x: 11 | if x%div==0: # 나눗셈을 해서 자기 자신으로밖에 나누어 떨어지지 않는 경우는 소수 12 | x/=div 13 | factor_list.append(div) 14 | else: 15 | div+=1 # 나눗셈 기준값 증가 16 | return factor_list 17 | 18 | class ThreadRange ( threading.Thread ) : 19 | def run(self): 20 | for i in range(9999999): # 소수를 구하는 범위를 설정합니다. 21 | sleep(0.001) # CPU의 사용량을 조절합니다. 22 | print prime_factors(i) 23 | 24 | for i in range(5): # 스레드를 5개 생성해 CPU 사용량을 더 높입니다. 25 | ThreadRange().start() 26 | -------------------------------------------------------------------------------- /7장/7.4 예외/7.4.2 도움말/other_cpu_arg.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import argparse 5 | 6 | def arg_parser(parser) : 7 | parser.add_argument('conf',nargs=1, help='모니터링 구성 [필수 입력 항목]') 8 | parser.add_argument('--version', action='version', version='%(prog)s 1.0') 9 | print parser.parse_args() 10 | 11 | if __name__ == "__main__": 12 | parser = argparse.ArgumentParser('other_cpu.py') 13 | arg_parser(parser) 14 | if len(sys.argv) > 1 : 15 | option = sys.argv[1] 16 | if option == "conf" and os.path.exists(cfg_path) : 17 | os.remove(cfg_path) 18 | -------------------------------------------------------------------------------- /7장/cpu_load.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from multiprocessing import Pool 5 | 6 | def f(x): 7 | # Put any cpu (only) consuming operation here. I have given 1 below - 8 | while True: 9 | x * x 10 | 11 | # decide how many cpus you need to load with. 12 | no_of_cpu_to_be_consumed = 3 13 | 14 | p = Pool(processes=no_of_cpu_to_be_consumed) 15 | p.map(f, range(no_of_cpu_to_be_consumed)) 16 | -------------------------------------------------------------------------------- /부록/Install Package (PyQt, py2exe)/PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x32.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/Install Package (PyQt, py2exe)/PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x32.exe -------------------------------------------------------------------------------- /부록/Install Package (PyQt, py2exe)/py2exe-0.6.9.win32-py2.7.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/Install Package (PyQt, py2exe)/py2exe-0.6.9.win32-py2.7.exe -------------------------------------------------------------------------------- /부록/bat 파일/convert.bat: -------------------------------------------------------------------------------- 1 | C:\Python27\Lib\site-packages\PyQt4\pyuic4 "c:/py/vkvm_dialog.ui" -o "c:/py/vkvm_dialog.py" -------------------------------------------------------------------------------- /부록/bat 파일/setup.bat: -------------------------------------------------------------------------------- 1 | C:\Python27\python.exe setup.py py2exe -------------------------------------------------------------------------------- /부록/cfg 파일/environment.cfg: -------------------------------------------------------------------------------- 1 | [Environment] 2 | lang=ko -------------------------------------------------------------------------------- /부록/exe package 파일/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/blank.png -------------------------------------------------------------------------------- /부록/exe package 파일/environment.cfg: -------------------------------------------------------------------------------- 1 | [Environment] 2 | lang=ko -------------------------------------------------------------------------------- /부록/exe package 파일/green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/green.png -------------------------------------------------------------------------------- /부록/exe package 파일/grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/grey.png -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/32BitLibs/VMAPI_DLL.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/32BitLibs/VMAPI_DLL.dll -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/32BitLibs/avctKVMIO.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/32BitLibs/avctKVMIO.dll -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/32BitLibs/libVMAPI_DLL.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/32BitLibs/libVMAPI_DLL.so -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/32BitLibs/libavctKVMIO.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/32BitLibs/libavctKVMIO.so -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/VMAPI_DLL.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/VMAPI_DLL.dll -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/avctKVMIO.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/avctKVMIO.dll -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/launchkvm.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | REM ================================================ 3 | REM ================== KVM launcher ================ 4 | REM ================================================ 5 | 6 | REM Linux jars included only to be consistent, won't actually be used for this .bat file 7 | java -d64 -version > NUL 2>&1 8 | if '%errorlevel%' == '0' ( 9 | set CP=.\libs\avctKVMIOLinux32.jar;.\libs\avctKVMIOLinux64.jar;.\libs\avctKVMIOWin64.jar;.\libs\avctNuova.jar;.\libs\avctVMLinux32.jar;.\libs\avctVMLinux64.jar;.\libs\avctVMWin64.jar;.\libs\lzvcnt.jar 10 | set LIBPATH=. 11 | ) 12 | java -d32 -version > NUL 2>&1 13 | if '%errorlevel%' == '0' ( 14 | set CP=.\libs\avctKVMIOLinux32.jar;.\libs\avctKVMIOLinux64.jar;.\libs\avctKVMIOWin32.jar;.\libs\avctNuova.jar;.\libs\avctVMLinux32.jar;.\libs\avctVMLinux64.jar;.\libs\avctVMWin32.jar;.\libs\lzvcnt.jar 15 | set LIBPATH=.\32BitLibs 16 | ) 17 | 18 | SET KVML_USAGE=Usage: launchkvm.bat -u username -p password -h host_ip 19 | SET USERNAME= 20 | SET PASSWORD= 21 | SET HOST= 22 | 23 | :LOOPARGS 24 | IF "%1" == "" goto :CONTINUEON 25 | set ARG1=%1 26 | REM position to next argument with SHIFT to get the associated value 27 | SHIFT 28 | 29 | REM if there is not a second argument in a pair then show usage and exit 30 | IF "%1" == "" ( 31 | ECHO %KVML_USAGE% 32 | goto :END 33 | ) 34 | 35 | IF "%ARG1%" == "-p" ( 36 | SET PASSWORD=%1 37 | goto :NEXTARG 38 | ) 39 | 40 | IF "%ARG1%" == "-u" ( 41 | SET USERNAME=%1 42 | goto :NEXTARG 43 | ) 44 | 45 | IF "%ARG1%" == "-h" ( 46 | SET HOST=%1 47 | goto :NEXTARG 48 | ) 49 | 50 | ECHO %KVML_USAGE% 51 | goto :END 52 | 53 | :NEXTARG 54 | REM position to next argument with SHIFT 55 | SHIFT 56 | 57 | REM if no more argument continue on to rest of bat script 58 | IF "%1" == "" goto :CONTINUEON 59 | goto :LOOPARGS 60 | goto :END 61 | :CONTINUEON 62 | 63 | IF "%USERNAME%" == "" goto :LAUNCHER 64 | IF "%PASSWORD%" == "" goto :LAUNCHER 65 | IF "%HOST%" == "" goto :LAUNCHER 66 | 67 | goto :CLI 68 | 69 | :LAUNCHER 70 | java -Xms256M -Xmx512M -Djava.library.path=%LIBPATH% -classpath %CP% Launcher 71 | goto :END 72 | 73 | :CLI 74 | java -Xms256M -Xmx512M -Djava.library.path=%LIBPATH% -classpath %CP% com.avocent.nuova.kvm.Main ip=%HOST% user=%USERNAME% passwd=%PASSWORD% title="KVM on %HOST%" apcp=1 version=2 kmport=2068 vport=2068 sslv3=1 autoEof=0 tempunpw=0 aimpresent=0 power=0 vm=1 chat=1 export=1 dvr=2 statusbar=ip,un,fr,bw,kp,enc,led custom=2 75 | goto :END 76 | 77 | :END 78 | -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/launchkvm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ================================================ 3 | # ================== KVM launcher ================ 4 | # ================================================ 5 | 6 | export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH 7 | export PATH=$PATH:.:./libs/avctVMWin32.jar:./libs/avctKVMIOWin32.jar 8 | export CP=./libs/avctKVMIOLinux32.jar:./libs/avctKVMIOLinux64.jar:./libs/avctKVMIOWin32.jar:./libs/avctNuova.jar:./libs/avctVMLinux32.jar:./libs/avctVMLinux64.jar:./libs/avctVMWin32.jar:./libs/lzvcnt.jar 9 | 10 | USERNAME= 11 | PASSWORD= 12 | HOST= 13 | 14 | usage() 15 | { 16 | echo "Usage: $0 -u username -p password -h host_ip" 17 | } 18 | 19 | while getopts "u:p:h:" opt 20 | do 21 | case "$opt" in 22 | u) USERNAME="$OPTARG";; 23 | p) PASSWORD="$OPTARG";; 24 | h) HOST="$OPTARG";; 25 | \?) usage;; 26 | *) usage;; 27 | esac 28 | done 29 | 30 | JAVA_VERSION=`java -version 2>&1 | grep "java version" | awk '{ print substr($3, 2, length($3)-2); }'` 31 | JAVA_MAJOR=`echo $JAVA_VERSION | awk -F "." '{ print $1 }'` 32 | JAVA_MINOR=`echo $JAVA_VERSION | awk -F "." '{ print $2 }'` 33 | 34 | if [ $JAVA_MAJOR -gt 1 ] || [ $JAVA_MINOR -ge 6 ] 35 | then 36 | if [ -z $USERNAME ] || [ -z $PASSWORD ] || [ -z $HOST ] 37 | then 38 | java -Xms256M -Xmx512M -classpath $CP Launcher 39 | else 40 | java -Xms256M -Xmx512M -classpath $CP com.avocent.nuova.kvm.Main ip=$HOST user=$USERNAME passwd=$PASSWORD title="KVM on $HOST" apcp=1 version=2 kmport=2068 vport=2068 sslv3=1 autoEof=0 tempunpw=0 aimpresent=0 power=0 vm=1 chat=1 export=1 dvr=2 statusbar=ip,un,fr,bw,kp,enc,led custom=2 41 | fi 42 | else 43 | echo "KVM requires Java Runtime Environment 1.6 or greater" 44 | fi 45 | -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libVMAPI_DLL.jnilib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libVMAPI_DLL.jnilib -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libVMAPI_DLL.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libVMAPI_DLL.so -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libavctKVMIO.jnilib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libavctKVMIO.jnilib -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libavctKVMIO.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libavctKVMIO.so -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libs/avctKVMIOLinux32.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libs/avctKVMIOLinux32.jar -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libs/avctKVMIOLinux64.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libs/avctKVMIOLinux64.jar -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libs/avctKVMIOMac64.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libs/avctKVMIOMac64.jar -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libs/avctKVMIOWin32.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libs/avctKVMIOWin32.jar -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libs/avctKVMIOWin64.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libs/avctKVMIOWin64.jar -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libs/avctNuova.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libs/avctNuova.jar -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libs/avctVMLinux32.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libs/avctVMLinux32.jar -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libs/avctVMLinux64.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libs/avctVMLinux64.jar -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libs/avctVMMac64.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libs/avctVMMac64.jar -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libs/avctVMWin32.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libs/avctVMWin32.jar -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libs/avctVMWin64.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libs/avctVMWin64.jar -------------------------------------------------------------------------------- /부록/exe package 파일/kvm/libs/lzvcnt.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/kvm/libs/lzvcnt.jar -------------------------------------------------------------------------------- /부록/exe package 파일/library.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/library.zip -------------------------------------------------------------------------------- /부록/exe package 파일/orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/orange.png -------------------------------------------------------------------------------- /부록/exe package 파일/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/red.png -------------------------------------------------------------------------------- /부록/exe package 파일/vkvm_launch_dialog.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/exe package 파일/vkvm_launch_dialog.exe -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/32BitLibs/VMAPI_DLL.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/32BitLibs/VMAPI_DLL.dll -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/32BitLibs/avctKVMIO.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/32BitLibs/avctKVMIO.dll -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/32BitLibs/libVMAPI_DLL.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/32BitLibs/libVMAPI_DLL.so -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/32BitLibs/libavctKVMIO.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/32BitLibs/libavctKVMIO.so -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/VMAPI_DLL.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/VMAPI_DLL.dll -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/avctKVMIO.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/avctKVMIO.dll -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/launchkvm.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | REM ================================================ 3 | REM ================== KVM launcher ================ 4 | REM ================================================ 5 | 6 | REM Linux jars included only to be consistent, won't actually be used for this .bat file 7 | java -d64 -version > NUL 2>&1 8 | if '%errorlevel%' == '0' ( 9 | set CP=.\libs\avctKVMIOLinux32.jar;.\libs\avctKVMIOLinux64.jar;.\libs\avctKVMIOWin64.jar;.\libs\avctNuova.jar;.\libs\avctVMLinux32.jar;.\libs\avctVMLinux64.jar;.\libs\avctVMWin64.jar;.\libs\lzvcnt.jar 10 | set LIBPATH=. 11 | ) 12 | java -d32 -version > NUL 2>&1 13 | if '%errorlevel%' == '0' ( 14 | set CP=.\libs\avctKVMIOLinux32.jar;.\libs\avctKVMIOLinux64.jar;.\libs\avctKVMIOWin32.jar;.\libs\avctNuova.jar;.\libs\avctVMLinux32.jar;.\libs\avctVMLinux64.jar;.\libs\avctVMWin32.jar;.\libs\lzvcnt.jar 15 | set LIBPATH=.\32BitLibs 16 | ) 17 | 18 | SET KVML_USAGE=Usage: launchkvm.bat -u username -p password -h host_ip 19 | SET USERNAME= 20 | SET PASSWORD= 21 | SET HOST= 22 | 23 | :LOOPARGS 24 | IF "%1" == "" goto :CONTINUEON 25 | set ARG1=%1 26 | REM position to next argument with SHIFT to get the associated value 27 | SHIFT 28 | 29 | REM if there is not a second argument in a pair then show usage and exit 30 | IF "%1" == "" ( 31 | ECHO %KVML_USAGE% 32 | goto :END 33 | ) 34 | 35 | IF "%ARG1%" == "-p" ( 36 | SET PASSWORD=%1 37 | goto :NEXTARG 38 | ) 39 | 40 | IF "%ARG1%" == "-u" ( 41 | SET USERNAME=%1 42 | goto :NEXTARG 43 | ) 44 | 45 | IF "%ARG1%" == "-h" ( 46 | SET HOST=%1 47 | goto :NEXTARG 48 | ) 49 | 50 | ECHO %KVML_USAGE% 51 | goto :END 52 | 53 | :NEXTARG 54 | REM position to next argument with SHIFT 55 | SHIFT 56 | 57 | REM if no more argument continue on to rest of bat script 58 | IF "%1" == "" goto :CONTINUEON 59 | goto :LOOPARGS 60 | goto :END 61 | :CONTINUEON 62 | 63 | IF "%USERNAME%" == "" goto :LAUNCHER 64 | IF "%PASSWORD%" == "" goto :LAUNCHER 65 | IF "%HOST%" == "" goto :LAUNCHER 66 | 67 | goto :CLI 68 | 69 | :LAUNCHER 70 | java -Xms256M -Xmx512M -Djava.library.path=%LIBPATH% -classpath %CP% Launcher 71 | goto :END 72 | 73 | :CLI 74 | java -Xms256M -Xmx512M -Djava.library.path=%LIBPATH% -classpath %CP% com.avocent.nuova.kvm.Main ip=%HOST% user=%USERNAME% passwd=%PASSWORD% title="KVM on %HOST%" apcp=1 version=2 kmport=2068 vport=2068 sslv3=1 autoEof=0 tempunpw=0 aimpresent=0 power=0 vm=1 chat=1 export=1 dvr=2 statusbar=ip,un,fr,bw,kp,enc,led custom=2 75 | goto :END 76 | 77 | :END 78 | -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/launchkvm.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # ================================================ 3 | # ================== KVM launcher ================ 4 | # ================================================ 5 | 6 | export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH 7 | export PATH=$PATH:.:./libs/avctVMWin32.jar:./libs/avctKVMIOWin32.jar 8 | export CP=./libs/avctKVMIOLinux32.jar:./libs/avctKVMIOLinux64.jar:./libs/avctKVMIOWin32.jar:./libs/avctNuova.jar:./libs/avctVMLinux32.jar:./libs/avctVMLinux64.jar:./libs/avctVMWin32.jar:./libs/lzvcnt.jar 9 | 10 | USERNAME= 11 | PASSWORD= 12 | HOST= 13 | 14 | usage() 15 | { 16 | echo "Usage: $0 -u username -p password -h host_ip" 17 | } 18 | 19 | while getopts "u:p:h:" opt 20 | do 21 | case "$opt" in 22 | u) USERNAME="$OPTARG";; 23 | p) PASSWORD="$OPTARG";; 24 | h) HOST="$OPTARG";; 25 | \?) usage;; 26 | *) usage;; 27 | esac 28 | done 29 | 30 | JAVA_VERSION=`java -version 2>&1 | grep "java version" | awk '{ print substr($3, 2, length($3)-2); }'` 31 | JAVA_MAJOR=`echo $JAVA_VERSION | awk -F "." '{ print $1 }'` 32 | JAVA_MINOR=`echo $JAVA_VERSION | awk -F "." '{ print $2 }'` 33 | 34 | if [ $JAVA_MAJOR -gt 1 ] || [ $JAVA_MINOR -ge 6 ] 35 | then 36 | if [ -z $USERNAME ] || [ -z $PASSWORD ] || [ -z $HOST ] 37 | then 38 | java -Xms256M -Xmx512M -classpath $CP Launcher 39 | else 40 | java -Xms256M -Xmx512M -classpath $CP com.avocent.nuova.kvm.Main ip=$HOST user=$USERNAME passwd=$PASSWORD title="KVM on $HOST" apcp=1 version=2 kmport=2068 vport=2068 sslv3=1 autoEof=0 tempunpw=0 aimpresent=0 power=0 vm=1 chat=1 export=1 dvr=2 statusbar=ip,un,fr,bw,kp,enc,led custom=2 41 | fi 42 | else 43 | echo "KVM requires Java Runtime Environment 1.6 or greater" 44 | fi 45 | -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libVMAPI_DLL.jnilib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libVMAPI_DLL.jnilib -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libVMAPI_DLL.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libVMAPI_DLL.so -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libavctKVMIO.jnilib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libavctKVMIO.jnilib -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libavctKVMIO.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libavctKVMIO.so -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libs/avctKVMIOLinux32.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libs/avctKVMIOLinux32.jar -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libs/avctKVMIOLinux64.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libs/avctKVMIOLinux64.jar -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libs/avctKVMIOMac64.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libs/avctKVMIOMac64.jar -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libs/avctKVMIOWin32.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libs/avctKVMIOWin32.jar -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libs/avctKVMIOWin64.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libs/avctKVMIOWin64.jar -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libs/avctNuova.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libs/avctNuova.jar -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libs/avctVMLinux32.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libs/avctVMLinux32.jar -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libs/avctVMLinux64.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libs/avctVMLinux64.jar -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libs/avctVMMac64.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libs/avctVMMac64.jar -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libs/avctVMWin32.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libs/avctVMWin32.jar -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libs/avctVMWin64.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libs/avctVMWin64.jar -------------------------------------------------------------------------------- /부록/kvm lib (From ucsm 3.0.x version)/libs/lzvcnt.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/kvm lib (From ucsm 3.0.x version)/libs/lzvcnt.jar -------------------------------------------------------------------------------- /부록/resource.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | import ConfigParser 5 | import os 6 | from PyQt4.QtCore import QString 7 | 8 | MESSAGE_EN = {} 9 | MESSAGE_KO = {} 10 | 11 | 12 | MESSAGE_EN["title"] = "Cisco UCS vKVM Launcher (Powered by HoonJo, JSKim)" 13 | MESSAGE_EN["rack_tab_title"] = "RACK Server (C-Series)" 14 | MESSAGE_EN["blade_tab_title"] = "UCS Manager (B-Series)" 15 | MESSAGE_EN["conn_info"] = "Connection info" 16 | MESSAGE_EN["ip"] = "IP Address : " 17 | MESSAGE_EN["id"] = "Username : " 18 | MESSAGE_EN["pw"] = "Password : " 19 | MESSAGE_EN["port"] = "Port : " 20 | MESSAGE_EN["add"] = "Add/Modify" 21 | MESSAGE_EN["delete"] = "Delete" 22 | MESSAGE_EN["vkvm_conn"] = "Launch vKVM " 23 | MESSAGE_EN["new_input"] = "" 24 | MESSAGE_EN["selected_blade"] = "Blade Server info" 25 | MESSAGE_EN["status"] = "Status" 26 | MESSAGE_EN["status_ready"] = "Ready" 27 | MESSAGE_EN["status_attached"] = "Attached only" 28 | MESSAGE_EN["status_etc"] = "etc" 29 | MESSAGE_EN["status_empty"] = "empty" 30 | MESSAGE_EN["conn_fail"] = "Connection Failure" 31 | MESSAGE_EN["dup_ip"] = "Duplicated IP(%s)" 32 | MESSAGE_EN["no_ucs_man"] = "No UCS Manager (For UCS B-Series) " 33 | 34 | MESSAGE_KO["title"] = "Cisco UCS vKVM 접속 도우미 (Powered by HoonJo, JSKim)" 35 | MESSAGE_KO["rack_tab_title"] = "등록된 랙 서버 매니저" 36 | MESSAGE_KO["blade_tab_title"] = "등록된 블레이드 서버 매니저" 37 | MESSAGE_KO["conn_info"] = "접속 정보" 38 | MESSAGE_KO["ip"] = "서버 매니저의 IP : " 39 | MESSAGE_KO["id"] = "관리자 ID : " 40 | MESSAGE_KO["pw"] = "암 호 : " 41 | MESSAGE_KO["port"] = "포트 번호 : " 42 | MESSAGE_KO["add"] = "추가/수정" 43 | MESSAGE_KO["delete"] = "삭제" 44 | MESSAGE_KO["vkvm_conn"] = "vKVM 접속" 45 | MESSAGE_KO["new_input"] = "<새로 입력>" 46 | MESSAGE_KO["selected_blade"] = "선택한 블레이드 서버 정보" 47 | MESSAGE_KO["status"] = "상태" 48 | MESSAGE_KO["status_ready"] = "접속 가능" 49 | MESSAGE_KO["status_attached"] = "장착만 된 상태" 50 | MESSAGE_KO["status_etc"] = "그 외의 상태" 51 | MESSAGE_KO["status_empty"] = "상태 정보 조회 불가" 52 | MESSAGE_KO["conn_fail"] = "접속에 실패했습니다." 53 | MESSAGE_KO["dup_ip"] = "이미 등록된 IP(%s) 입니다." 54 | MESSAGE_KO["no_ucs_man"] = "블레이드 서버 매니저가 아닙니다." 55 | 56 | lang = None 57 | def get_language() : 58 | env_cfg = ConfigParser.RawConfigParser() 59 | if os.path.exists("./environment.cfg") : # environment.cfg 파일이 없으면 영문 60 | env_cfg.read("./environment.cfg") 61 | if env_cfg.sections().count("Environment") > 0 : # Environment 섹션이 없으면 영문 62 | lang = env_cfg.get("Environment", "lang") # lang=ko로 설정돼야 한글 63 | if lang.lower() == "ko" : 64 | return "ko" 65 | return "en" 66 | 67 | def select_msg(msg_id) : 68 | global lang 69 | if lang == None : # 환경 설정을 읽은 적이 없으면 환경 설정값을 로드 70 | lang = get_language() 71 | if lang == "ko" : 72 | return MESSAGE_KO[msg_id] # 한글로 설정됐다면 한글 리소스 반환 73 | return MESSAGE_EN[msg_id] # 한글로 설정되지 않았다면 영문 리소스 반환 74 | 75 | def get_message(msg_id) : 76 | return QString.fromUtf8(select_msg(msg_id)) 77 | 78 | # 리소스 내에 MESSAGE_KO["dup_ip"]처럼 치환할 값이 있다면 인자로 전달 79 | def get_message_args(msg_id, args) : 80 | return QString.fromUtf8(select_msg(msg_id) % args) 81 | -------------------------------------------------------------------------------- /부록/run_dialog.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from PyQt4.QtGui import * 5 | import sys 6 | 7 | # ui XML을 변환한 모듈 import 8 | import vkvm_dialog 9 | 10 | # vkvm_dialog 모듈 안의 Ui_Dialog 클래스로부터 파생 11 | class XDialog(QDialog, vkvm_dialog.Ui_Dialog): 12 | 13 | def __init__(self): 14 | QDialog.__init__(self) 15 | # setupUi() 메서드는 화면에 다이얼로그 보여줌 16 | self.setupUi(self) 17 | 18 | if __name__ == "__main__": 19 | app = QApplication(sys.argv) 20 | dlg = XDialog() 21 | dlg.show() 22 | app.exec_() 23 | -------------------------------------------------------------------------------- /부록/run_dialog_language.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from PyQt4.QtGui import * 5 | import sys 6 | from resource import get_message 7 | 8 | # ui XML을 변환한 모듈 import 9 | import vkvm_dialog 10 | 11 | # vkvm_dialog 모듈 안의 Ui_Dialog 클래스로부터 파생 12 | class XDialog(QDialog, vkvm_dialog.Ui_Dialog): 13 | 14 | def __init__(self): 15 | QDialog.__init__(self) 16 | # setupUi() 메서드는 화면에 다이얼로그를 보여줌 17 | self.setupUi(self) 18 | self.set_resource() 19 | 20 | def set_resource(self): 21 | self.setWindowTitle(get_message("title")) 22 | self.tabWidget.setTabText(0, get_message("rack_tab_title")) 23 | self.tabWidget.setTabText(1, get_message("blade_tab_title")) 24 | self.connInfoBox.setTitle(get_message("conn_info")) 25 | self.ipLabel.setText(get_message("ip")) 26 | self.idLabel.setText(get_message("id")) 27 | self.pwLabel.setText(get_message("pw")) 28 | self.portLabel.setText(get_message("port")) 29 | self.addButton.setText(get_message("add")) 30 | self.removeButton.setText(get_message("delete")) 31 | self.connButton.setText(get_message("vkvm_conn")) 32 | self.bladeBox.setTitle(get_message("selected_blade")) 33 | self.statusBox.setTitle(get_message("status")) 34 | self.statusList.item(0).setText(get_message("status")) 35 | self.statusList.item(1).setText(get_message("status_ready")) 36 | self.statusList.item(2).setText(get_message("status_attached")) 37 | self.statusList.item(3).setText(get_message("status_etc")) 38 | self.statusList.item(3).setText(get_message("status_empty")) 39 | 40 | if __name__ == "__main__": 41 | app = QApplication(sys.argv) 42 | dlg = XDialog() 43 | dlg.show() 44 | app.exec_() 45 | -------------------------------------------------------------------------------- /부록/setup.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from distutils.core import setup 5 | import py2exe 6 | from glob import glob 7 | import os 8 | 9 | file_list = {} 10 | options={ 11 | "bundle_files":1, # 컴파일된 파이썬 코드와 관련 패키지 라이브러리를 하나로 묶어서 배포하기 위한 옵션으로 64비트에서는 사용하지 못하는 옵션입니다. 12 | "dll_excludes":["MSVCP90.dll", "w9xpopen.exe"], # 설치 과정에서 포함하지 않을 dll을 정의합니다. 13 | "includes" : ["sip", "_cffi_backend"], # 포함할 라이브러리를 지정합니다. sip는 PyQt4 코드를 배포할 때 사용합니다. _cffi_backend는 paramiko 모듈이 사용하는 라이브러리입니다. (ssh_check_type.py 모듈에서 paramiko 모듈을 임포트하고 있음) 14 | "packages": [ "packaging", "xml", "ucsmsdk", "paramiko"], # 함께 배포될 패키지를 정의합니다.packaging은 배포 시 사용되는 패키지입니다. xml, ucsmsdk은 코드에서 사용한 vKVM 접속과 관련된 패키지입니다. 15 | # paramiko: SSH 접속 테스트를 위한 패키지 16 | } 17 | datas=[ 18 | ("", ["./grey.png", "./green.png", "./orange.png", "./red.png", "./blank.png", "./environment.cfg"]) 19 | ] 20 | 21 | def get_file_list(path) : # 하위 파일 리스트를 모두 찾습니다. 22 | global file_list 23 | if os.path.isdir(path) : 24 | for path in glob(path + "/*") : 25 | get_file_list(path) 26 | else : 27 | dirname = os.path.dirname(path).replace("c:/", "") 28 | path = path.replace("\\", "/") 29 | if file_list.get(dirname) == None : 30 | file_list[dirname] = [path] 31 | else : 32 | file_list[dirname].append(path) 33 | 34 | def append_kvm_files() : 35 | global datas 36 | get_file_list("./kvm") 37 | keys = file_list.keys() 38 | keys.sort() 39 | for dirname in keys : 40 | datas.append((dirname, file_list[dirname])) # kvm의 파일을 모두 찾아서 datas에 포함시킴 41 | append_kvm_files() 42 | setup( 43 | options = {"py2exe" : options}, # options : 설치 옵션을 정의 44 | data_files = datas, # datas: EXE 실행 파일을 만들 때 함께 복사할 파일 45 | windows=["vkvm_launch_dialog.py"], # 윈도우 형태의 실행 파일을 작성할 파이썬 코드 46 | ) 47 | -------------------------------------------------------------------------------- /부록/ssh_check_type.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | from ssh_exec_cmd import * 5 | 6 | def check_type() : 7 | system_type = "Unknown" 8 | data = exec_cmd("uname -a") 9 | if data.find("Linux ") >= 0 : 10 | data = exec_cmd("grep . /etc/*-release") 11 | system_type = "Linux" 12 | elif data.find("VMkernel ") >=0 : 13 | system_type = "VMware" 14 | elif data.find("Cmd exec") >= 0 : 15 | data = exec_cmd("show version") 16 | if data.find("Cisco Nexus Operating System (NX-OS) Software") >=0: 17 | data = exec_cmd("show version | include version") 18 | system_type = "NX-OS_Switch" 19 | elif data.lower().find("invalid command") >= 0 : 20 | data = exec_cmd("show version") 21 | if data.find("Firmware Version") >=0 : 22 | system_type = "UCSC_MGMT_Port" 23 | elif data.find("System version") >=0: 24 | system_type = "UCSM_FI" # 현재 랩에서 NX-OS가 아닌 경우는 UCSM 입니다. 25 | return (system_type, data) 26 | 27 | def get_message(system_type, cmd_result) : 28 | if system_type == "Linux" : 29 | return "리눅스 시스템입니다. : %s" % get_line(cmd_result, 0) 30 | elif system_type == "VMware" : 31 | return "VMware 시스템입니다. : %s" % get_line(cmd_result, 0) 32 | elif system_type == "UCSC_MGMT_Port" : 33 | return "서버 관리 모듈입니다. : %s(%s)" % ( 34 | get_line(cmd_result, 0), get_line(cmd_result, 2)) 35 | elif system_type == "NX-OS_Switch" : 36 | return "네트워크 시스템입니다. : %s" % get_line(cmd_result, 3) 37 | elif system_type == "UCSM_FI" : 38 | return "UCS 매니저 시스템입니다. : %s" % get_line(cmd_result, 0) 39 | return "시스템 타입을 알 수 없습니다." 40 | 41 | def get_line(data, row) : 42 | lines = data.split("\n") 43 | return str(lines[row]).strip() 44 | 45 | if __name__ == '__main__': 46 | (host, port_num, user, pw) = get_connection_input() 47 | connnected = connect(host, port_num, user, pw) 48 | if connnected: 49 | close() 50 | else : 51 | print "원격지 시스템 접속에 실패하였습니다." 52 | if connnected : 53 | (system_type, cmd_result) = check_type() 54 | print get_message(system_type, cmd_result) 55 | -------------------------------------------------------------------------------- /부록/ssh_exec_cmd.py: -------------------------------------------------------------------------------- 1 | #!/bin/env python 2 | #-*- coding: utf-8 -*- 3 | 4 | 5 | import paramiko 6 | import time 7 | 8 | 9 | client = None 10 | (host, port_num, user, pw) = ("", 22, "", "") 11 | def connect(host, port_num, user, pw) : 12 | global client 13 | client = paramiko.SSHClient() 14 | client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) 15 | try : 16 | set_connection_info(host, port_num, user, pw) 17 | client.connect(hostname=host, port=port_num, username=user, password=pw) 18 | return True 19 | except : 20 | return False 21 | 22 | 23 | def close() : 24 | client.close() 25 | 26 | def exec_cmd(cmd) : 27 | if connect(host, port_num, user, pw) : 28 | try : 29 | (stdin, stdout, stderr) = client.exec_command(cmd) 30 | if stderr.read().strip() != "" : 31 | return invoke_shell(cmd) 32 | return stdout.read().strip() 33 | except : 34 | print "명령어를 수행할 수 없습니다. :", cmd 35 | close() 36 | 37 | 38 | def invoke_shell(cmd) : 39 | channel = client.invoke_shell() 40 | response = channel.recv(9999) 41 | channel.send(cmd + "\n") 42 | while not channel.recv_ready(): 43 | time.sleep(3) 44 | response = channel.recv(9999) 45 | out = response.decode("utf-8") 46 | first_enter_index = min(out.find("\r"), out.find("\n")) 47 | out = out[first_enter_index : len(out)] 48 | out = out.replace("\r\n", "\n") 49 | return out.strip() 50 | 51 | 52 | def get_connection_input() : 53 | host = raw_input("원격지 시스템의 IP를 입력하세요. : ") 54 | port_num = 22 55 | try : 56 | port_num = input("원격지 시스템의 Port 번호를 입력하세요. [22] : ") 57 | except : 58 | port_num = 22 59 | user = raw_input("관리자 ID를 입력하세요. : ") 60 | pw = raw_input("암호를 입력하세요. : ") 61 | return (host, port_num, user, pw) 62 | 63 | 64 | def set_connection_info(input_host, input_port_num, input_user, input_pw): 65 | global host, port_num, user, pw 66 | host = input_host 67 | port_num = input_port_num 68 | user = input_user 69 | pw = input_pw 70 | 71 | if __name__ == '__main__': 72 | (host, port_num, user, pw) = get_connection_input() 73 | connnected = connect(host, port_num, user, pw) 74 | if connnected: 75 | close() 76 | else : 77 | print "원격지 시스템 접속에 실패하였습니다." 78 | if connnected: 79 | cmd = "dir" 80 | print "수행 명령어 :", cmd 81 | print exec_cmd(cmd) 82 | print "*" * 70 83 | cmd = "ls" 84 | print "수행 명령어 :", cmd 85 | print exec_cmd(cmd) 86 | print "*" * 70 87 | -------------------------------------------------------------------------------- /부록/이미지 파일 (png format)/blank.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/이미지 파일 (png format)/blank.png -------------------------------------------------------------------------------- /부록/이미지 파일 (png format)/green.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/이미지 파일 (png format)/green.png -------------------------------------------------------------------------------- /부록/이미지 파일 (png format)/grey.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/이미지 파일 (png format)/grey.png -------------------------------------------------------------------------------- /부록/이미지 파일 (png format)/orange.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/이미지 파일 (png format)/orange.png -------------------------------------------------------------------------------- /부록/이미지 파일 (png format)/red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wikibook/python-for-sysadmin/2992af4255796a6c08b78fdb04146d3836b9ce40/부록/이미지 파일 (png format)/red.png --------------------------------------------------------------------------------