네트워크 장비 제어를 위한 추상화 API - 1

dingdong·2022년 1월 14일
0

네트워크 장비 제어를 위해 했던 여정 🚗

고민거리 🤔

네트워크 장비를 제어하다보면
같은 기능인데
장비 제조사에 따라서 CLI 가 다르고
같은 제조사라도 시기에 따라서 CLI 스타일이 다르고
같은 제조사라도 vender 의 요청으로 인해서 조금씩 다른 상황을 경험하게 되었다.


예를 들어본다면
"안녕하세요" 라는 기능을 수행시키려면
각 장비마다 설정 방법이 다른 상황을 경험 할 수 있다.



CLI가 다르다보니 자동화 개발자 입장에서 아래와 같은 고민이 생겼다.

1) 코드 중복을 줄이고 싶다.

1) 장비별로 코드를 복사해서 CLI 가 다른부분만 바꿔준다. (비효율적이다.)

2) 경험이 부족한 사람은 설정을 헤맨다. learning curve 를 줄여 주고 싶다.

2) CLI가 다르면 경험이 부족한 사람의 경우 설정 방법을 해맬 수 있다.



1차 방법: 접근 방법 ❗

예를 든다면 아래와 같은 상속 구조로 디자인을 했었다.

pseudocode


Class AllGroupCommon(object):
  def __init__(self, 데이터들):
      telnet 접속하기
      login 하기
  
  @abc.abstractmethod
  def get_mactable(self):
     pass
  
  @abc.abstractmethod
  def set_port_disable(self):
     pass
     
  def get_config(self):
     # 모든 장비가 동일한 명령을 사용할 경우
     장비로_부터_받은_정보 = CONFIG_정보_확인 명령 실행
     return 장비로_부터_받은_정보
  

Class AGroupCommon(AllGroupCommon):
  def get_mactable(self):
     장비로_부터_받은_정보 = MAC_정보_확인 명령 실행
     return 장비로_부터_받은_정보
  
  def set_port_disable(self):
     장비로_부터_받은_정보 += PORT_DISABLE_실행전_모드로_접속
     장비로_부터_받은_정보 += PORT_DISABLE_실행
     장비로_부터_받은_정보 += PORT_DISABLE_실행후_모드_나가기
     return 장비로_부터_받은_정보
     

API 사용 방법 예시

  • 아래 같은 느낌으로 접근할 수 있도록 작업하여었다.
  • 장비.기능분류.함수명(필요한 데이터) 호출시
    장비에 따라서 "안녕하세요", "你好", "Hello" 명령을 수행한다.

장비.기능분류.함수명(필요한 데이터)

1차 방법: 무언가 단단히 잘못되었다 💦

사용하다보니 여러 문제점들이있었다.

1. 명령 입력 전/후 모드 이동 문제

  • 네트워크 장비 설정 예시 : port disable 과정
# config terminal
(config)# interface ge1/1
(ge1/1)# shutdown
(ge1/1)# exit
(config)# exit
#
port ge1/1 를 disable 했다가 Enable 할 경우
  • 1차 방법의 문제점: 비효율적인 모드 이동
# config terminal
(config)# interface ge1/1
(ge1/1)# shutdown
(ge1/1)# exit
(config)# exit
#
# config terminal
(config)# interface ge1/1
(ge1/1)# no shutdown
(ge1/1)# exit
(config)# exit
#
  • 원했던 sequence: 효율적인 모드 이동
# config terminal
(config)# interface ge1/1
(ge1/1)# shutdown
(ge1/1)# no shutdown
(ge1/1)# exit
(config)# exit
#

위와 같은 상황 처럼
비효율적으로 모드를 이동하여 소요시간이 오래 걸리게됨.

2. 빈번해지는 코드 중복이 발생됨

  • Model2는 AGroupCommon 이랑 70% 일치하고 BGroupCommon 이랑은 30% 일치하는 이런 경우가 빈번하게 발생하게 되었다.

3. 장비의 Command 기능과 Session (telnet) 와의 의존성 문제

  • connector 와 장비 기능(feature) 을 따로 디자인 하는게
    의존성을 줄이는 방법이였다.

4. SSH, Serial(direct) 등 사용이 필요해짐 (지원하는 Session 종류를 늘려야됨)

  • telnet 이외의 세션 접속 방법에 대해서 다양화가 필요했다.

5. 윈도우 환경에서도 API 사용이 필요해짐

  • 1차 방법은 리눅스 디펜던시가 있는 상태였다.


1차 방법: 회고 ☕

1) 디자인 단계에서 다양한 CASE 를 확보하지 못했었다.

  • 다양한 네트워크 장비에 대한 경험이 부족하였다.

2) 개발관련 지식이 부족하였다.

  • 이때 당시 나 포함하여 프로젝트를 참여하신분들이 개발을 시작한지 얼마 안된 시점이였다.
    그래서 지식적으로도 많이 부족하였었다.
  • 'Model1과 Model2가 겹치네!' 묶어서 상속받는 구조로 가자 해서 만들어진 디자인이다.
  • 디자인 패턴에 대해서도 몰랐었다.
    이때 당시 저 방식이 Factory Pattern 인지도 몰랐었다.

나는 이번 1차 방법 실패를 통해서
사전 조사의 중요함을 알게되었다.
개발의 대상이되는 것에 충분히 파악해야되고
여러 USECASE 에 대해서 충분한 확보가 필요하다는 것을 알게되었다.
사전조사가 미흡 할수록 설계가 자칫 산🌄 으로 갈 수 있다는 것을 알게 되었다.



1차 방법: 결국 폭발 💣

2019년 1월 9일
4명이서 1년 넘게 작업한 프로젝트를 폭발시켰다. 💣
위의 나열한 문제점들로 인해서 다시 처음부터 시작을 하기로 결단을 내렸었다.
1년 넘게 한 프로젝트를 폭발하였지만 나는 개인적으로 아쉽거나, 미련이 남지는 않았다.

왜냐면 나는 미련이 남았던 경험이 있었다.
Python 을 처음 시작하였을때
나의 멘토 분께서 코드리뷰의 시간을 가지면서
내가 어떠한 의도로 코드를 작성했는지에 대해서 설명하고 피드백을 받는 시간을 가졌었다.
어떠한 과제를 받고, 나 나름대로 열심히 했지만
결국 코드를 날리고, 다시 해야되는 상황이였다.
나는 매우 실망을 했었던거 같다.😔
그때 멘토분께서 이런 말씀을 해주셨었다.
너의 코드를 너무 사랑하지마 라고 ...

너의 코드를 너무 사랑하지마 라는 말은
아직도 나의 개발할때의 마음가짐 중 중요한 하나이다.
개발을 할때 당시에 나는 열렬히 최선을 다해서 만들었겠지만
어느 순간 돌이킬 수 없는 문제가 발생되었다면
고칠 수 없을 지경이라면
더 좋은 방식이 있다면
과감하게 놓아주어야된다고 생각한다.

profile
자동화 개발

0개의 댓글