Cisco Bug API を使って Bug 検索を自動化する

### はじめに

この記事は、シスコシステムズの有志による Cisco Systems Japan Advent Calendar 2020 の 16 日目として投稿しています。

2017 年版: https://qiita.com/advent-calendar/2017/cisco
2018 年版: https://qiita.com/advent-calendar/2018/cisco
2019 年版: https://qiita.com/advent-calendar/2019/cisco
2020 年版 (1枚目): https://qiita.com/advent-calendar/2020/cisco
2020 年版 (2枚目): https://qiita.com/advent-calendar/2020/cisco2

### Cisco Support API ってなに？

[Cisco Support API](https://developer.cisco.com/site/support-apis/) と呼ばれるサポート契約のあるパートナーや、ユーザーが利用可能な API が公開されています。Cisco Support API を用いることで契約情報、 RMA の情報、Bug の情報といった様々な情報を取得することが可能となります。日本語のドキュメントで書かれているものが見当たらず、どの程度ご使用されているかはわからないところもあり、せっかくなので使ってみようと思いました。今回は Cisco Bug APIを使って Bug の検索を自動化することを目標にしてみようと思います。

### 使い方

まずは、Cisco API Console で Application の登録して KEY と CLIENT SECRET を発行する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310027/e847bdd9-08a1-cde4-2ab1-2b054a6d7609.png)

次に、上で発行した  KEY と CLIENT SECRET を使って Access Token を取得します。この Access Token を Header に入れることで API へアクセスすることができるようになります。ここでは `testApp.json` という別ファイルに KEY と CLIENT SECRET の情報を記述しています。 

```python

import requests
import json

AUTH_URL='https://cloudsso.cisco.com/as/token.oauth2'

def getAccessToken(path):
    with open(path, 'r') as f:
        json_dict = json.load(f)
    
    headers={'Content-Type': 'application/x-www-form-urlencoded'}
    payload = {'grant_type':'client_credentials', 'client_id':json_dict['client_id'], 'client_secret':json_dict['client_secret']}
    res = requests.post(AUTH_URL, headers=headers, params=payload)

    return res.json()

if __name__ == '__main__':
    token = getAccessToken('./testApp.json')
```

Cisco Bug API の API Reference に記載されていますが、様々なクエリに対応していますので、ここでは実際に役立ちそうな例で試してみようかと思います。Application を登録するときに気づきましたが API が v3.0 になっています。「ACI というキーワードを含む」、 「F の状態のもの(修正済み)」で「過去30日以内に変更があったもの」を探してみることにします。作ってみたサンプルのコードは以下の通りです。

```python

import requests
import json
import urllib

AUTH_URL='https://cloudsso.cisco.com/as/token.oauth2'
BUG_API_URL='https://api.cisco.com/bug/v3.0/bugs/'

def getAccessToken(path):
    with open(path, 'r') as f:
        json_dict = json.load(f)
    
    headers={'Content-Type': 'application/x-www-form-urlencoded'}
    payload = {'grant_type':'client_credentials', 'client_id':json_dict['client_id'], 'client_secret':json_dict['client_secret']}
    res = requests.post(AUTH_URL, headers=headers, params=payload)

    return res.json()


def getDefect(token, path, query):
    custom_query = urllib.parse.urlencode(query)
    URL = BUG_API_URL + path + '?' + custom_query

    headers={'Authorization': token['token_type'] + ' ' + token['access_token']}
    res = requests.get(URL, headers=headers)

    return res.json()

if __name__ == '__main__':
    token = getAccessToken('./testApp.json')
    path = "keyword/ACI"
    query = {
        "modified_date":3,
        "status":"F"
    }
    bugList = getDefect(token, path, query)

    for bug in bugList['bugs']:
        print( bug['bug_id']+ ' : ' + bug['headline'])
```

これを実行すると、条件に合致したもののうち10件の検索結果が取得できます。申し訳ないですが、実行結果はその目で確かめてみてください。あとは、検索結果と一緒に `pagination_response_record` の情報が返ってくるので、`last_index` まで繰り返し実行すれば検索結果を全てリストアップできます。検索の仕方や、過去の検索結果を照らし合わせたりして工夫をすれば、最近登録された Bug のリストアップも容易になるかと思います。

### おわりに

手動で検索することで、神業のような検索も確かにできますが、こういった自動化するメリットとしては効率化や省力化といったことだけでなく、均一な検索を常に行うことができるということがメリットかなと思います。手動での検索だと、漏れであったり見逃しが生じてしまいがちですが、検索するキーワードやバージョンを決めておけるので、同一条件で検索を常に行うことができるというのが利点として大きいと思います。他にも Excel にまとめるなどの作業も合わせて自動化できるようになるかなと思います。装置のインベントリ情報やソフトウェアの情報を適切に管理していれば、データベースと連携して、月1回の Bug 調査も自動化することができて業務の効率化につながるかと思いますので、ぜひお試しいただければと思います。業務の効率化を目指していきましょう！


### 参考資料

Cisco DevNet
https://developer.cisco.com/

Cisco Support API Docs
https://developer.cisco.com/docs/support-apis/

### 免責事項

本サイトおよび対応するコメントにおいて表明される意見は、投稿者本人の個人的意見であり、シスコの意見ではありません。本サイトの内容は、情報の提供のみを目的として掲載されており、シスコや他の関係者による推奨や表明を目的としたものではありません。各利用者は、本 Web サイトへの掲載により、投稿、リンクその他の方法でアップロードした全ての情報の内容に対して全責任を負い、本 Web サイトの利用に関するあらゆる責任からシスコを免責することに同意したものとします。