Ncloud API 사용하여 생성된 서버 목록 출력 #1

728x90

👍목표 : Ncloud에서 생성한 서버의 목록을 API를 사용하여 확인

현재 회사 내 직원들이 사용하는 네이버클라우드 TEST 계정이 있다.

생성되어 있는 서버의 목록을 불러와서 확인하는것이 목표!
사용할 API는 Compute/Server(VPC)의  getServerInstanceList API

 

API 사용 전 준비사항

 

먼저 Ncloud에서 제공하는 API 문서를 확인하였다.
링크: https://api.ncloud-docs.com/docs/common-ncpapi

API를 사용하기 위해서는 Ncloud 사용자 계정에서 발급된 별도의 Key가 필요하다.

Key 발급은 Ncloud 포털 내 마이페이지 > 계정 관리 > 인증키 관리에서 생성 및 관리 할 수 있다.


신규 API 인증키를 생성하면 Access Key ID랑 Secret Key를 확인할 수 있다.


이렇게 생성한 Key를 사용하여 API를 사용할 수 있다.

하지만 실제 작업은 SubAccount 계정(회사 내 Ncloud Test 계정)이여서, Key 발급 및 사용 권한은 계정 관리자에게 요청하여 발급받고, 사용할 수 있었다.

API 관련 사용 언어는 Python을 선택하였다.
이유는 Ncloud에서 제공하는 API관련 예시에서 Python 예시를 제공해 주었고, Python을 개인적으로 배워보고 싶어 선택하게 되었다.

 

API 사용 기본 틀


API 호출 관련해서 기본적인 틀은 아래와 같다.
1. 서명 키 생성(Access, Secret Key 필요)
2. 헤더파일 생성(서명키 필요)
3. API 요청(헤더 필요)
4. 응답데이터 처리

Ncloud에서 Signature Key 생성 관련 제공해주는 Python 예시 코드는 아래와 같다.

import sys
import os
import hashlib
import hmac
import base64
import requests
import time

def make_signature():
timestamp = int(time.time() * 1000)
timestamp = str(timestamp)

access_key = "{accessKey}" # access key id (from portal or Sub Account)
secret_key = "{secretKey}" # secret key (from portal or Sub Account)
secret_key = bytes(secret_key, 'UTF-8')

method = "GET"
uri = "/photos/puppy.jpg?query1=&query2"

message = method + " " + uri + "\n" + timestamp + "\n"
+ access_key
message = bytes(message, 'UTF-8')
signingKey = base64.b64encode(hmac.new(secret_key, message, digestmod=hashlib.sha256).digest())
return signingKey


위 Sample 코드를 참고하여 작성한 키 생성 및 헤더 생성 코드는 아래와 같다.

# unix timestamp 설정
timestamp = int(time.time() * 1000)
timestamp = str(timestamp)

# Ncloud API Key 설정
ncloud_accesskey = "Access Key"
ncloud_secretkey = "Secert Key"

# 암호화 문자열 생성을 위한 기본값 설정
apicall_method = "GET"
space = " "
new_line = "\n"

# API 서버 정보
api_server = "https://ncloud.apigw.ntruss.com"

# API URL 서버 목록 조회
api_uri = "/vserver/v2/getServerInstanceList?responseFormatType=json"


# hmac으로 암호화할 문자열 생성
message = apicall_method + space + api_uri + new_line + timestamp + new_line + ncloud_accesskey
message = bytes(message, 'UTF-8')

# hmac_sha256 암호화
ncloud_secretkey = bytes(ncloud_secretkey, 'UTF-8')
signingKey = base64.b64encode(hmac.new(ncloud_secretkey, message, digestmod=hashlib.sha256).digest())

#위 코드까지는 Ncloud에서 제공해 주는 Signatuer Key 생성 부분과 동일

# http 호출 헤더값 설정
http_header = {
    'x-ncp-apigw-timestamp': timestamp,
    'x-ncp-iam-access-key': ncloud_accesskey,
    'x-ncp-apigw-signature-v2': signingKey
}

 

첫 번째 난관 - API서버 URL과 URI


해당 코드 작성에 있어서 첫번째 난관은 API서버 URL과 API URI 였다.
사실 URL과 URI도 개인적으로 정리되어 있지 않은 상황에서 이를 구별하기가 힘들었다.

API Server: https://ncloud.apigw.ntruss.com

 

API Server의 주소 경우 사용하고자 하는 Service마다 주소가 다르니 다른 서비스의 API를 사용할때는 해당 주소를 확인해서 사용해야 한다.
추후에 목표했던 Cloud Insight를 API를 사용하는 예제에서 API Server 주소는 아래와 같다.

API Server: https://cw.apigw.gov-ntruss.com (공공 Ncloud)

 

API uri의 경우는 사실 아직도 잘 모르겠다.. 다만, uri를 분석해 보면 vpc내 서버를 조회하기 때문에 /vserver/v2(api버전)/서버 목록 조회(getServerInstanceList)?응답데이터 형식 지정으로 해석할 수 있다.

API URI: /vserver/v2/getServerInstanceList?responseFormatType=json

 

추후에 목표했던 Cloud Insight를 API를 사용하는 예제에서 API uri는 아래와 같다.

API URI: /cw_fea/real/cw/api/data/query/multiple


첫번째 난관은 검색한 블로그에 작성된 코드들을 돌려보면서 파악할 수 있었다.
이렇게 해서 API 호출까지만도 오랜 시간이 걸렸다.

생성한 서명 키 및 헤더를 사용하여 API를 요청하는 코드는 아래와 같다.
API요청 후 응답 데이터를 출력하는 코드도 같이 작성되어 있다.

#api 호출
response = requests.get(api_server + api_uri, headers=http_header)

#응답받은 response를 출력
#print(response.text)

#현재 응답받은 데이터의 타입 확인 -> 현재 데이터는 정확하게 json 데이터가 아닌 request의 응답 데이터라는 클레스로 출력됨(<class 'requests.models.Response'>)
#print(type(response))

#데이터를 파이썬 딕션어리 데이터 타입으로 저장
real_data = json.loads(response.text)

#변환 확인 및 출력
#<class 'dict'> 확인 -> api응답 데이터가 파이선 dic 데이터 타입으로 변환된 것을 확인.
#print(type(real_data))
#print(real_data)

#응답데이터 내용 중 전체는 dictionary 자료형으로 되어 있고 그 안에 serverinstancelist는 리스트로 되어있음.
#serverinstancelist를 변수에 넣고 for문을 이용하여 이름 및 상태만 출력
list = real_data["getServerInstanceListResponse"]["serverInstanceList"]
for name in list:
    print(name['serverName'] + " / " + name["serverInstanceStatusName"])

 

두 번째 난관 - 응답 데이터 처리


두번째 난관은 응답 데이터 처리였다.(이 부분이 제일 어려웠다.)
(개인적으로 응답 데이터 출력할때 .text를 붙이지 않아 에러가 발생했는데 이것도 한참을 고생해서 알았다.... 쩝..😰)
실제 API 호출에 대한 응답으로 데이터를 출력하면 생성되어 있는 서버의 모든 정보가 다 출력된다.
네트워크 정보, 서버 스펙, 생성 시간, 서버 상태 등등...
내가 알고 싶은 정보는 서버 이름과 서버 기동 상태 정보이다. 
해당 데이터를 내가 원하는 데이터만 출력하는 과정도 오래 걸렸다.

API 요청 시 응답 데이터는 실제 json파일 형식이 아니다. 내가 원하는 데이터로 가공하기 위해서는(Parsing) 사용하는 언어, 즉 Python의 데이터 타입으로 변환을 해야 가능했다.
따라서 Python의 Dictionary 타입으로 형 변환을 해야한다.

형 변환 후 데이터를 출력하면 서버의 정보가 모두 출력되어 어떤 서버가 어떤 상태인지 파악하기가 힘들었다. 또한 데이터의 구조가 어떻게 되어 있는지도 파악하기가 힘들다.(짜증....😡)

데이터의 구조는 json형식의 데이터 출력을 보기 좋게 출력해주는 사이트에서 변환해서 파악하였다.
(json형식과 Python의 Dictionary는 다른 데이터 타입니다. 더구나 json형식은 실제 데이터의 타입이 아니다. 다만 동일한 Key=Value 형태의 데이터이기 때문에 Dictionary 데이터를 넣어도 보기 좋게 가공해서 출력해주는 듯 하다.)

하지만 제일 큰 난관은 이제부터이다.
전체 데이터 타입은는 Dic 타입이다. Value값이 또 Dic타입으로 되어 있고 그 안에 Value가 리스트 형식으로 되어 있고.... 아주아주 복잡한 구조로 되어 있었다.

데이터 구조는 아래와 같이 요약할 수 있었다.

getServerInstanceListResponse 응답 메시지 딕션너리 구조

"getServerInstanceListResponse" : { 
"serverInstanceList" : [
{"serverInstanceNo":"xxxxxxxxx",
 "serverName":"xxxxxxxxx",
 "serverInstanceStatusName":"running or stop"}, 
{server 2}
        {server 3}
]


getServerInstanceListResponse의 value로 serverInstanceList가 있고, 이것에 value값이 list자료형으로 되어있고, 이 list내용은 또 dic타입으로 데이터를 가지고 있었다.(이것만 들어도 복잡...... 다른 클라우드에서는 응답 데이터가 직관적이라고 하는데 직접 확인은 안해봤으나... Ncloud는 많이 복잡해 보인다.)
나한테 필요한 데이터 정보는 serverName, serverInstanceStatusName!!

내가 접근하고자 하는 데이터는 최종적으로 value안에 있는 List 자료형이기 때문에 별도의 변수에 해당 부분을 저장하였다.

list = real_data["getServerInstanceListResponse"]["serverInstanceList"]

 

이 중 알고싶은 serverName(key), serverInstanceStatusName(key)를 반복문을 통해 출력하였다.

for name in list:
    print(name['serverName'] + " / " + name["serverInstanceStatusName"])

 

이렇게 해서 원하는 내용만 출력을 할 수 있었다.

출력 예
```
serverA / running
serverB / running
serverC / stopped
serverD / stopped
serverE / stopped
```


이렇게 해서 단순하 생성된 서버의 목록과 가동상태를 출력해 주는 코드를 완성할 수있었다.

 

😡결론(소감)

 

Ncloud 콘솔에서 서버를 눌르면 생성되어 있는 서버목록과 정보 및 가동 상태를 바로 확인할 수 있다.
이를 API로 확인하는 방법은 너무 힘들었다.(개인의 능력 및 경험부족....)
이 코드를 완성하는데는 2주정도 시간이 소요되었다. API를 처음 호출해보고, Python언어로 코드를 처음 작성해 보고.. 기본적인 지식도 부족했고..(사실 코딩이라고 할 수 없다 ......)
시간도 많이 걸리고 헤매기도 많이 헤맸지만, 그래도 내가 원하는 것을 출력할 수 있어서 개인적으로 뿌듯함을 느꼇고, 별거 없지만 많은 내용을 공부할 수 있었다.
역시 직접 코드를 짜고 직접 실습해 봐야 알 수 있다는걸 다시한번 느꼈다.

 

아래는 전체 소스코드 이다.

import hashlib
import hmac
import base64
import requests
import time
import json

# unix timestamp 설정
timestamp = int(time.time() * 1000)
timestamp = str(timestamp)

# Ncloud API Key 설정
ncloud_accesskey = "Access Key"
ncloud_secretkey = "Secert Key"

# 암호화 문자열 생성을 위한 기본값 설정
apicall_method = "GET"
space = " "
new_line = "\n"

# API 서버 정보
api_server = "https://ncloud.apigw.ntruss.com"

# API URL 서버 목록 조회
api_uri = "/vserver/v2/getServerInstanceList?responseFormatType=json"

# hmac으로 암호화할 문자열 생성
message = apicall_method + space + api_uri + new_line + timestamp + new_line + ncloud_accesskey
message = bytes(message, 'UTF-8')

# hmac_sha256 암호화
ncloud_secretkey = bytes(ncloud_secretkey, 'UTF-8')
signingKey = base64.b64encode(hmac.new(ncloud_secretkey, message, digestmod=hashlib.sha256).digest())


# http 호출 헤더값 설정
http_header = {
    'x-ncp-apigw-timestamp': timestamp,
    'x-ncp-iam-access-key': ncloud_accesskey,
    'x-ncp-apigw-signature-v2': signingKey
}

# api 호출
response = requests.get(api_server + api_uri, headers=http_header)

# 응답받은 response를 출력
#print(response.text)

#현재 응답받은 데이터의 타입 확인 -> 현재 데이터는 정확하게 json 데이터가 아닌 request의 응답 데이터라는 클레스로 출력됨(<class 'requests.models.Response'>)
#print(type(response))

# 데이터를 파이썬 딕션어리 데이터 타입으로 저장
real_data = json.loads(response.text)

# 변환 확인 및 출력

#print(type(real_data))
#<class 'dict'> 확인 -> 즉 api응답 데이터가 파이선 dic 데이터 타입으로 변환된 것을 확인.

#print(real_data)

#응답데이터 내용 중 전체는 dictionary 자료형으로 되어 있고 그 안에 serverinstancelist는 리스트로 되어있음.
#serverinstancelist를 변수에 넣고 for문을 이용하여 이름 및 상태만 출력
list = real_data["getServerInstanceListResponse"]["serverInstanceList"]
for name in list:
    print(name['serverName'] + " / " + name["serverInstanceStatusName"])
728x90