<img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=939333007162424&amp;ev=PageView&amp;noscript=1">

Google Form과 NAC REST API 를 이용한 IP 신청
(Sheet 버전)

제품을 개발할 때 다양한 고객들의 요구 사항을 모두 수용하기는 현실적으로 어렵습니다. 하지만 연동을 위한 API 들이 추가되고 편하고 접근성이 좋은 서비스들이 시중에 나와있기 때문에 이들을 이용하여 고객의 요구 사항을 직접 구현해볼 수 있습니다.

이에 Google Form과 RESTful API를 활용한 고객 맞춤 서비스 아이디어를 소개하려고 합니다. 본 문서는 이 서비스의 개념, 시나리오, 구현 방법 등을 상세히 설명하여 NAC와 IP 신청 시스템을 운영 시 참고하실 수 있도록 작성되었습니다.

 

개념 소개

  1. Genian NAC의 RESTful API
    내부 자산과 사용자를 보호하고 기업 자원을 안전하게 사용할 수 있도록 지원하는 유무선 네트워크 접근제어 솔루션인 Genian NAC 에서는 해당 자원들을 접근하고 통제할 수 있는 기능 및 IP 신청 등을 REST API로 제공하고 있습니다.

  2. Google Form
    Google Form은 구글에서 제공하는 무료 웹 기반 설문조사 도구 입니다. 간편한 설문지 생성, 실시간 응답 수집, 다양한 공유 옵션, 통계분석 기능과 부가기능을 제공합니다. 설문지 생성 시 Script가 동작하도록 설정할 수 있으며 구글폼을 통해 사용자에게 IP 신청을 받는 용도로 활용합니다.

  3. Google Apps Script
    Google에서 제공하는 클라우드 기반 스크립팅 플랫폼 입니다. 이를 활용하여 Google 제품군과 통합하여 맞춤형 애플리케이션을 빌드할 수 있습니다.
    Google 워크스페이스, Gmail, 드라이브, Sheets 등의 통합환경에서 Javascript 기반 스크립트를 작성하며 특정 이벤트에 맞춰 스크립트를 실행하는 트리거와 이벤트 및 API 연동을 클라우드 기반으로 무료 및 저비용으로 사용할 수 있는 도구 입니다.

 

시나리오

본 문서에서 다루는 시나리오는 이와 같습니다.

1. 사용자가 Google Form 으로 신청 내용 작성
2. Google Sheets 에 신청 내용 등록
3. 신청한 내용을 바탕으로 IP 신청
4. 관리자가 Google Sheets에서 승인으로 값 변경
5. 관리자가 승인한 IP 신청서 승인

간략하게 그림으로 표현하면 아래와 같습니다.

 Google Form과 RESTful API를 활용한 고객 맞춤 서비스 시나리오
[그림 1] Google Form과 RESTful API를 활용한 고객 맞춤 서비스 시나리오

 

사전 준비 및 구현

1. Genian NAC

Google Apps Script에서 NAC의 API를 호출하기 위해서는 네트워크 접근이 가능해야 하기 때문에 클라우드 기반의 NAC 환경이거나 NAC에 접근할 수 있도록 도메인 설정을 먼저 해야 합니다. 여기에서는 접근 편의성을 위해 Test용 Cloud NAC를 생성하여 진행합니다.

(1) Cloud NAC 사이트 생성

Cloud NAC 사이트 생성[그림 2] Cloud NAC 사이트 생성


(2) 센서 설정 및 API Key 발급

  • IP 신청을 하기 위해서는 관리하고 있는 네트워크에 NAC 센서를 연결하여 생성한 사이트에 등록해야 합니다. NAC 센서 생성 및 설정은 Genian NAC Documents를 참고하세요.

  • API 연동을 위해서는 관리자의 API Key를 생성해야 합니다.
    관리 > 사용자 > 관리자의 상세 화면에서 API Key를 생성할 수 있습니다.

NAC API Key 생성[그림 3] API Key 생성 화면

  •   해당 Key는 생성할 때만 확인할 수 있기 때문에 분실하지 않도록 보관합니다.

 

(3) 센서 Node ID 확인

  • IP 신청을 할 때 NAC 센서를 선택해야 하는데 선택할 때의 Key가 되는 Node ID를 확인합니다.
  • 시스템 > 센서 설정 > 센서 상세 화면의 노드 ID 확인

노드 ID 확인 화면[그림 4] 노드 ID 확인 화면



2. Google Form

(1) 사용자에게 IP 신청을 받을 수 있는 Google Form의 항목을 설정합니다.

  • Google Drive 의 메뉴에서 Google 설문지 메뉴 선택

구글 설문지[그림 5] Google Drive 설문지


(2) IP 신청서 작성 시 필수 입력이 되는 부분을 설정합니다.

  • 각 사이트마다 요구 사항은 다를 수 있으며 환경에 맞게 구성합니다.
  • 이번 문서에서는 기본적인 항목을 기반으로 설정하였고 설정 사항은 아래와 같습니다.

사용위치 : 드롭다운 사용하고 있는 센서를 추가합니다. 여러 항목을 선택할 수 있도록 드롭다운을 사용했으며 구분을 위해 IP 주소를 라벨로 지정했습니다.
사용자 ID : 단답형 텍스트 사용자의 ID를 입력합니다.
용도 : 드롭다운 유동, 고정 IP 사용인지 용도를 선택할 수 있습니다.
IP 주소 : 단답형 텍스트 고정 IP 용도인 경우 IP를 입력받습니다.
MAC 주소 :단답형 텍스트 고정 IP 용도인 경우 MAC 주소를 입력 받습니다.
이메일 : 단답형 텍스트 신청 결과를 받을 이메일 주소를 입력 받습니다.

 

IP 신청서 화면[그림 6] IP 신청서 화면

(3) 응답결과에 대한 Sheets를 생성합니다.

  • 응답 > Sheets에서 보기 선택

IP 신청 응답결과 화면
[그림 7] IP신청 응답결과 화면


(4) Sheets 에서 컬럼 두개를 추가 합니다.

IP 신청 결과 Sheets 화면[그림 8] IP 신청 결과 Sheets 화면

① 승인여부 컬럼
관리자가 승인 여부를 선택할 수 있도록 컬럼을 추가합니다. (드롭다운 메뉴로 추가하면 편리합니다.)


Sheet 드롭다운 메뉴 추가[그림 9] Sheet 드롭다운 메뉴 추가


② idx 컬럼
신청서 추가 후 발급받은 idx 값을 업데이트 할 컬럼 입니다.



3. Apps Script

  • 설문이 작성되어 시트에 내용이 저장될 때마다 실행될 스크립트를 작성합니다.
  • 실행할 스크립트 종류는 두 종류 입니다.
    ① 신청서 작성 시 신청서 등록 스크립트
    ② 관리자 승인 시 신청서 승인 스크립트

 

(1) Sheets 메뉴 > 확장 프로그램 > Apps Script 를 선택합니다.

Apps Script 확장 프로그램[그림 10] Apps Script 확장 프로그램

 

(2) 스크립트를 작성하기 전 NAC의 Swagger 페이지에서 사용할 API를 확인합니다.


Genian NAC의 Swagger 페이지 화면[그림 11] Genian NAC의 Swagger 페이지 화면

  • 생성과 승인을 하기 위해 POST /mc2/rest/applications/ips(신청서 생성) 와 PUT /mc2/rest/applications/ips/신청서idx(신청서 상태 수정) API를 확인합니다.

 

(3) Google form이 작성될 때마다 실행될 스크립트를 작성합니다.

  • IP 신청서 등록

function onFormSubmit(e) {
     const itemResponses = e.namedValues;

      // 관리자의 API Key를 생성한 뒤 api 호출 시 사용할 수 있도록 선언한다.
      const API_KEY = "[apiKey]"
      // REST API 를 호출할 url
      const url = "https://[도메인]/mc2/rest/applications/ips";
  
      const applyResJson = applyIpApplication(url, API_KEY, itemResponses);
      if(applyResJson !==  null) {
          const idx = applyResJson.ipApps[0].idx;
          const sheet = e.range.getSheet();
          const row = e.range.getRowIndex();
          sheet.getRange(row, 9).setValue(idx);
       }
    }

/**
  * IP 신청서 신청 후 응답값을 json 객체로 반환
  */
function applyIpApplication(_url, apiKey, itemResponses) {
     const url = _url + "?apiKey=" + apiKey;
     const payload = getApplicationPayload(itemResponses);

      // REST API 호출
      const options = {
         "method": "POST",
         "contentType": "application/json;charset=UTF-8",
         "headers": {
              "accept": "application/json;charset=UTF-8"
         },
         "payload": payload
       };
      const response = UrlFetchApp.fetch(url, options);
      let resJson = null;
      try {
          resJson = JSON.parse(response.getContentText());
      } catch(e) {
          resJson = null;
      }
      return resJson;
  
   }

   /**
     * IP 신청서 신청 시 입력된 값을 json string 으로 변환
     */
   function getApplicationPayload(itemResponses) {
        // 센서의 nid을 가져올 수 있도록 객체로 미리 선언
       const sensorDatas = {'172.29.50.52': '0d300156-7c51-103e-8002-080027a65e65-cc2d2503'
                                                  '172.29.50.53': '0d300156-7c51-103e-8002-080027a65e65-cc2d2504'};
        // 용도의 value 값 선언
       const purposeDatas = {'유동IP사용': 'USERIP_VARIABLE'
                                                          '고정IP사용': 'USERIP_STATIC'};
        // 응답 데이터 가공
       const purposeType = itemResponses["용도"][0];
       const data = {};
       // 신규신청 : 1
       data["appType"] = 1;
       data["sensorNid"] = sensorDatas[itemResponses["사용위치"][0]];
       data["id"] = itemResponses["사용자 ID"][0];
       data["applicantId"] = itemResponses["사용자 ID"][0];
       data["purposeCode"] = purposeDatas[itemResponses["용도"][0]];
       if(purposeType === '고정IP사용') {
           data["ipStr"] = itemResponses["IP 주소"][0];
           data["mac"] = itemResponses["MAC 주소"][0];
        }
       data["alarmEmail"] = itemResponses["이메일"][0];
        const payload = JSON.stringify([
            data
        ]);
        return payload;
      }

  • function 설명

onFormSubmit() Google form이 작성되는 실행되는 진입점이 되는 function
applyIpApplication() 신청서 API를 호출하는 function. 작업이 완료되면 결과값을 json 형태로 리턴합니다.
getApplicationPayload() 신청서 API 호출 시 form에 입력된 정보를 바탕으로 파라미터를 생성합니다.

  • 사전 정의한 정보

  const sensorDatas = {'172.29.50.xx': '센서 Node ID', 
                                           '172.29.50.xx': '센서 Node ID'};
  // 용도의 value 값 선언
  const purposeDatas = {'유동IP사용': 'USERIP_VARIABLE',
                                                  '고정IP사용': 'USERIP_STATIC'};
    • IP 신청을 할 때 센서의 Node ID 값을 파라미터로 전송해야 하는데 form에 Node ID를 노출하는 것은 사용자가 인식하기 어려운 정보이기 때문에 해당 부분은 치환이 될 수 있도록 js 객체로 사전에 정의해 놓았습니다.
    • 용도의 Key 값도 사용자가 선택한 라벨이 치환될 수 있도록 사전에 정의해 놓습니다.

  • IP 신청 승인

/**
 * 시트에서 승인 컬럼 값이 변경되면 호출
 * @param {e} 이벤트 객체
 */
 function onEdit(e) {
      const sheet = e.source.getActiveSheet();
      const targetColumn = 8; // idx 컬럼
      const editedRow = e.range.getRow();
      const val = e.range.getValue();
  
      // 수정된 셀이 타겟 컬럼에 있는 경우에만 처리
      if (val === '승인') {
         const record = sheet.getRange(editedRow, 1, 1, sheet.getLastColumn()).getValues()[0];
         const idx = record[targetColumn];
         if(idx !== '') {
             approveIpApplication(idx);
         }
       }
  }

  /**
   * IP 신청서 승인
   */
 function approveIpApplication(idx) {
      // 관리자의 API Key를 생성한 뒤 api 호출 시 사용할 수 있도록 선언한다.
      const API_KEY = "[apiKey]"
      const apiUrl = "https://[도메인]/mc2/rest/applications/ips/" + idx + "?apiKey=" + API_KEY;
      const options = {
           "method": "PUT",
           "contentType": "application/x-www-form-urlencoded",
           "headers": {
                "accept": "application/json;charset=UTF-8"
            },
            "payload": "cmd=approve"
        };

        try {
            const response = UrlFetchApp.fetch(apiUrl, options);    
         } catch (err) {
            Logger.log("Error: " + err);
         }
    }

  • function 설명
   onEdit()
  • 시트의 컬럼값을 관리자가 수정했을때 호출되는 function
  • 관리자가 수정한 컬럼이 승인여부 컬럼이면서 승인으로 값을 변경할 경우, approveIpApplication() function을 호출한다.
approveIpApplication()
  • 선택한 레코드의 IP 신청서를 승인한다.

 

(4) 트리거로 등록

  • 트리거 메뉴로 이동합니다.

Apps Script 화면[그림 12] Apps Script 화면

  • 트리거 추가

    • IP 신청서 등록 트리거 (이벤트 유형: 양식 제출 시)

IP신청서 승인 트리거 화면 - 함수: onFormSubmit

[그림 13] IP신청서 승인 트리거 화면 - 함수: onFormSubmit

실행할 함수 선택 스크립트에 작성한 onFormSubmit() 선택
실행할 배포 Head
이벤트 소스 선택 스프레드시트에서
이벤트 유형 선택 양식 제출 시

 

    • IP 신청서 등록 트리거 (이벤트 유형: 수정 시)

IP신청서 승인 트리거 화면 - 함수: onEdit [그림 14] IP신청서 승인 트리거 화면 - 함수: onEdit

실행할 함수 선택 스크립트에 작성한 onEdit() 선택
실행할 배포 Head
이벤트 소스 선택 스프레드시트에서
이벤트 유형 선택 수정 시


  • 설문 작성 및 실행 확인
    • 실행 확인
      ① 설문을 작성 후 확인
      ② 시트에서 승인 후 확인

Apps Script 실행 화면[그림 15] Apps Script 실행 화면

  • Logger.log 로 확인할 내용을 작성해 놓으면 실행에서 확인할 수 있습니다.

 

(5) NAC에서 IP 신청 결과 확인

  • 관리 > 신청 > IP 사용 신청서 > 결과 조회 메뉴 이동
  • 승인된 신청서 확인

Genian NAC - IP 사용신청서 결과 화면[그림 16] Genian NAC - IP 사용신청서 결과 화면

 

마치며

Google Apps Script와 Genian NAC의 REST API를 활용하여 IP 신청서를 생성하고 승인하는 과정을 경험해 보았습니다. 이처럼 Google Apps Script뿐만 아니라 REST API를 호출할 수 있는 다양한 도구들과 Genian NAC를 연동하면, 무궁무진한 활용 방법을 모색해 볼 수 있을 것입니다.

Genian NAC의 기존 UI에서 제공하는 기능 만으로는 한계가 있지만, REST API를 적극 활용한다면 고객의 요구 사항을 보다 폭넓게 수용할 수 있을 것입니다. 예를 들어 화면 개선이 어려운 상황이라면, 연동을 통해 해결책을 모색해볼 수 있습니다.

고객 환경에 맞는 최적의 솔루션을 제공하기 위해서는 때로는 기존의 틀을 벗어난 새로운 접근이 필요할 것입니다. 위 문서를 토대로 고객의 불편 사항을 꼭 해결할 수 있는 방안이 없는지 아이디어를 발휘해 보시면 어떨지 생각하며 이 글을 마칩니다.


 

글쓴이.한동선

지니언스 기술연구소에서 NAC 관련 제품 개발 및 기술 연구를 담당하고 있습니다.