LoginSignup
10
3

More than 5 years have passed since last update.

Python初心者が、ISE ERS API を利用してスクリプトを書いてみた

Posted at

はじめに

Cisco製品には様々な製品でAPIが用意されていますが、今回はISEのERS(External RESTful Services) APIを利用してPython(ver3.6.3)スクリプトを作成してみました。

ISE ERS(External RESTful Services) API について

ガイドはこちら

事前準備

ISE ERS(External RESTful Services) APIを利用するためには、まず初めにISEの管理画面から、Administration->System->SettingsのERS Settingsで、ERSを有効にする必要があります。
スクリーンショット 2017-12-04 午後2.09.12.png

さらに、Administration->Sytem->Admin AccessのAdmin Uers設定で、ESR APIへアクセスするための管理者IDとパスワードを作成します。
スクリーンショット 2017-12-04 午後2.21.23.png
Admin Groupsは、ERS Adminを選択します。
スクリーンショット 2017-12-04 午後2.21.35.png

APIについては、上記のCCOガイドに詳細な記載がないので、ERSを有効にした後、https://(ise ip address):9060/ers/sdkに作成した管理者IDとパスワードでアクセスするとAPIの詳細やスクリプト例を確認することができます。

想定するユースケース

ユーザ様から、ISEが高機能なことは理解しているのだけど、管理者用のUIが(英語だし)複雑で使いにくい、もっとシンプルにUIをカスタマイズしたい、あるいは既存のシステムと連携させたい、という声をよくお聞きします。そういった場合に活用できるのがAPIです。
今回は、大学様や病院様での使用が多い有線のMacアドレス認証でのISEの利用を想定し、ISEの管理者UIにアクセスすることなくAPI経由で、ISEが管理している端末情報を取得するスクリプトを作成します。取得結果は、txtファイルに保存すると同時に、SparkのbotからSparkのRoomに結果をPostすることとします。

利用するAPI

Endpoint API (GET-All)

Request:

Method: GET
URI: https://(ise ip address):9060/ers/config/endpoint
HTTP 'Content-Type' Header:application/json

Response:

JSON
{
  "SearchResult" : {
    "total" : 2,
    "resources" : [ {
      "id" : "id1",
      "name" : "name1",
      "description" : "description1"
    }, {
      "id" : "id2",
      "name" : "name2",
      "description" : "description2"
    } ],
    "nextPage" : {
      "rel" : "next",
      "href" : "link-to-next-page",
      "type" : "application/xml"
    },
    "previousPage" : {
      "rel" : "previous",
      "href" : "link-to-previous-page",
      "type" : "application/xml"
    }
  }
}

EndPoints Identity Group (GET-By-Id)
Request:

Method: GET
URI: https://(ise ip address):9060/ers/config/endpointgroup/{id}
HTTP 'Content-Type' Header:application/json

Response:

JSON
{
  "EndPointGroup" : {
    "id" : "id",
    "name" : "name",
    "description" : "description",
    "systemDefined" : true
  }
}

スクリプト解説

STEP0: Basic認証ヘッダを作成する

import base64
user='ersadmin'  ## ISEのERS Adminのユーザ名
password='Password123' ## ISEのERS Adminのパスワード

creds = str.encode(':'.join((user, password)))
auth_header = bytes.decode(base64.b64encode(creds))

STEP1: Pythonのrequestモジュールを使用して端末情報を取得する

 import requests
 import json

 iseip='X.X.X.X'  ## ISEのIPアドレス
 url = "https://"+iseip+":9060/ers/config/"
 url_endpoint = url+"endpoint"
 headers = {
            'accept': "application/json",
            'authorization': 'Basic ' + header, ## STEP0で生成したbasic認証ヘッダー
            'cache-control': "no-cache",
            }

 ##全ての端末情報をjson形式で取得
 response = requests.get( url_endpoint, verify=False,headers=headers).json()

 ##ディクショナリのキーを指定し、必要な情報を取り出す
 o_json = json.dumps(response["SearchResult"]["resources"])

注意点

response = requests.get( uri,verify=False,headers)

SSL証明書が正しくない場合にはデフォルトでSSL認証エラーを出すため、正しい証明書を入れるか、verify=Falseでverifyを無効にしない場合、[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failedのエラーが返されます。verify=Falseを書いた場合も、下記のWarningが出ます。

/usr/lib/python3.6/site-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
  InsecureRequestWarning)

Warningは、下記で無効にし出力させないようにすることができます。

import urllib3
from urllib3.exceptions import InsecureRequestWarning
urllib3.disable_warnings(InsecureRequestWarning)

STEP2: 結果をファイルに保存

import datetime
 now = datetime.datetime.now()
 file_name = "{0:%Y%m%d.%H%M}".format(now) ##ファイル名に作成した時間を記録
 f = open(file_name + "_endpoints_list.txt","w")
 for x in message: ##STEP1でリスト化した要素を改行を入れながらファイルに記述
  x2 = x.replace('\\n','\n')
  f.write(str(x2))
 f.close()

STEP3: SparkのbotからRoomにAPI経由で取得結果をpost

SPARK APIについては、developerサイトで詳細な情報を得られます。今回はMessages APIを利用して取得した情報をpostします。
スクリーンショット 2017-12-04 午後3.31.48.png

スクリプト全体

get-all-internal-endpoint.py
import requests
import urllib3
from urllib3.exceptions import InsecureRequestWarning
urllib3.disable_warnings(InsecureRequestWarning)
import base64
import json
import sys
import datetime

iseip='X.X.X.X'  ## ISEのIPアドレス

ACCESS_TOKEN="***********" ## SPARK botのアクセストークン
ROOM_ID="*********" ## SPARKのROOM ID


def get_authheader():
 user='ersadmin'  ## ISEのERS Adminのユーザ名
 password='Password123' ## ISEのERS Adminのパスワード

 creds = str.encode(':'.join((user, password)))
 auth_header = bytes.decode(base64.b64encode(creds))
 return auth_header

APIAuth = get_authheader()

def get_endpoint_info(header):
 url = "https://"+iseip+":9060/ers/config/"
 url_endpoint = url+"endpoint"
 url_endpointgroup = url+"endpointgroup"

 ##ヘッダー情報
 headers = {
            'accept': "application/json",
            'authorization': 'Basic ' + header,
            'cache-control': "no-cache",
            }

 ##全ての端末情報を取得
 response = requests.get( url_endpoint, verify=False,headers=headers).json()
 o_json = json.dumps(response["SearchResult"]["resources"])

 msg=[]
 ## 取得した端末情報から、macアドレス情報と端末が所属するグループIDを取得
 for item in response["SearchResult"]["resources"]:
     href = item["link"]["href"]
     response_href = requests.get(href, verify=False,headers=headers).json()
     r = json.dumps(response_href["ERSEndPoint"]["groupId"])
     gid = r.split('"')
   ## 所属するグループIDからグループ名を取得
     gname_url = url_endpointgroup+"/"+gid[1]
     gname_r = requests.get( gname_url, verify=False,headers=headers).json()  
     gname = json.dumps(gname_r["EndPointGroup"]["name"])
     gname2 = gname.replace('"','')
   
   ##端末のmacアドレス情報と端末が所属するグループ名をリスト化
     msg.append('mac address:'+ item["name"]+', identity group name:'+gname2+'\\n')
 return msg

## Sparkへ結果をpost
def postMsg(roomId, markdown): 
 accessToken_hdr= 'Bearer '+ACCESS_TOKEN
 spark_header={'Authorization':accessToken_hdr,'Content-Type': 'application/json;charset=utf-8'} ##ヘッダーの作成
 the_data = '{"roomId":"' + roomId + '","markdown":"' + markdown +'"}' ## 使用するbotのroom IDと、postする情報を指定
 uri = 'https://api.ciscospark.com/v1/messages' ## Messgae API URI

 resp=requests.post(uri,data=the_data,headers=spark_header)
 print (resp)

if __name__ == '__main__':
 APIAuth = get_authheader()
 message=get_endpoint_info(APIAuth) 
 num=len(message)

 ## Sparkへリストのままpostできないため、要素を連結
 m=''
 for x in message:
  m += x+'\\n'

 ## 取得結果をテキストファイルに保存
 now = datetime.datetime.now()
 file_name = "{0:%Y%m%d.%H%M}".format(now)
 f = open(file_name + "_endpoints_list.txt","w")
 for x in message:
  x2 = x.replace('\\n','\n')
  f.write(str(x2))
 f.close()

 data ='Total number of endpoints managed by ISE is :'+'  '+ str(num)+'\\n\\n'+ m

 postMsg(ROOM_ID,data)

実行結果

[root@localhost naogawa]# python3 ./get-all-internal-endpoint.py 
<Response [200]>
[root@localhost naogawa]# ls
20171204.0652_endpoints_list.txt  get-all-internal-endpoint.py
[root@localhost naogawa]# cat 20171204.0652_endpoints_list.txt 
mac address:00:00:5E:00:01:01, identity group name:Profiled
mac address:00:0C:29:73:CB:DA, identity group name:Profiled
mac address:00:0C:29:8F:93:85, identity group name:Profiled
mac address:00:0C:29:94:E1:39, identity group name:Profiled
mac address:00:0C:29:BB:CE:BD, identity group name:Profiled
mac address:00:0C:29:C9:B1:CA, identity group name:Profiled
mac address:00:0C:29:D0:AC:AC, identity group name:Profiled
mac address:00:0C:29:F3:30:B6, identity group name:Profiled
mac address:00:24:97:CE:DF:A0, identity group name:Profiled
mac address:00:38:DF:20:49:48, identity group name:Profiled
mac address:00:38:DF:3E:3C:F0, identity group name:Profiled
mac address:00:A3:D1:88:B9:00, identity group name:Profiled
mac address:00:B0:64:FC:D6:65, identity group name:Profiled
mac address:00:B0:64:FC:D6:99, identity group name:Profiled
mac address:00:B0:64:FD:05:84, identity group name:Profiled
mac address:1C:DF:0F:1D:7F:D6, identity group name:Profiled
mac address:2C:86:D2:8B:B7:C0, identity group name:Profiled
mac address:2C:86:D2:FE:C8:C0, identity group name:Profiled
mac address:50:7A:55:DD:C1:EF, identity group name:Profiled
mac address:58:8D:09:08:98:68, identity group name:Profiled
[root@localhost naogawa]# 

スクリーンショット 2017-12-04 午後2.59.24.png

最後に

APIを活用すれば、ユーザ様の様々な要件に柔軟に対応することができます。ぜひ、APIの活用をご検討ください。

10
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
3