'Programmability'에 해당되는 글 23건

  1. 2014.07.08 Programmability for Networker : Part 3
  2. 2014.07.02 Programmability for Networker : Part 2
  3. 2014.06.18 Programmability for Networker : Part 1 (1)
프로그래밍/Python2014.07.08 02:49

 


 

이번 포스팅은 지난 포스팅에 이어서 실제 Python 예제를 통해서 보려고 합니다.

기본 내용은 지난 포스팅과 이어지게 됩니다.  예제 소스는 기존 포스팅과 함께 왔다리 갔다리

하기 힘드실 듯하여... 해당 예제 포스팅이 끝날 때까지 계속 포함할 예정입니다. 

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

 

Python for Networker : Part 2

 

을 보고 오셔야 합니다.

 

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

[ 예제 링크 ] 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 코드 실행 순서

  -  Active한 대화명 프롬프트 모드에서의 Python 실행이 아닌, Python 스크립트 코드를 보면서 어떻게 실행이 되는지

    혹시라도 헛갈리실 수 있을 듯 싶어서, 간단하게 위의 코드를 보면서 어떤 순서로 실행되는 보려고 합니다.

  - 우선 모든 코드는 제일 위에서부터 차례대로 진행이 되기 때문에 지난 Part 2에서 얘기된 필요한 Python 모듈을 먼저 Import

    하는 것으로 코드가 시작이 됩니다. 실제 아래 정의되는 실행부분에서 해당 모듈의 내용을 사용해야 하기 때문에 Python 모듈을

    Import하는 것이 당연히 제일 먼저 선언되어야 할 것입니다.

  - 그리고나서는 순서대로 실행이 되어야 하나, 위에서 보면 def 키워드로 expandrange() 함수가 선언되어 있습니다.

    함수는 바로 실행되지는 않기 때문에 expandrange() 함수 영역까지 (상단에서 보면 return host 부분)는 실제 바로 실행되지는

    않습니다.

  - 함수 선언부가 지난 이후에 일반 실행 코드가 순서대로 실행이 되게 됩니다.

  - 그리고 targets = expandrange(args.ip)에서 상단에 선언한 함수를 호출을 하게 됩니다. 그러면 당연히 Def로 선언한 함수

    선언부의 첫 줄부터 실행을 하게 되고, return host 부분까지 실행 후에는 해당 함수를 호출했던 라인으로 복귀를 하게 됩니다.

  - 그 다음에는 for문을 순환한 이후에 프로그램이 종료하게 됩니다.

  - 별다른 내용은 아니긴 하지만, 코드를 보면서 def나 class로(앞으로 다뤄질) 지정된 부분은 그 해당 라인에서 바로 실행이 아니라

    해당 내용을 사용하기 위한 선언부이기 때문에 실행 해당 내용이 실행되는 시점은 아래 실행 코드에서 해당 선언부를 호출하는

    경우가 되게 됩니다. 

 

 


 

 

 

python 문자열 다루기

      - Network 장비에서의 Python 사용에 있어서 가장 많이 활용하기 위해서 사용하는 부분이 문자열을 어떻게 다루느냐가 아닐 듯

       싶습니다.  물론 만약에 장비에서 얼마나 많은 종류의 자체 Python 모듈을 제공하느냐에 따라서 이 부분이 달라질 수 있을 듯

       싶지만, 그렇다고 하더라도 문자열을 가지고 활용할 수 있는 방법은 많을 것 같습니다. 이번 포스팅에서는 이런 문자열 다루기에

       대해서 다뤄봅니다. 아래 내용은 위의 코드를 이해하는 데 가장 많이 사용되는 부분이니, 꼭! 중요하게 읽어보셔야 할 것이라~

       생각해봅니다.

  

문자열 선언

   문자열을 선언하는 방법에는

       문자열’ , “문자열” , ‘’’다중라인 문자열‘’’, “””다중 라인 문자열“””

   •’, “ 모두 표기 가능하게 하여, 문자열 안에 를 넣으려고 할 때에는 문자열 안에 기호와 반대로 문자열을 묶어주면 안의

      기호는 문자열 기호가 아니라 단순히 ‘, “ 의 역할만 하게 된다.

       , “Network” ZIGI를 표현하고 싶을 경우에는 로 묶어서 ‘ “Network” ZIGI ‘ 쓰면 된다.

 

문자열 슬라이싱

   문자열[시작Idx:종료Idx-1]   : 문자열을 시작 Index 지점부터, 종료 Index – 1까지 의 문자열을 잘라낸다.

   시작 Index와 종료 Index를 각각 생략하게 되면, 각각 최초 시작 지점/종료 지점을 가리키게 된다.

 

❖ 문자열 연산

   문자열을 ‘+’로 합치는 경우에는 두 문자열 사이에 공백이 없이 합쳐지고, ‘,’로 합치는 경우에는 두 문자열 사이에 공백이

     들어가면서 합쳐지게 된다.

 

❖ 문자열 Formatting

   •print 시에 %s, %c, %d 등으로 지정하여 원하는 데이터 값을 출력 할 수 있다.

   Formatting 코드에 맞춰서 값을 넣어야 하지만, %s로 지정할 경우에는 자동 변환이 되서 들어가게 된다.

   문자열 내에 %를 사용하여 Formatting 시에는 %를 일반 문자로 출력하려면 %%로 써야 출력이 된다.

      하지만, 문자열 내에 % 사용한 Formatting이 없으면 그냥 %만 써도 된다.

   •%숫자s 과 같이 %Formatting 코드 사이에 숫자를 넣으면 해당 크기만큼 공간을 할당해서 출력하게 된다.

       이 때에 숫자를 로 입력하면 해당 공간만큼 할당하여 문자열을 왼쪽 정열하여 출력하게 된다.

  

%s 문자열 (String)

%c 문자 한개(character)

%d 정수 (Integer)

%f 부동소수 (floating-point)

%o 8진수

%x 16진수

%% Literal % (문자 '%s' 자체) 

 

Formatting Example Code

Example Code Result

print "I warn %d won." % 100

print "Americano %d won. Latte %d won" % (3900,4600)

print "My Name is %s" % ("Network ZIGI")

I warn 100 won.

Americano 3900 won. Latte 4600 won

My Name is Network ZIGI

print "%15s %s" % ("Network", "ZIGI")

print "%-15s %s" % ("Network", "ZIGI")

        Network ZIGI

Network         ZIGI

 

문자열 Method

•find(keyword, [start, [end]])   / rfind(keyword, [start, [end]])

     - 문자열에서 Keyword가 위치한 첫 번째(rfind는 뒤에서부터 첫 번째) Index리턴하고, 해당 Keyword가 존재하지 않으면

       ‘-1’을 리턴

•index(keyword, [start, [end]])

     - find() 와 동일한 동작을 하지만, Keyword가 존재하지 않을 경우에 ‘-1’이 아닌 ValueError 예외를 발생.

•join(sequence)

      - sequence 형변수를, Join을 호출한 문자열로 연결해서 리턴하는 메서드이며, split()와 반대의 역할을 하게 됨.

•partition(separator)

      - 문자열을 separator을 나누게 되는 데, separator , separator , separator 뒤의 3개의 Tuple로 리턴.

lstrip([chars])

      - 문자열의 왼쪽을 제거.chars을 지정하지 않으면 공백 문자를 제거.

 

 

Join / Partition / lstrip Example Code

 Join / Partition / lstrip Example Code Result

str1 = '-'

joinstr = str1.join("abc")

print(joinstr)

 a-b-c

str1 = "Network ZIGI Good"

partStr = str1.partition("ZIGI")

print(partStr)

part1 = partStr.__getitem__(2)

print(part1)

part1 = part1.lstrip()

print(part1)

 

('Network ', 'ZIGI', ' Good')

 Good

Good

 

•Split([separator, [maxsplit]])

      - separator로 문자열을 분리하는 것은 Partition과 동일하나, Partition의 경우에는 separator도 함께 리턴되지만,

        split는 해당 separator 기준으로 분리가 되면서 포함되지 않는다.

      - 뒤에 Maxsplit의 값을 주게되면, 앞에서부터 분리되는 개수의 max 값을 지정할 수 있다

Strip([chars])

      - 문자열 양쪽 끝을 잘라내는 데, 별도의 chars를 지정하지 않으면 공백을 제거하고 chars 지정 시에는 해당 문자가 포함된

        모든 내용이 삭제 된다

 

 

Split Example Code

Split Example Code

str1 = "Network ZIGI Good Split Test"

partStr = str1.partition("ZIGI")

print(partStr)

str2 = str1.split()

print(str2)

str3 = str1.split("ZIGI")

print(str3)

str4 = str1.split(' ',2)

print(str4)

 

('Network ', 'ZIGI', ' Good Split Test')

['Network', 'ZIGI', 'Good', 'Split', 'Test']

['Network ', ' Good Split Test']

['Network', 'ZIGI', 'Good Split Test']

 

 

 

Posted by 네떡지기
프로그래밍/Python2014.07.02 18:17

 

 


 

이번 포스팅은 실제 Python 예제를 통해서 보려고 합니다.

코드에 대한 상세 내용은 내용은 추가적인  포스팅으로 예제들과 함께 다뤄질 예정입니다.

이번 포스팅은 '이런 것도 할 수 있구나?'

 정도의 느낌의 포스팅이라고 보시면 좋을 듯 싶습니다.

이번 포스팅에 사용된 예제는 github.com에서 보실 수 있습니다.

 

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

 

우선 예제를 보기 전에 몇 가지 정리를 해봅니다.

 

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

 

 

 


 

Python Script

    •Python ScriptNX-OS의 기본적으로 bootflash://’ 에서 실행된다.

 

   NX-OS# dir

    …

        Mar 10 07:38:37 2009  pingrange.py

    ...

   NS-OS#

 

    기본 CLI Mode에서의 Python Script 실행 시에는 python 키워드를 사용하여 아래와 같이 실행 할 수 있다.

                 NX-OS# python pythonFileName.py { args,.. }

 


 

 

pingragne.

 

    •pIng을 확인할 때, '-'를 사용하여 range를 주어서 확인이 필요한 IP대역에 대해서 확인을 할 수 있다.

    •range는 각 옥텟별로 구성이 가능하다.

             Ex) 1.1.1-2.3-4       : 3번째 옥텍에서 1과 2에 대해서 각각 4번째 옥텟의 3,4번 IP에 대해서 Ping Check.

                                               즉, 1.1.1.3 / 1.1.1.4 / 1.1.2.3 / 1.1.2.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'))

 

 

pingrange.py 실행결과

NX-OS# python pingrange.py 10.1.1-2.1-3

   10.1.1.1 – UP

   10.1.1.2 – UP

   10.1.1.3 – DOWN

   10.1.2.1 – UP

   10.1.2.2 – UP

   10.1.2.3 – DOWN
NX-OS#

 

 


 

pingrange 이해하기 위한 기반 내용들을 하나씩 볼 예정이며, 이번 내용에서 몇 가지만 살펴보게 됩니다.

    Data type과 제어문에 반복문에 대한 부분은 기존 제 포스팅을 참조하셔도 됩니다.


 

 

○ 패키지 Import

     import 패키지명

         - 모듈 이름으로 Import하며, 사용 시에는 패키지명.멤버메서드명 으로 사용한다.

     from 패키지명 import 멤버

         - 실제 사용하고자 하는 멤버를 Import하며, 해당 멤버가 포함된 패키지도 함께 from 키워드로 지정해준다.

         - 즉 어떤 패키지로부터(from), 사용하고자 하는 멤버를 가져온다(import) 의미로 보며,

           실제 사용 시에는 멤버명으로 바로 사용 한다.

○ 패키지를 Import 시에는 해당 패키지의 멤버를 가져올 수도 있지만, 해당 패키지의 일반 명령어 라인도 함께 실행하게 된다.

    따라서, Import하여 사용하게 될 경우에 의도하지 않은 일반 명령어 라인을 실행하지 않게 하기 위해서는 일반 명령어를

    [ if __name__ == ‘__main__’ : ] 조건 내부에 넣는다.

    그렇게 되면, 해당 패키지는 독립적으로 실행하는 경우에는 해당 일반 명령어 라인으로 실행하고 Import 시에는 조건이 맞지

    않으므로 일반 명령어 부분은 실행되지 않는다.

      ※ 범위 / Scope에 대한 부분은 기존 Python 포스팅을 화면하면 됩니다. 코드상으로 볼 때 동일한 들여쓰기를 한 구간이

          하나의 범위가 되게 됩니다. 세부적인 부분일 수록 들여쓰기가 많아지며, 들여쓰기가 적은 부분은 그 하위 들여쓰기한 부분의

          범위를 포함하게 됩니다.

 

File

npy2.py

npy1.py - 1

npy1.py -2

Source

def sum(a,b):

    return a+b

if __name__ == "__main__":

    print "Non-Import Auto Run"

else:

    print "Import Auto Run"

 

import npy2

print "10 + 20 = %d " % npy2.sum(10,20)

 

from npy2 import sum

print "10 + 20 = %d " % sum(10,20)

 

결과값

Non-Import Auto Run

Import Auto Run

10 + 20 = 30

Import Auto Run

10+20=30

 

Posted by 네떡지기

Last Updated : 2014.07.02

 


 

Network 장비에서 Python을 활용한 부분에 간단히 정리를 해보려고 합니다.

우선 처음 진행 부분은 현재 실제 테스트가 가능한 Nexus 7000 / 5000으로 먼저 간단히 시작합니다.

물론 완전 초기 부분이라서, 아마도 잘못된 부분 등에 대해서는 업데이트가 지속적으로 필요할 것 같습니다.

그리고 Nexus에서는 9000 / 3000 시리즈 기반으

Python 활용도가 더 높은 것으로 알고 있지만..(잘못 알고 있을수도? ^^)

현재 테스트가 가능한 부분이 Nexus 7000과 5000이라 이것으로 시작하며, 추후에 다른 테스트 장비(VM포함)로..

추가적인 포스팅을 진행할까합니다.

 

 


 

Cisco Nexus 7000  Python 특징

 Nexus 7K에서는 Python 2.7.2Interactive / noninteractive(script)에 대한 모드를 모두 지원합니다.

 NX-OS 6.2(8) 부터는 JavaScript Object Notation(JSON)logging module을 지원합니다.

 

 

Cisco Nexus 5000  Python 특징

 Nexus 5K에서는 Python 2.7.2모든 Feature를 사용할 수 있다.

 • Python Script를 이용하여 다음과 같은 기능을 구현할 수 있다.

       -  Swtich Bootup 시에 Configuration을 확인하는 Script 실행

       - Configuration 백업

       - Monitoring Buffer 이용량에 따라서, 사전에 혼잡 관리가 가능

       - 일정 시간 간격으로 작업을 수행

       - 프로그래밍 방식으로 SwitchCLI 명령을 수행하고 다양한 업무에 활용 가능

 

 

Third Party Pure Python Packages

 •Nexus에서 Third Party Python Package를 다음과 같은 방법으로 설치하고 사용할 수 있다.  

    ) ZIGI.tgz 를 서버로부터 복사하여 설치하는 경우.

     Step 1. 다음의 명령으로 tar fileSecure Copy 한다.

                      copy scp://user@server/path/to/ZIGI.tgz bootflash:ZIGI.tgz vrf management

     Step 2. Packge의 압축을 해제

                      tar extract bootflash:ZIGI.tgz

     Step 3. 압축이 풀린 Packgebootflash로 옮긴다

                      move bootflash:ZIGI/* bootflash:          

     Step 4. PackgeInstall 한다.

                      python setup.py install

     Step 5. bootflash에 복사된 파일을 제거한다.

     Step 6. Python Mode에서 해당 Packge를 사용한다.

                      NX-OS# python

                      >>> import ZIGI

 

 

 

Python 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!

 >>> exit()

NX-OS#

 

 

 

 

Python 모드에서 Cli  명령 

 

 API

내  용 

1.  NX-OS# >>> cli("명령어")
    string = cli(“
명령어”)

 Python Mode에서 NexusCLI 명령어를 실행하고 Raw 결과를 리턴받게.

‘;’ 이용하여 다수의 명령어를 한 줄에 실행 가능

제어/특수 문자도 함께 출력. 이는 ‘\n’과 값도 함께 출력된다는 것을 의미하며,

    이는 가독성을 떨어지므로, clip() 명령을 사용하는 것이 보다 가독성에 좋다

2. NX-OS# >>> clid(“명령어”)

    dictionary= cli(“명령어”)

XML을 지원하는 CLI 명령어로 결과를 Dictionary 형식으로 리턴 받게 됨.

3. NX-OS#>>> Clip(“명령어”)

CLI 명령어에 대한 결과를 표준 Output으로 출력을 하며, 별도의 리턴 값은 없다.

 clip(“명령어”) r = cli(“명령어”) , print r  은 동일한 역할을 한다.

※ Nexus 7000 기준이며, Nexus 5000에서는 cli만 지원이 됩니다.

 

 Python Mode / CLI Mode 관련

 •Python Mode에서 Cli 명령을 사용하여 Switch Mode를 변경하는 경우에, Python Mode를 벗어나게 되면 변경된 Switch
   
Mode  유지되지는 않고, Python Mode 들어올 때의 기존 Mode로 가게 된다.

 •Python Mode에서 선언된 Data는 해당 Python Shell에서만 유효하며, Shell을 나간 후에 다시 들어오게 되면 사용 할 수 없게 된다. 

 

EX-1

EX - 2

NX-OS# python

NX-OS# >>> cli("conf t")

NX-OS(config)# >>> cli(“int e1/1”)

NX-OS(config-if)# >>> exit

NX-OS# 

NX-OS# python

NX-OS# >>> ZIGI = “JaeSung

NX-OS# >>> print ZIGI

JaeSung

NX-OS# >>> exit

NX-OS# python

NX-OS>>> pint ZIGI

Error:variable ‘ZIGI’ undefined

 

 

Posted by 네떡지기

티스토리 툴바