DevOps/Automation2015.03.09 22:39

 

Ansible Arista 제어

 

거의 한 달여만의 포스팅이자, Automation for Networker 시리즈로는 거의 3~4달여만 남기는 것 같습니다.

이래 저래.. 일도 있고, 2월부터 4월까지 예정중인 네트워크 타임즈 기고 건 때문에 조금 더디게 정리하고 있기도 합니다. ^^;

이번 포스팅은 4월 네트워크 타임즈 기고에서도 다뤄지게 될 내용인, Ansible을 통한 Arista Switch를 제어하기의 첫 번째 시간인

환경 구축입니다.  다음 포스팅은 이 환경 구축을 통한 실제 Ansible로 Arista swtich 제어하는 에제를 다루게 될 예정입니다.

길이는 무척이나 짧지만, 인고의 삽질 끝에 얻어낸 축약된 내용입니다. ^^;


Ansible로 Arista Switch 제어하기 

 

1. Arista 장비에서 EOS Command API를 활성화

    ZIGI-ARI# management api http-commands

    ZIGI-ARI(config-mgmt-api-http-cmds)# no shutdown

 

 

2. Ansible에서 Arista 장비를 SSH 통해서 제어하기 위해서,  Ansible Control Node가 Arista Linux Shell에 직접 접근하도록 구성.

        - Ansible Control Node는 Arista EOS Node에 Password를 입력하지 않고 SSH Key를 통해서 접속하도록 구성

    2-1 Ansible에서 사용할 SSh 접속용 User 생성

    2-2 Ansible Control Node에서 SSH Key를 전송하기 위한 디렉토리를 생성 후, 권한 설정

 

 

 

 

 

3. Ansible Control Node에서 SSH Key를 Arista EOS Node로 전송 후, SSH 접속 테스트

         - Key를 접속하기 전에는 SSH 접속 시, Password를 입력해야 하지만 Key 전송 후에는 바로 접근 가능

 

 

 

 

4. Arista 장비에서 Ansible 사용자가 key를 이용해서만 Login하도록, 재부팅 시에 Password를 할당하지 않게 설정한다.

 

 

 

 


 

● 라이브러리 종속성

     - Ansible을 사용하여 Arista Switch를 제어하기 위한 설치 과정에서 아래와 같은 종속성이 있기 때문에 각각 모두 설치가 필요하다.

 

 

※ 초기에는 devops extension을 설치하였지만, 현재는 arista.eos로 대체

 

 

Posted by 네떡지기
DevOps/Programmability2015.02.17 20:35

NX-API

 

기존의 Python for Networker라는 주제로 포스팅하던 것을, 주제를 넓혀보고자..

Programmability for Networker로 이름을 변경하고 지속해서 시작합니다. ^^;

이번 포스팅은 Cisco의 Programmability를 지원하는 NX-API에 대한 포스팅입니다.  


 

NX-API  - Cisco Programmability

 

◈ NX-API

    - HTTP/HTTPS의 RPC 기반의 API 기능 수행

    - 'show', 'configuration', 'Linux Bash' 지원

    - JSON-RPC를 지원

    - Cisco Nexus 9000 platform 적용

 

 

◈ NX-API 동작

    - HTTP/HTTPS로 전송되며, 해당 CLI는 HTTP/HTTPS의 POST body로 encode된다.

    - Nexus 장비에서는 이러한 NX-API를 위해서 Nginx HTTP Server를 사용한다.

    - Nginx와 모든 하위 Process는 Linux cgroup의 메모리 제한 값을 초과하면, Process가 재시작 되도록 하여, 본 장비 리소스를 보호한다.

 

 

◈ NX-API 명령 포맷

    - Nexus 9000의 향상된 NX-OS CLI

    -  XML 출력,JSON 형태 출력

 

 

◈ NX-API 기능 활성화

    - NX-API feature 활성화 필요 ( Default : Disable)

NX-OS#(config)# feature nxapi

 

 

◈ NX-API Sandbox

    - HTTP/HTTPS를 사용하여, 사용자가 Cli 명령을 특정 Command Type, Output Type을 지정해서 사용할 수 있는 웹기반 인터페이스

    - NX-API Feature를 활성화 후, nxapi sandbox를 사용 할 수 있다.

NX-OS#(config)# nxapi sandbox

     - 접속 방법 : Web 브라우저에서 http://mgmt-ip  로 접속

 

 

◈ NX-API Request Element

    ○ Input

         - 1개 이상의 명령어 입력 가능. (단, 동일한 Messaage Type이어야 함 : Show, Configuration, bash)

         - Show와 Conf의 경우에는 다수의 명령어 입력 시, ';'(세미콜론)을 사용하며, 명령어와 세미콜론 사이는 1칸의 공백 필요

              ex) show interface brief ; show version  or  interface eth2/1 ; switchport ; no shut

         - Bash의 경우에는 다수의 명령어 입력 시, 마찬가지로 ';'(세미콜론)을 사용하지만, 명령어와 세미콜론 사이의 공백이 없어야 함.

             ex) cd /bootflash;mkdir zigi_dir

     

 

    ○ Type

        - cli_show : 구조화 된 결과값을 나타냄. 만약 XML을 지원하지 않는 명령 입력 시에는 error 메시지를 리턴

                              즉, 특정 명령어에 대해서만 구조화된 결과값을 나타내도록 지원. 

        - cli_show_ascii : ASCII 값으로 결과 출력.

        - cli_conf : Configuraion 명령 사용 시 사용

        - bash : Bash 명령 사용 ( NX-API에서는 non-interacitve Bash 명령을 지원)

        * 최대 10개의 Show 명령을 동시에 지원. (10개 이상 입력 시, 11번째부터는 무시 됨.)

        * ASCII의 경우에는 '|' (Pipe) 가 지원 됨. (XML의 경우에는 미 지원)

 

    ○ output_format 

        -  XML / JSON 포맷을 지원

        -  N9K는 XML을 지원하며, JSON은 XML을 전환하여 결과 값을 만든다.

   

 

◈ NX-API Response Element

     ○ version

         - NX-API Version (현재 1.0 / dCloud에서는 0.1 Version 지원)

     ○ type

         - 명령 실행 타입 (cli_show, cli_show_ascii, cli_conf, bash)

     ○ sid

         - 응답에 대한 Session ID.

         - 응답메시지가 chunked인 경우에만 유효함.

    ○ outputs

         - 요청한 전체 명령에 대한 출력 값을 감싸고 있는 Tag

         - cli_show, cli_show_ascii 의 경우에 다수의 명령어를 요청한 경우 각 개별 명령은 output tag가 붙는다.

    ○ output

         - 요청한 개별 명령에 대한 출력 값을 감싸고 있는 Tag

    ○ intput

         - 요청한 명령어

    ○ body

         - 요청한 명령어에 대한 응답

    ○ msg

         - 요청에 대한 응답의 처리 결과 메세지. code Element의 내용으로 확인 가능.

    ○ code

         - 요청에 의한 응답의 결과에 따른 Code번호.

         - NX-API에서는 표준 HTTP의 Status Code값을 사용한다.  

 

[ NX-API SandBox 실행화면 ]

 

 

◈ NX-API Sandbox 화면 구성

     ○ 상단 화면

 

 

         - 실행행하고자 하는 Command 와 Meassage format, Command Type을 지정할 수 있다.

            - POST 버튼은 위에서 지정한 Command와 Format/Type에 맞춰서 Request 코드가 만들어면서, Request가 이뤄진다.

 

    ○ 하단 좌측

 

 

 

 

            - 상단화면에서 지정한 내용에 따라서 만들어진 Request 내용을 출력

            - Python 버튼을 누르면, 해당 Request를 사용 할 수 있는 Python 코드로 생성 됨.

 

      ○ 하단 우측

 

 

         - 상단화면에서 요청한 내용에 대한 결과 값을 출력.

 

 

 

 NX-API Sandbox 실행 예제 -  JSON - cli_show

    

 

 

 NX-API Sandbox 실행 예제 -  JSON - bash

 

 

 NX-API Sandbox 실행 예제  -  Request를 Python Code로 변경

 

 

◈ NX-API Response Code

 

NX-API Response

Code

Message

SUCCESS

200

Success.      

CUST_OUTPUT_PIPED

204

Output is piped elsewhere due to request.

BASH_CMD_ERR

400

Input Bash command error.   

CHUNK_ALLOW_ONE_CMD_ERR

400

Chunking only allowed to one command. 

CLI_CLIENT_ERR

400

CLI execution error.    

CLI_CMD_ERR

400

Input CLI command error.   

IN_MSG_ERR

400

Request message is invalid.   

NO_INPUT_CMD_ERR

400

No input command.    

PERM_DENY_ERR

401

Permission denied.     

CONF_NOT_ALLOW_SHOW_ERR

405

Configuration mode does not allow show .

SHOW_NOT_ALLOW_CONF_ERR

405

Show mode does not allow configuration. 

EXCEED_MAX_SHOW_ERR

413

Maximum number of consecutive show
commands exceeded. The maximum is 10.

MSG_SIZE_LARGE_ERR

413

Response size too large.   

BACKEND_ERR

500

Backend processing error.    

FILE_OPER_ERR

500

System internal file operation error.  

LIBXML_NS_ERR

500

System internal LIBXML NS error.  

LIBXML_PARSE_ERR

500

System internal LIBXML parse error.  

LIBXML_PATH_CTX_ERR

500

System internal LIBXML path context error. 

MEM_ALLOC_ERR

500

System internal memory allocation error.  

USER_NOT_FOUND_ERR

500

User not found from input or cache.

XML_TO_JSON_CONVERT_ERR

500

XML to JSON conversion error.  

BASH_CMD_NOT_SUPPORTED_ERR

501

Bash command not supported.   

CHUNK_ALLOW_XML_ONLY_ERR

501

Chunking allows only XML output.

JSON_NOT_SUPPORTED_ERR

501

JSON not supported due to large amount of output.

MSG_TYPE_UNSUPPORTED_ERR

501

Message type not supported.   

PIPE_OUTPUT_NOT_SUPPORTED_ERR

501

Pipe operation not supported.   

PIPE_XML_NOT_ALLOWED_IN_INPUT

501

Pipe XML is not allowed in input.

RESP_BIG_JSON_NOT_ALLOWED_ERR

501

Response has large amount of output. JSON not
supported.

STRUCT_NOT_SUPPORTED_ERR

501

Structured output unsupported.    

 

 

※ 참고

http://www.google.co.kr/url?url=http://www.jedelman.com/home/introduction-to-using-cisco-nx-api&rct=j&frm=1&q=&esrc=s&sa=U&ei=R2HhVIi2Ioqa8QXqtYAw&ved=0CDMQFjAF&usg=AFQjCNE6Udq_iqse1vYQpq12BtIIiKVOXA

http://keepingitclassless.net/2014/02/cisco-aci-nexus-9000-nxapi/

http://jeffostermiller.blogspot.kr/2015/01/my-first-python-script.html#!/2015/01/my-first-python-script.html

 

Posted by 네떡지기
분류없음2014.12.15 22:53

Python for Networker 13번째는 본래 의도와는 다르게 다시 조금 쉬어가는 포스팅입니다.

OnePK의 예제 코드를 다뤄보기 전의 Cisco OnePK에 대해서 조금 더 간단히 알아보는 내용입니다.

다음 포스팅부터 이제 실제 예제코드는 함께 다뤄질 예정입니다! ^^

또한 본 포스팅은 OnePK에 대한 소개이기 때문에 이론적인 부분에 있어서는 지속적으로 업데이트 할 예정입니다.

 


 

OnePK Introduce

   - 다양한 Cisco Device를 OnePK라는 Application Toolkit을 통해 기존 네트워크를 programmability하게 사용 가능하도록 함.

 

 

 

 

 - 기존 IOS ,OSd/XE, XR, NX-OS 모두 각각  onePK API를 지원하는 환경에서 다양한 언어(C, Java, Python)로 만들어진

   API를 통해서 통신하여 동작할 수 있도록 함.

 

 

 

 

 

OnePK Service Set

  

 

 

○ OnePK Hosting Option

     - OnePK는 아래와 같은 3가지 방식으로 동작할 수 있도록 지원 됨.

    ▷ Process Hosting

        - OnePK가 동작하기 위한 Module 형식의 Software 구조가 필요로 함. 

        - Latency와 Delay 매주 작음.

        - 해당 장비 내부에서 동작하기 때문에 자원을 공유함.

 

    ▷ Blade Hosting

        - OnePK가 동작하기 위한 Blade Hardware가 필요로 함.

        - Latency와 Delay가 비교적 작음.

        - 모든 Platform을 지원

 

    ▷ End-Poin(Node) Hosting

        - 별도의 Device를 사용

        - Latency와 Delay가 비교적 큼.

        - 모든 Platform을 지원

  

  

 

 

 

 

 

OnePK 지원 장비 

  

 - 현재 OnePK는 1.3 Version이며, 아래의 Hardware와 Software Version에서 동작한다. (2014년 8월 기준)

Device

Software

Cisco ASR 1000 & ISR 4400 Series Router

CSR 1000V Cloud Services Router

Cisco IOS XE 3.12.0S

Cisco ASR 9000 Series Aggregation Services Router

Cisco IOS XR 5.2.0

Cisco ISR G2

Cisco IOS Release 15.4(2)T

Cisco ME 3600X/24CX

Cisco IOS Release 15.4(3)S

 

 

 

OnePK Platform별 지원 Service Set 

 

 Service Set

ME3600X/24CX

ISR G2 

ISR 4400 

ASR 1000 

ASR 9000 

CSR 1000V 

Data Path 

 

Policy

Routing 

Element

Discovery

Utility

Developer

Location

 

 

 

MediaTrace
(PathTrace)

 

 

Identity

(SANET)

 

 

 

 

 

 

 

○ Language별 OnePK Service Set 지원

   - C언어는 모든 Service Set 지원

   - Java, Python은 Data Path를 제외한 모든 Service Set 지원

 

 

 

Posted by 네떡지기
분류없음2014.12.14 04:16

 


이번에는 Cisco OnePK에 대한 아주 간단한 소개와 앞으로 포스팅 하게 될 OnePK에 대한 예제 내용들입니다.

이번 포스팅에서는 OnePK로 할 수 있는 예제 결과에 대해서만 간략하게 보여드리고,

이후 포스팅부터는 OnePK에 대한 좀 더 기술적인 내용과 함께

이번 포스팅에 보여드린 예제에 대해서 코드와 함께 좀 더 자세히 살펴보도록 하겠습니다.

 


 

Cisco OnePK (Platform Kit)

 

 ○ OnePK 란?

     - Cisco Open Network Environment SDN 전략 요소

     - 개발/자동화/빠른 서비스 생성 등의 작업을 손쉽게 하게 도와주는 툴킷

     - 다양한 언어(C, Java, Python)를 사용할 수 있도록 API를 제공

     - API를 사용하여 비즈니스 요구에 따른 확장, 변경 등의 다양한 작업 가능.

 

 

 ※ Cisco OnePK Site : https://developer.cisco.com/site/onepk/index.gsp

 

 

 ○ OnePK를 사용한  예제 1

     - Network Element(Device)에 접속하여 다양한 속성값을 가져올 수 있다.

 

 

 

 ○ OnePK를 사용한  예제 2

     - Network Element(Device)의 정보를 가져와서 확인할 수 있다. 

- Network Element의 실제 Interface 정보 -

 

- OnePK를 사용하여, Interface 번호와 Description을 가져온 결과 -

 

 

 ○ OnePK를 사용한  예제 3

     - Network Element의 설정을 OnePK에서 제공하는 API를 통해서 변경 ( Interface Descpriton 변경)

 

 

 

 

 

 ○ OnePK를 사용한  예제 4

     - Network Element에 직접 CLI 명령을 통해서 정보 확인 및 Config 설정

 

- CLI 명령을 통해서, 현재 정보를 출력하고, Loopback Interface를 생성 후, 동일한 정보를 출력하여 확인 -

 

 

● Cisco OnePK에 대한 소개 정보는 솔라구구님 블로그를 참조하셔도 좋습니다.

   : http://sola99.tistory.com/208

 

 

Posted by 네떡지기
분류없음2014.07.31 23:51

 


벌써 9번째 포스팅에 접어들었네요. ^^;

 

이번 포스팅은 직접 장비가 없어도 해보실 수 있는 VM을 이용하여 실습을 할 수 있도록 하는 환경을 꾸미는 내용입니다.

 

바로 ARISTA의 vEOS를 VMWARE 환경에서 사용할 수 있도록 만들어 보겠습니다.

 

이번 포스팅에서 1대의 가상 머신을 설치해보지만, 여러대의 VM을 띄워서 네트워크 구성도 물론 가능합니다!

 

 

NetworkZIGI Python Git : https://github.com/NetworkZIGI/Python_for_Network

 


 

 

먼저 Arista의 vEOS를 사용하기 위해서, vEOS 이미지를 구하셔야 합니다.

vEOS 이미지는 Arista 홈페이지를 가면, 아래와 같이 vEOS를 다운 받으실 수 있습니다. 
물론 다운을 받기 위해서 가입을 하셔야 합니다. (단, 별도의 파트너 계정일 필요는 없이 회원 가입만으로 다운이 가능합니다.)

 

그리고 버전이 여러개가 있는데,

 

    F 버전 : 기능이 추가된 버전

    M버전 : 안정화된 버전

 

이라고 볼 수 있습니다.

 

 

버전 한가지를 골라서, 해당 버전의 모든 파일과 ISO 파일을 모두 다운 받습니다.

 

다운을 받는데는 시간이 조금 걸리기 때문에, 다운 시켜놓고~ 잠시 네떡지기의 블로그에서 다른 포스팅도 봐주시면 감사하겠습니다.

 

....

 

자 모든 파일이 다운이 끝났으면, 이제부터 환경을 만들어 보겠습니다.

전 과정(?)을 모두 캡춰를 떴으니~ 사진만 보고 따라가셔도 충분히 손쉽게 구축할 수 있습니다.

 

 

Custom 모드를 선택해서 시작합니다.

 

그냥 Next를 하시면 됩니다. ^^

 

아까 홈페이지에서 다운 받은

Aboot-veos-2.0.8.iso

로 지정하시면 됩니다!

 

Linux로 선택하시고, inOther Linux 2.6x 로 선택 하시면  됩니다.

 

 

 

 

적당하게, Virtual Machine Name을 주고, 위치를 지정합니다.

 

Next 클릭! (CPU 1)

 

2048MB 로 지정하시고, Next 선택

 

전 Host-only networking을 했습니다.

 

Next 클릭! (LSI Logic)

  

IDE로 지정하시고, Next 선택

 

 

Disk는 Existing Disk로 지정하시고,

Arista 홈페이지에서 다운받은 이미지 파일(vEOS-4.13.7M.vmdk)을 지정합니다.

Next 선택합니다.

 

모두 끝습니다.

Finish를 선택하시면 됩니다.

 

자, 이제 가상머신을 구동시킵니다!

 

위와 같이 vEOS가 부팅되는 것을 볼 수 있습니다.

 

부팅이 완료되면, 로그인 창이 뜹니다.

기본 계정은 'admin'으로 하시고, 별도의 비밀번호는 없습니다.

 

 

자, 이제 모든 환경이 갖춰졌으니 Python Shell을 띄워서 간단하게 Print까지 한 줄 해보았습니다.

 

이제부터는 집에 있는 컴퓨터로도 실습까지 해 볼 수 있는 멋진 환경을 구축하시게 되었습니다.

 

이번 포스팅은 이만 줄이고~ 다음 포스팅에서 다시 또 조만간 뵙도록 하겠습니다.

Posted by 네떡지기
프로그래밍/Python2014.07.28 12:59

 

Last Updated : 2014.07.30


 

이번 포스팅은 Nexus 7000 시리즈에서 Python Script를 실행하기 위한 방법입니다.

 

Nexus 버전별로 지원되는 부분이 조금씩 다른 듯 싶은데..    (물론 제가 모든 장비를 해 볼 수 있는 환경이 아니어서요... )

 

Nexus 5000의 경우에는 바로 Python 명령을 사용하여 기존의 만들어진 Python 모듈을 실행할 수 있지만,

 

Nexus 7000에서는 Python 명령을 치고 '?'를 치면...   아래와 같이 Python Shell로 들어가는 것 밖에 되지 않습니다.

 

 

 

Nexus 7000

Nexus 5000

N7K# python ?
  <CR>  

N5K# python ?
  <CR>       
  bootflash:  The file to run

 

그럼 과연 실행은 어떻게 할까요?

바로 source 명령어로 실행을 하게 됩니다.

그런데, 이 때 Source 명령으로 실행하기 위해 'Hello.py'를

 

print 'Hello ZIGI'

 

라는 한 줄짜리 코드를 작성해서 실행하려고 보면, 실행이 되지 않습니다.

그럼 source라는 명령을 치고 ? 를 쳐봅니다.

그럼 아래와 같이 출력이 됩니다.

 

 

Source 명령

NX-OS# source ?
  background (no abbrev)         Run the script in the background, see also 'show background' and 'kill background'
  build_cmd_script.py               No help
  build_cmd_script_from_file.py  No help
  cgrep                                Grep for something in stdin (-> use behind pipe) and display its 'context' \

                                         (determined by indentation, like in 'show run')
  check_sys_st_op_consist.py     No help
  cmn_file_util.py                    No help
  copy-sys (no abbrev)            Copy the system provided example scripts of /sys to bootflash:scripts
  def_cmd_script.tmp               No help
  elame.tcl                            No help
  gen_sys_st_op.py                  No help
  logw.py                              No help
  poap.py                             Loads system/kickstart images and config file for POAP
  show-version                      A succinct 'show version' -- mixes in stuff from 'show version build-info / internal build'
  sys/                                  Directory
  systemcheck.py                   No help
  systemcheck.pyc                 No help
  update_cmd_script.py           No help

 

Hello.py 라는 파일이 없습니다.

 

이유인 즉,

 

The bootflash:scripts directory is the default script directory. All scripts must be stored in the bootflash:scripts directory or in a subdirectory of it.

 

바로 bootflash 안에 scripts 폴더에 넣어야 합니다. 바로 위에 보이는 저 항목들도 모두 Scripts 폴더에 있기 때문이지요.

물론 Scripts 하위 폴더에 저장을 해도 상관은 없습니다. 경로만 지정한다면..

그럼 scripts 폴더에 다음 "hello.py"를 아래와 같이

 

print 'Hello ZIGI'

 

를 다시 만들어 실행해봅니다.

 

NX-OS# source hello.py
Error: language not supported

 

그럼 위와 같이 다시 또 실행이 되지 않습니다.

 

그 이유는.

 

You can run a tcl script instead of a Python script by inserting #!/bin/env tclsh before the first line in the example and replacing all occurrences of the Python

 

Python script 제일 상단에  "#!/bin/env python"  을 추가해줘야 합니다.

  

 

bootflash://scripts/hello.py

#!/bin/env python

print "Hello ZIGI"

※ 스크립트가 #!로 시작하는 경우, 스크립트를 해석하여 실행할 프로그램 의 경로명이 된다.

 

자, 이제 다시 실행을 해보겠습니다.

 

 

bootflash://scripts/hello.py : 실행

NX-OS# source hello.py

Hello ZIGI

NX-OS#

 

위와 같이 Python Script를 실행할 수 있는 걸 볼 수 있습니다.

 

그럼 기존에 포스팅했던 Script도 실행할 수 있습니다.

 

 

bootflash://scripts/hello.py : 실행

NX-OS# source ipinfo.py 10.10.10.100
================================================
             IP Info : NetworkZIGI             
================================================
IP-Address      : 10.10.10.100

Mac-Address   : 0080.9867.123B
Vlan              : 11
Interface       : Ethernet 1/1
Description     : ZIGI-WebServer

 

단, 코드를 약간 수정해주셔야 합니다.

왜냐하면, Cisco Nexus에서도 장비 버전별로 지원되는 패키지가 다르기 때문이지요.

Nexus 5000에서 사용한 cisco.CLI() 라는 메서드 대신에, cisco.cli(), cisco.clip(), cisco.clid()가 있습니다.

 

저는 cisco.cli() 메서드를 이용해서 위와 같이 만들었습니다.

어떻게 변형해야 하는지는 간단한 숙제로 남겨드리겠습니다. ^^

 

 

  

Posted by 네떡지기
프로그래밍/Python2014.07.24 21:30

이번 포스팅도 Python으로 만들어 보는 예제입니다.  마찬가지로 Cisco Nexus 5548 기준입니다.   

 

하지만, 현재 만드는 예제가 모두 기본 CLI명령을 입력하는 부분에서만 Cisco 패키지를 사용하기 때문에

 

간단한(?) 변형을 통해 다른 곳에도 활용이 가능합니다.

 

(물론 출력된 문자열이 Nexus 기준에서 가공하여 만든 예제라 문자열 가공을 각 상황에 맞게 일부 변형이 필요합니다)

 

이번 예제는 특정 interface의 사용량을 원하는 횟수만큼,  원하는 시간 간격으로 화면에 출력해주는 예제입니다.

 

* Github에서 보기

    uInt.py : https://github.com/NetworkZIGI/Python_for_Network/blob/master/uInt.py

    uIntmod : https://github.com/NetworkZIGI/Python_for_Network/blob/master/uIntmod.py

 


 

 

uInt.py

__author__ = 'Network ZIGI'

import cisco
import time
from argparse import ArgumentParser


def CheckInterfaceRate():
    inPacketList = []
    inBitList =[]
    outPacketList=[]
    outBitList=[]
 

    for cnt in range(1,int(args.repeat)+1):
        result = getInterfacerRate()
        print '%8d >>  [ Input ]  %13s bps -  %6s pps   :   [ Ouput ]  %13s bps  -  %6s pps    [ %s %s]' % \
        (cnt,result[0][4], result[0][6],result[1][4],result[1][6],result[0][0],result[0][1])
        inBitList.append(int(result[0][4]))
        inPacketList.append(int(result[0][6]))
        outBitList.append(int(result[1][4]))
        outPacketList.append(int(result[1][6]))
        time.sleep(int(args.interval[0]))

    print '==========================================================================='
    print 'Max  >>   [ Input ]  %13d bps -  %6d pps   :   [ Ouput ]  %13d bps  -  %6d pps ' % \
    (max(inBitList), max(inPacketList),max(outBitList), max(outPacketList))

 

def getInterfacerRate():
     intRateCmdResult = cisco.CLI('sh int '+args.Intinfo, False)
    intRateCmdResultList =intRateCmdResult.get_output()
    for rate in intRateCmdResultList:
        if(-1<rate.find('input rate')):
            inputList = rate.split()
        elif ( -1<rate.find('output rate')):
            outputList = rate.split()
            return inputList, outputList

 

parser = ArgumentParser('usingInt')
parser.add_argument('Intinfo',  help='Interface')
parser.add_argument('repeat', help='repeat Interface Input/Output rate')
parser.add_argument('interval', type=str, default=['1'],nargs='*',  help='Interval time (Second) - [default : 1 Second]')
args = parser.parse_args()
CheckInterfaceRate()

 

그리고 위의 코드를 아래와 같이 실행해봅니다.

 

필요한 매개변수는

 

1. 사용량을 확인할 인터페이스               2. 반복할 횟수               3. 체크할 시간 간격

 

uInt.py - Cli 모드 실행 결과

4F_DMZ_NEXUS_A_1# python uInt.py po1 5 2
  1 >> [ Input ]          9592 bps -       9 pps : [ Ouput ]        126888 bps  -     173 pps  [ 30 seconds]
  2 >> [ Input ]          9264 bps -       9 pps : [ Ouput ]        125600 bps  -     170 pps  [ 30 seconds]
  3 >> [ Input ]          9264 bps -       9 pps : [ Ouput ]        125600 bps  -     170 pps  [ 30 seconds]
  4 >> [ Input ]          9264 bps -       9 pps : [ Ouput ]        125600 bps  -     170 pps  [ 30 seconds]
  5 >> [ Input ]          9328 bps -       9 pps : [ Ouput ]        124000 bps  -     166 pps  [ 30 seconds]
===========================================================================
Max  >> [ Input ]          9592 bps -       9 pps : [ Ouput ]        126888 bps  -     173 pps

 

원하는 대로 결과값이 나온 것 같습니다!!

하지만... 절망.. Cli모드에서 실행을 하게되면 모든 코드가 종료된 이후에 결과가 나오게 됩니다.

이 부분을 실시간으로 나오게 하는게 있는지 확인을 오늘 이래저래.. 구글링을 해 보았으나..

없는 듯 싶습니다. (만약 있다면 알려주세요!!!)

 

그래서 어찌할까.. 하다가... Python Shell 모드에서 실행하도록 변형해봅니다.

 

위에서 만든 코드를 거의 그대로 가져다 쓸 수 있도록 메인 실행 부분을 함수로 변형하고 실행 시의 매개변수를

해당 함수를 호출 할 때의 매개변수로 대체하는 것 이외에는 달라지는 부분은 없습니다.

 

 

uIntmod.py

 # -*- coding: utf-8 -*-
__author__ = 'Network ZIGI'

import cisco 
import time

def CheckInterfaceRate(args):
    inPacketList = []
    inBitList =[]
    outPacketList=[]
    outBitList=[]
    inPacketavg=0
    inBitavg=0
    outPacketavg=0
    outBitavg=0

    for cnt in range(1,args['repeat']+1):
        result = getInterfaceRate(args['intInfo'])
        print '%8d  >>  [ Input ]  %13s bps -  %6s pps   :   [ Ouput ]  %13s bps  -  %6s pps    [ %s %s]' % \

       (cnt,result[0][4], result[0][6],result[1][4],result[1][6],result[0][0],result[0][1])
        inBitList.append(int(result[0][4]))
        inPacketList.append(int(result[0][6]))
        outBitList.append(int(result[1][4]))
        outPacketList.append(int(result[1][6]))
        time.sleep((args['interval']))

    print '==========================================================================='
    print 'Max  >>   [ Input ]  %13d bps -  %6d pps   :   [ Ouput ]  %13d bps  -  %6d pps ' % \

    (max(inBitList), max(inPacketList),max(outBitList), max(outPacketList))

 

def getInterfaceRate(Intinfo):
    intRateCmdResult =cisco.CLI('sh int '+Intinfo,False)
    intRateCmdResultList =intRateCmdResult.get_output()
    for rate in intRateCmdResultList:
        if(-1<rate.find('input rate')):
            inputList = rate.split()
        elif ( -1<rate.find('output rate')):
            outputList = rate.split()
            return inputList, outputList
 
def rate(info,r,step=1):
    args = {'intInfo':info,'repeat': r, 'interval':step}
    CheckInterfaceRate(args)

 

모듈로 만들었으니.. 이제 위의 모듈을 Shell모드에서 import하여 실행해봅니다.

 

 

 uIntmod : Python Shell Mode에서 실행하기

NX-OS# python
Python 2.7.2 (default, Nov 27 2012, 17:50:33)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
Loaded cisco NxOS lib!
>>> import uIntmod
>>> uIntmod.rate('po1',5,2)
       1  >>  [ Input ]           8968 bps -       9 pps   :   [ Ouput ]         122544 bps  -     164 pps    [ 30 secon
       2  >>  [ Input ]           9216 bps -       9 pps   :   [ Ouput ]         123296 bps  -     165 pps    [ 30 secon
       3  >>  [ Input ]           9216 bps -       9 pps   :   [ Ouput ]         123296 bps  -     165 pps    [ 30 secon
       4  >>  [ Input ]           8592 bps -       8 pps   :   [ Ouput ]         122856 bps  -     165 pps    [ 30 secon
       5  >>  [ Input ]           8592 bps -       8 pps   :   [ Ouput ]         122856 bps  -     165 pps    [ 30 secon
===========================================================================
Max  >>   [ Input ]           9216 bps -       9 pps   :   [ Ouput ]         123296 bps  -     165 pps
>>> exit()
NX-OS#

 

Shell 모드에서는 실행할 때, 만든 모듈을 Import하고 메서드를 이용해서 모듈의 기능을 사용합니다.

 

자 이제 실시간으로 한 줄씩.. 원하는 시간간격으로 Interface의 사용량을 확인할 수 있게 되었습니다.

 

Posted by 네떡지기
프로그래밍/Python2014.07.19 13:38

 


이번 포스팅은  Python으로 만들어 보는 예제입니다.

 

제가 Test 가능한 환경이 Cisco Nexus이기 때문에  Cisco Nexus 5548 기준으로 작성된 예제입니다만,

 

기본 CLI명령을 입력하는 부분에서만 Cisco 패키지의 명령을 사용하였기 때문에 변형을 한다면,

 

다른 곳에서 충분히 활용이 가능한(?) 예제가 될 수 있을 듯 싶습니다. 

 

(물론 출력된 문자열이 Nexus 기준에서 가공하여 만든 예제라 문자열 가공을 각 상황에 맞게 일부 변형이 필요합니다)

 

IP를 입력하면, 해당 IP의 MAC주소와 VLAN, Interface, Description 정보를 한 번에 확인할 수 있는 내용입니다.

 

추후에 아래 코드는 조금씩 변형되서 업데이트 버전이 만들 계획이지만, 언제 어떻게 될지는 아직은 알 수 없습니다! ^^;

 

아래 코드는 Github에서도 함께 볼 수 있습니다. 

 

Github 에서 보기 


 

 

 ○ IP Info

 __author__ = 'Network ZIGI - Ko Jae Sung'

  # 2014.07.19. First Version
  #
  # ================================================
  #      IP Info : NetworkZIGI   2014.07.19
  #================================================
  #IP-Address      : 10.0.0.1
  #Mac-Address     : 0012.3456.abcd
  #Vlan            : 11
  #Interface       : Eth14/2
  #Description     : NetworkZIGI Blog Server
  #
  # Blog : http://ThePlmingspace.tistory.com
  #
  # Tested : Cisco Nexus 5548  : 6.0(2)N2(4)

 

  import argparse
  import sys
  import cisco

  IP = 'IP-Address'
  MAC = 'Mac-Address'
  Vlan = 'Vlan'
  Int = 'Interface'
  Desc = 'Description'

  
  IP_info = {IP:'None', MAC:'None', Vlan:'None', Int:'None', Desc:'None'}    # IP정보를 저장할 Dict type 변수

 

  # ARP 정보를 가져오는 메서드

  def get_ARP_Table(ipaddr):
      arpCmd = 'sh ip arp ' + ipaddr
      arpCmdResult = cisco.CLI(arpCmd, False)
      arpCmdResultList = arpCmdResult.get_output()
      for arp in arpCmdResultList:
          if (-1<arp.find(args.ip)):
              return arp
      else:
          print ' %s : Not found IP Address Infomation' % args.ip
          sys.exit()

 

  # IP와 MAC, VLAN 정보를 가져오는 메서드

  def get_IP_MAC_info(info):
      info_list = info.split()
      IP_info[IP] = info_list[0]
      IP_info[MAC] = info_list[2]
      IP_info[Vlan] = info_list[3][4:]

 

  # Interface 정보를 가져오는 메서드

  def get_Interface_info():
      macCmd = 'sh mac address-table addr ' + IP_info[MAC]
      macCmdResult = cisco.CLI(macCmd, False)
      macCmdResultList = macCmdResult.get_output()
      if (len(macCmdResultList) > 6):                                                
          IP_info[Int] = macCmdResultList[5][58:]
          get_Description_info(IP_info[Int])

 

  # Description 정보를 가져오는 메서드

  def get_Description_info(iInfo):
      if(iInfo.find('Eth') == 0 or iInfo.find('Po')==0): 

          intCmd = 'sh int desc | inc ' + iInfo
          intCmdResult = cisco.CLI(intCmd, False)
          intCmdResultList = intCmdResult.get_output()
          IP_info[Desc] = intCmdResultList[0][25:]

 

  # IP 정보 출력

  def show_IP_info():
      print '================================================'
      print '             IP Info : NetworkZIGI              '
      print '================================================'
      print '%-15s : %s' % (IP,IP_info[IP])
      print '%-15s : %s' % (MAC,IP_info[MAC])
      print '%-15s : %s' % (Vlan, IP_info[Vlan])
      print '%-15s : %s' % (Int, IP_info[Int])
      print '%-15s : %s' % (Desc,IP_info[Desc])

 

  # 프로그램 시작 지점

  parser = argparse.ArgumentParser('Args',description='Args Desc')
  parser.add_argument('ip')
  args = parser.parse_args()

  iparp = get_ARP_Table(args.ip)
  get_IP_MAC_info(iparp)
  get_Interface_info()
  show_IP_info()

 

 

 ○ IP Info : 결과

NX-OS# python ipinfo.py 10.10.10.11
================================================
      IP Info : NetworkZIGI   2014.07.19       
================================================
IP-Address                                : 10.10.10.11
Mac-Address                           : 0012.3456.789A
Vlan                                           : 20
Interface                                  : E12/3
Description                              : NetworkZIGI Blog Web Server

 

Posted by 네떡지기
프로그래밍/Python2014.07.15 00:56

이전까지 다뤄졌던 pingrange Python 예제를 변형해봅니다.

 

코드를 모두 짤 수 없다면, 잘 짜여진 기본 에제를 바탕으로 필요한 내용을 수정/보완하는 것도 중요할 것입니다.

물론 그렇게 하기 위해서는 기존 코드를 잘 이해하는 것이 매우 중요합니다.

 

기존 예제 소스를 이해하기 위해서 이론 정리만 했다면 이번 변형 예제는 기존 예제와 달라진 점을 비교해보고

또한 변형 예제에 대해서는 나름대로.. 친절하게 주석을 달았습니다.

물론 이론적인 부분이 함께 알아두고, 코드를 잘 쪼개서 볼 수 있어야 이해가 쉬울 것입니다.

 

 기존 예제 포스팅은 아래와 같습니다.

 

Python for Networker : Part 2                  Python for Networker : Part 3                    Python for Networker : Part 4 

 

기존 예제는 아래에서 볼 수 있습니다.

[ 예제 링크 ] https://github.com/datacenter/who-moved-my-cli

 

※ 본 내용의 진행은 Nexus 5548 6.0(2)N2(4) 기준입니다.

 

※ Modified Version Code는 다음에서 받을 수 있스니다.

      - https://github.com/NetworkZIGI/Python_for_Network

 


 

 

pingrange.py

import re

from cisco import cli

from argparse import ArgumentParser

def expandrange(rangefunc):

    hosts = []

    octets = rangefunc.split('.')

    for i,octet in enumerate(octets):

        if '-' in octet:

            octetrange = octet.split('-')

            for digit in range(int(octetrange[0]), int(octetrange[1])+1):

                ip = '.'.join(octets[:i] + [str(digit)] + octets[i+1:])

                hosts += expandrange(ip)

            break

    else:

        hosts.append(rangefunc)

    return hosts

 

parser = ArgumentParser('pingrange')

parser.add_argument('ip', help='IP range to ping, e.g., 10.1.0-1.0-255 will expand to 10.1.0.0/23')

parser.add_argument('options', nargs='*', help='Options to pass to ping', default=['count 1'])

args = parser.parse_args()

targets = expandrange(args.ip)

for ip in targets:

    tupleping  = cli('ping %s %s' % (ip, ' '.join(args.options)))

    strping = str(tupleping)

    m = re.search('([0-9\.]+)% packet loss',strping )

    print('%s - %s' % (ip, 'UP' if float(m.group(1)) == 0.0 else 'DOWN'))

 

 

기존 pingrange의 변형된 코드의 달라진 점

      IP범위를 잘못 입력했을 경우에 예외 처리를 하였다.  (옥텟별로 1~255 사이)

             : checkRagne 메서드 정의.

             : 잘못된 입력인 경우에는 오류 메시지를 출력하고 시스템을 종료(sys.exit())를 한다.

      지정된 IP범위에서 증가값을 옵션으로 임의로 지정 할 수 있게 하였다.

              : 별도의 범위를 지정하지 않으면, default 1씩 증가한다.

 

 ◇ 기타 대부분의 코드는 아래의 변형된 코드와 유사하기 때문에 변형 코드의 주석과 기존 Part 2~4에서 다루었던 코드 이해하기

     이론 내용 등을 함께 보면 기존 코드를 이해하는 데 도움이 될 수 있을 것 같습니다.

 

 

pingrange Code : Modified Version

import sys                                                             # 시스템 패키지. 시스템 종료 메서드를 호출하기 위해 사용

import re                                                              # 정규식을 쓰기 위한 패키지

import cisco                                                         # Cisco 패키지  : Cli 명령을 사용하기 위해 사용.

from argparse import ArgumentParser               # 실행시의 매개변수를 다루기 위한 패키지

 

def checkRange(checkIP):                                       # 입력받은 IP 옥텟이 IP범위에 해당하는지 확인하기 위한 메서드

    octets = checkIP.split('.')                                  # 입력받은 IP를 '.으로 나눠서 각 옥텟별로 만듬

    for octet in octets:                                            # 각 옥텟이 저장된 List의 항목(IP의 각 옥텟)을 순환

        ip = int(octet)                                              # int 형 데이터로 변경

        if (ip < 0 or ip > 255):                                 # IP의 적정 범위인지 확인하여, 그 이외의 숫자인 경우에는 에러 발생

            print "Invalid Input Value"

            print "IP value is not less than 0 or greater than 255."

            sys.exit()                                                 # 시스템 종료

    return True

 

 

def expandrange(rangefunc,stepcnt):   # 사용자가 요청한 IP 범위 / 체크할 IP띄어쓸 범위

                                                                          # 체크할 IP 범위를 별도로 지정하지 않으면 1default 값으로 함.

    hosts = []                                                      # ping을 확인할 IP를 저장하기 위한 리스트 변수

    step = str(stepcnt[0])                                   # 매개변수 두번째를 리스트 type으로 받기 때문에 문자열 처리를 위해서 변경

    octets = rangefunc.split('.')                         # IP리스트를 옥텟별로 분리하여 LIST 변수에 저장

    for i,octet in enumerate(octets):                 # 옥텍별로 확인

        if '-' in octet:                                            # 만약에 옥텟안에 '-'이 있다면 해당 옥텟은 범위를 뜻하는 것.

            octetrange = octet.split('-')                # IP 범위를 LIST로 분리 (제일 앞 대역과 제일 대역)

            sip = int(octetrange[0])                      # IP 범위의 앞 부분을 sip로 int type으로 저장

            dip = int(octetrange[1])                     # IP 범위의 뒷 부분을 dip로 int type으로 저장

            for digit in range(sip,dip+1, int(step) if i==3 else 1):     

                                                                        # 순환문을 위한 값 지정 : 범위 지정의 첫번째 IP / IP / 증가값

                                         # 증가값의 경우에는 1~3번째 옥텟에는 해당하지 않고, 마지막 옥텟에만 해당되기 떄문에

                                         # 4번째 옥텟일 경우에만(i가 3인 경우가 옥텟이 4번째인 경우임, 0,1,2,3) 증가값을 적용하고

                                         # 그 이외의 경우에는 기본 증가값인 1을 사용한다.

                ip = '.'.join(octets[:i] + [str(digit)] + octets[i+1:])   # 범위의 옥텟전 / 범위옥텟 / 범위 옥텟후를 더해서 IP로만듬

                                        # List의 경우 [] 안에 시작이나 종료점을 쓰지 않으면, 처음부터 끝까지를 나타냄.

                hosts += expandrange(ip,stepcnt)    # 옥텟에서 아직 범위가 있을 수 있기 때문에 다시 expandrage 호출

            break

    else:                                                                        # for문이 break로 종료되지 않고 정상 종료된 경우에 실행.

        if checkRange(rangefunc):                   # for문이 정상 종료된 경우 범위가 지정되지 않은 숫자로만 이뤄진 IP이나

            hosts.append(rangefunc)            # IP가 정상적인 IP범위에 해당하는지 checkRange메서드 호출해서 true인경우만

    return hosts                                          # Host에 IP를 추가하고 리턴해준다.

 

parser = ArgumentParser('AdvPing')

parser.add_argument('ip', help='IP range to ping, e.g., 10.1.0-1.0-255 will expand to 10.1.0.0/23')

                                                                # 매개변수 관리용 : 'ip' 이름으로 매개변수 1번째를 관리

parser.add_argument('options', type=str, default=['1'], nargs='*', help='Options to pass to ping')

                                                                # 매개변수 관리용 : 'options'로 처리하며, typestr로 하고 default값은 '1' 로 한다.

args = parser.parse_args()                     # 매개변수 손쉽게 사용하기 위해서 parse_args()메서드 호출

targets = expandrange(args.ip,args.options)    # IP와 option(IP 증가값)을 가지고 호출

for ip in targets:     # Ping을 체크할 전체 IP 리스트를 순환하면서 실행

    tupleping  = cisco.cli('ping %s' % ip)       # Ping 명령을 실행하고 그에 대한 결과값을 받음.

    strping = str(tupleping) # Tuple형식의 결과값을 str type으로 변형

    m = re.search('([0-9\.]+)% packet loss',strping ) # 정규식을 활용하여 IP가 UP/Down 확인

    print('%s - %s' % (ip, 'UP' if float(m.group(1)) == 0.0 else 'DOWN')) # 해당 IP의 UP/Down 표기

 

 

 

pingrange Code : Modified Version : 결과값

NX-OS# python pingrange2.py 10.9.8.1-200 32

10.9.8.1 - UP

10.9.8.33 - DOWN

10.9.8.65 - UP

10.9.8.97 - UP

10.9.8.129 - DOWN

10.9.8.161 - DOWN

10.9.8.193 - DOWN

 

Posted by 네떡지기
프로그래밍/Python2014.07.13 01:50

 


pingrange Python 예제로 살펴보는 포스팅의 3번째 편이자, 해당 예제의 마지막 편입니다.

물론 다음 편에서 다시 비슷하게 다뤄질 예정이긴 합니다.

 

기본 내용은 지난 포스팅과 이어지게 되며, 예제 소스는 이번 포스팅에도 동일하게 포함하여 보시기 쉽게 하였습니다.

 

혹시 기존 포스팅을 보지 못하신 분은 반드시!

 

Programmability for Networker : Part 2            Programmability for Networker : Part 3

 

을 보고 오셔야 합니다.

 

본 내용에 사용된 에제는 아래에서 볼 수 있습니다.

[ 예제 링크 ] https://github.com/datacenter/who-moved-my-cli

 

※ 본 내용의 진행은 Nexus 5548 6.0(2)N2(4) 기준입니다.

 

 


 

 

pingrange.py

import re

from cisco import cli

from argparse import ArgumentParser

def expandrange(rangefunc):

    hosts = []

    octets = rangefunc.split('.')

    for i,octet in enumerate(octets):

        if '-' in octet:

            octetrange = octet.split('-')

            for digit in range(int(octetrange[0]), int(octetrange[1])+1):

                ip = '.'.join(octets[:i] + [str(digit)] + octets[i+1:])

                hosts += expandrange(ip)

            break

    else:

        hosts.append(rangefunc)

    return hosts

 

parser = ArgumentParser('pingrange')

parser.add_argument('ip', help='IP range to ping, e.g., 10.1.0-1.0-255 will expand to 10.1.0.0/23')

parser.add_argument('options', nargs='*', help='Options to pass to ping', default=['count 1'])

args = parser.parse_args()

targets = expandrange(args.ip)

for ip in targets:

    tupleping  = cli('ping %s %s' % (ip, ' '.join(args.options)))

    strping = str(tupleping)

    m = re.search('([0-9\.]+)% packet loss',strping )

    print('%s - %s' % (ip, 'UP' if float(m.group(1)) == 0.0 else 'DOWN'))

 

 


 

 

[ 매개변수 ]

 

명령줄 매개변수

     •Python Script 실행 시에, 사용되는 매개변수는 sys.argv에 리스트 형태로 전달된다.

     리스트의 첫 번째 값은 해당 Script의 이름이고, 그 이후의 값이 실제 매개변수가 된다.

        따라서, sys.argv[1:] 으로 하면 실제 매개변수의 값만 리스트로 뽑을 수 있다.

     argparse 모듈을 사용 할 경우에는 매개변수에 대한 작업을 좀 더 편하게 할 수 있다.

 

argparse

     •class argparse.ArgumentParser(prog=None, usage=None, description=None, epilog=None, parents=[],

                                           formatter_class=argparse.HelpFormatter, prefix_chars='-', fromfile_prefix_chars=None,

                                           argument_default=None, conflict_handler='error', add_help=True)

     ArgumentParser 클래스는 실행 시의 매개변수에 대한 값을 손쉽게 처리하도록 매개변수의 값을 argparse 객체로 만들어 준다 .

     add_argument 메서드는 매개변수를 어떻게 분석하여 처리할지에 대한 부분 지정한다.

 

 

Args1.py : Code

import sys

argvList = sys.argv

for ar in argvList:

    print 'argv : %s' % ar

 

Args.py : 실행

>>> python  Args1.py 2014 ZIGI JaeSung

argv : I:/Network/Nexus/py/Args1.py

argv : 2014

argv : ZIGI

argv : JaeSung

 

Args2.py : Code

import argparse

parser = argparse.ArgumentParser('Args',description='Args Desc')

parser.add_argument('year', type = int)

parser.add_argument('nick', type = str)

parser.add_argument('name')                               # Type 미지정 시에는 Default로 Str Tytpe

args = parser.parse_args()

print "2014=%d , nick=%s , name=%s" % (args.year, args.nick, args.name)

 

Args.py : 실행

>>> python  Args.py 2014 ZIGI JaeSung

year=2014 , nick=ZIGI , name=JaeSung

 


 

 

[ 정규식 ]

 

❖ 정규식

     - 복잡한 문자열 패턴을 검색/추출/대치하는 규칙

 

re 모듈

     - Python에서 정규식을 사용하기 위해 제공하는 모듈

  

meta 문자

     - 문자나 문자 패턴을 반복의 표현을 나타나는 문자

 

     ▷ 메타 문자 [반복]

 

 Meta 문자

 내용

 예제

*

  문자를 0회 이상 반복

 Zi*Gi : ZGI, ZiGi, ZiiiiiiiiGi

+

 앞 문자를 1회 이상 반복

 Zi+Gi : ZiGi, ZiiiiiGi

?

 앞 문자를 0 or 1회 반복

 Zi?Gi : ZGi, ZiGi

{m}

 앞 문자를 m회 반복

 Zi{3} : Ziii

{m,n}

 앞 문자를 m~n 회까지 반복

 Zi{2,3} : Zii, Ziii

 

     ▷ 메타 문자 [매칭]

 

 Meta 문자

 내용

 예제

.

 개행문자를 제외한 모든 문자와 매칭

re.DOTALL 모드 시에는 개행문자 포함하여 매칭

 Z.Gi : ZiGi ZzGi, Z1Gi

^

1. 문자열의 시작과 매칭

   re.MULTILINE 모드에서는 각 줄의 시작과 매칭

2. 메타 문자 [ ]안에서는 해당 문자 예외

^ZiGi : ZiGi of Network (O) , Network ZiGi(X)

 

Z[^i]Gi : ZkGi, ZlGi (O) , ZiGi (X)

$

문자열의 마지막과 매칭

메타 문자 [ ] 내부에서는 순수한 $의 의미로 사용

$ZiGi : Network ZiGi (O), Network ZiGis (X

[ ]

 문자 집합 안에 속한 한 문자를 의미

‘-’로 범위지정 가능

 Z[hij]]Gi : ZhGi, ZiGi, ZjGi

 Z[a-z]Gi

|

 Or

 Zi|oGi : ZiGi, ZoGi

( )

정규식을 그룹으로 지정

정규식 내부에서 그룹을 만들고,

각 그룹을 Index에 따라서 가져올 수도 있다.

, Index를 벗어나게 될 경우에는 예외처리된다

 m = re.match('\s*([0-9]+) ([0-9]+)', ' 123 12')

print m.group(0)                 : ‘ 123 12’

print m.group(1)                 : ‘123’

print m.group(2)                 : ‘12’

 

 

      ▷ 메타 문자 [특수문자]

 

 Meta 문자

 내용

 예제

\\

‘\’ 자체를 문자로 인식

 Z.Gi : ZiGi ZzGi, Z1Gi

\d

 모든 숫자와 매칭

[0-9]

\D

 숫자가 아닌 모든 문자와 매칭

 [^0-9]

\s

공백이나 탭등의 문자와 매칭

[\t\n\r\f\v]

\S

공백이나 탭등이 아닌 문자와 매칭

[^ \t\n\r\f\v]

\w)

숫자 혹은 문자와 매칭

[a-zA-Z0-9]

 

 

match() vs search()

     •match

         - 문자열의 시작지점에서부터 일치하는지 확인

     •search

         - 문자열 내부에 부분적으로 일치하는 것이 존재하는지 확인

Ex)

     >>> re.match("c", "abcdef")  # No match

     >>> re.search("c", "abcdef") # Match

 

 


 

 이번 포스팅으로, git에 올라와 있는 Nexus pingrange 예제를 알아보기 위한 Python 내용을 살펴보았습니다.

각 항목별로 물론 더 많은 이론 내용이 있겠지만, 이번 포스팅의 중점은 코드를 이해하기 위한 기술 수준에서만 정리를 했습니다.

물론 조금 더 이해하기 쉽게(?)하기 위해 비교를 위해서 딱 코드에 있는 내용만 있지는 않고 +a의 내용이 있습니다.

각 코드별로 좀 더 이해를 돕기 위한 내용은 이번 pingrange에서는 하지 않았습니다.

물론 정리해놓은 기술 내용을 기반으로 보실 수 있기는 합니다만, 그래도 좀 더 각 줄 별로 주석을 달아드리겠지만

이번 코드가 아닌 다음 포스팅에서 다뤄질  pingrange의 변형 코드에서 할 예정입니다.

그 전까지는 코드를 먼저 나눠서 기술 내용을 바탕으로 이해해 보시면 좋을 듯 싶습니다.

 

아래는 pingrange를 이해하기 쉽게 하기 위한 각 실행 범위별 구간이니(Part 3에서 다뤄지기도 했습니다.),

참고하시면 좋을 것 같습니다.

 


 

 

Posted by 네떡지기

티스토리 툴바