Categories: Cisco DevNet

APIC-EM から Cisco DNA Center へと PnP API を移行する

この記事は、Distinguished Sales Architect の Distinguished System Engineer である Adam Radford によるブログ「Migrating PnP API from APIC-EM to Cisco DNA Center」(2021/3/11)の抄訳です。

私はこれまで、デバイスのプロビジョニングを APIC-EM から DNA Center for Plug and Play(PnP)に移行する最良の方法について、たくさんの質問をいただきました。APIC-EM において、PnP API は非常に高い支持を得ており、DNA Center では PnP 機能とAPI の両方が強化されてきました。DNAC には、古いワークフロースタイルの API も依然として存在していますが、それらは比較的複雑で、UI コンポーネントがありません。

 

移行アプローチ

「移行方法」に関する質問に対して、私はこれまで下記の2つの方法を提案してきました。1つ目の方法は「遷移」(単にワークフロー API を使用する)、もう1つは「変換」(新しい「サイトベース」の API に移る)です。

静的な構成ファイルがデバイス(それらを生成する他のツールなど)に対して存在する場合は、通常、1つ目の方法を選択することになるでしょう。変数のあるテンプレートの方に興味がある場合は、2つ目の方法を選ぶことになるでしょう。

今では、新しいサイトクレーム API を、「固定」式の構成テンプレートと共に使用するハイブリッドオプションもあります。

 

PnP API

まず、PnP API に着目し、その仕組みを見ていきましょう。ステップは、1)デバイスを追加する、および 2)デバイスをクレームする、の2つに分かれます。

ステップ1は、デバイスを PnP デバイステーブルに追加します。追加は、gなし(デバイスが DNA Center を検出する)と、事前プランあり(デバイスが DNA Center に挿入される)といった2つの方法が可能です。このステップでは、APIC-EM の場合と同様、/import API エンドポイントが使用されます。必要なものは、デバイスのモデルとシリアル番号だけです。

デバイスが PnP テーブルの一部になると、これをクレームできるようになります。かつて、ワークフローベースの API は、/claim API エンドポイントを使用していました。 今では、新しい /site-claim API エンドポイントが推奨されています。これには、デバイス(ステップ1から)とサイトが必要です。イメージのアップグレードと構成テンプレートに関しては、オプションの属性があります。

これらのステップは UI で表示されます。1つ目のデバイス(pre-planned)は、DNA Centerに追加されていますが、クレームはされていません。2つ目のデバイスは、DNA Center に追加され、かつあるサイトにクレームされています。両デバイスのソースは「User」でした。これはプランなしデバイスを示す 「Network」と異なり、pre-plannedだったことを意味します。

 

スクリプトの使用

これらのスクリプトは、githubで提供されています。インストール方法については、readme に記載されています。スクリプトは、私が過去のブログで説明した dnacentersdk を使用します。

最初のステップは、テンプレートとして構成ファイルをアップロードすることです。これらのファイルは 「Onboarding Configuration」フォルダに保存されています。


$ ./00load_config_files.py --dir work_files/configs
Processing:switch1.cfg: adding NEW:Commiting e156e9e6-653d-4016-85bd-f142ba0659f8
Processing:switch3.cfg: adding NEW:Commiting 9ae1a187-422d-41b9-a363-aafa8724a5b2

2つ目のステップは、アップロードするデバイスと構成ファイルを含めるよう、CSV ファイルを編集することです。下に示すファイルは、例として、意図的にいくつかのエラーを設けています(構成ファイルとイメージの欠如)。


$ cat work_files/devices.csv
name,serial,pid,siteName,template,image
adam123,12345678902,c9300,Global/AUS/SYD5,switch1.cfg,cat3k_caa-universalk9.16.09.05.SPA.bin
adam124,12345678902,c9300,Global/AUS/SYD5,switch2.cfg,cat3k_caa-universalk9.16.09.05.SPA.bin
adam_bad_image,12345678902,c9300,Global/AUS/SYD5,switch2.cfg,cat3k_caa-universalk9.16.09.10.SPA.bin

3つ目のステップは、スクリプトを使用してデバイスを DNA Center にアップロードすることです。構成ファイルがないことと、イメージがないことに対して、フラグが立っています。


$ ./10_add_and_claim.py --file work_files/devices.csv
Device:12345678902 name:adam123 siteName:Global/AUS/SYD5 Status:PLANNED
##ERROR adam124,12345678902: Cannot find template:switch2.cfg
##ERROR adam_bad_image,12345678902: Cannot find image:cat3k_caa-universalk9.16.09.10.SPA.bin
adam_bad_image,12345678902,c9300,Global/AUS/SYD5,switch2.cfg,cat3k_caa-universalk9.16.09.10.SPA.bin

これは、DNA Center の PnP ページで反映されます。

 

詳細を探る

SDK を使用して、API を抽象化します。ペイロードについてより詳しく理解したい方のために、ここからはペイロードについて深掘りしていきます。

 

テンプレート

下記の API コールは、「Onboarding Configuration」フォルダの projectId を取得します。


GET dna/intent/api/v1/template-programmer/project?name=Onboarding%20Configuration

その結果、プロジェクトの UUIDが得られます。また、テンプレートのリストも表示されるので、テンプレートを探す際にも使用できます。テンプレートはバージョンで管理されているため、テンプレートの本文を取得するには別のコールが必要です。下記の“id”は、マスターテンプレート ID を意味します。


[
{
"name": "Onboarding Configuration",
"id": "bfbb6134-8b1a-4629-9f5a-435a13dba75a",
"templates": [
{
t"name": "switch1.cfg",
"composite": false,
"id": "e156e9e6-653d-4016-85bd-f142ba0659f8"
} ,

テンプレートを取得するより良い方法は、クエリパラメータとしてプロジェクト ID を使用してテンプレート API をコールすることです。テンプレートを名前でルックアップすることはできません。結果のリストを反復処理することが唯一の選択肢になります。


GET dna/intent/api/v1/template-programmer/template?projectId=bfbb6134-8b1a-4629-9f5a-435a13dba75a

テンプレートにはバージョンがあります。よって、マスターテンプレート IDのほか、各バージョンの IDがあります。下の例の場合、バージョンは“id”: “bd7cfeb9-3722-41ee-bf2d-a16a8ea6f23a”の1つのみです。


{
"name": "switch1.cfg",
"projectName": "Onboarding Configuration",
"projectId": "bfbb6134-8b1a-4629-9f5a-435a13dba75a",
"templateId": "e156e9e6-653d-4016-85bd-f142ba0659f8",
"versionsInfo": [
{
"id": "bd7cfeb9-3722-41ee-bf2d-a16a8ea6f23a",
"author": "admin",
"version": "1",
"versionTime": 1590451734078
}
] ,
"composite": false
}

テンプレートの本文を取得するには(SHA ハッシュと比較するため)、特定のバージョンに対してテンプレート API コールを使用します。


GET dna/intent/api/v1/template-programmer/template/bd7cfeb9-3722-41ee-bf2d-a16a8ea6f23a

すると、本文が返されます。テンプレートは、製品ファミリとソフトウェアタイプに適用されています。これらは、テンプレートの作成または更新に使用されます。


{
"name": "switch1.cfg",
"tags": [] ,
"author": "admin",
"deviceTypes": [
{
"productFamily": "Switches and Hubs"
}
] ,
"softwareType": "IOS-XE",
"softwareVariant": "XE",
"templateContent": "hostname switch1\nint g2/0/1\ndescr nice one\n",
"templateParams": [] ,
"rollbackTemplateParams": [] ,
"composite": false,
"containingTemplates": [] ,
"id": "bd7cfeb9-3722-41ee-bf2d-a16a8ea6f23a",
"createTime": 1590451731775,
"lastUpdateTime": 1590451731775,
"parentTemplateId": "e156e9e6-653d-4016-85bd-f142ba0659f8"
}

新しいテンプレートを追加するには、2つのステップがあります。1つ目のステップは、テンプレートを作成してからコミットします。2つ目のステップは、既存のテンプレートをアップデートする場合と同様です。これで新しいバージョンが作成されます。デバイスタイプ(deviceTypes)とソフトウェアタイプ(softwareType)が必要な点に注意してください。


POST dna/intent/api/v1/template-programmer/project/bfbb6134-8b1a-4629-9f5a-435a13dba75a/template
{
"deviceTypes": [{"productFamily": "Switches and Hubs"}] ,
"name": "switch4.cfg",
"softwareType": "IOS-XE",
"templateContent": "hostname switch4\nint g2/0/1\ndescr nice four\n"
}

タスクが返されたら、これをポーリングする必要があります。


{
"response": {
"taskId": "f616ef87-5174-4215-b5c3-71f50197fe72",
"url": "/api/v1/task/f616ef87-5174-4215-b5c3-71f50197fe72"
} ,
"version": "1.0"
}

タスクのポーリング


GET dna/intent/api/v1/task/f616ef87-5174-4215-b5c3-71f50197fe72

ステータスは成功で、テンプレート ID は“57371b95-917b-42bd-b700-0d42ba3cdcc2”になります。


{
"version": "1.0",
"response": {
"username": "admin",
"rootId": "f616ef87-5174-4215-b5c3-71f50197fe72",
"serviceType": "NCTP",
"id": "f616ef87-5174-4215-b5c3-71f50197fe72",
"version": 1590468626572,
"startTime": 1590468626572,
"progress": "Successfully created template with name switch4.cfg",
"instanceTenantId": "5d817bf369136f00c74cb23b",
"endTime": 1590468626670,
"data": "57371b95-917b-42bd-b700-0d42ba3cdcc2",
"isError": false
}
}

最後に、変更をテンプレートにコミットします。


POST dna/intent/api/v1/template-programmer/template/version
{
"templateId": "57371b95-917b-42bd-b700-0d42ba3cdcc2"
}

既存のテンプレートをアップデートするには、POST ではなく PUT します。ここでも、デバイスタイプとソフトウェアタイプが必要です。


PUT dna/intent/api/v1/template-programmer/template
{
"deviceTypes": [ { "productFamily": "Switches and Hubs" } ] ,
"id": "57371b95-917b-42bd-b700-0d42ba3cdcc2",
"name": "switch4.cfg",
"softwareType": "IOS-XE",
"templateContent": "hostname switch4\nint g2/0/1\ndescr nice four **\n"
}

再度、タスクが返されますので、これをポーリングする必要があります。


{
"version": "1.0",
"response": {
"username": "admin",
"rootId": "52689b1e-e9b8-4a60-8ae9-a574bb6b451c",
"serviceType": "NCTP",
"id": "52689b1e-e9b8-4a60-8ae9-a574bb6b451c",
"version": 1590470080172,
"startTime": 1590470080172,
"progress": "Successfully updated template with name switch4.cfg",
"instanceTenantId": "5d817bf369136f00c74cb23b",
"endTime": 1590470080675,
"data": "57371b95-917b-42bd-b700-0d42ba3cdcc2",
"isError": false
}
}

最後のステップとして、最初にテンプレートを作成した時と同様、変更をコミットします。UI では、このテンプレートの2つのバージョンが表示されます。

 

サイト

サイト ID を見つけるには、名前をクエリパラメータとしてルックアップします。名前には、サイトの完全修飾名を使用します。


GET dna/intent/api/v1/site?name=Global/AUS/SYD5

これで、サイト ID が返されます。


{
"response" : [ {
"parentId" : "ace74caf-6d83-425f-b0b6-05faccb29c06",
"systemGroup" : false,
"additionalInfo" : [ {
"nameSpace" : "Location",
"attributes" : {
"country" : "Australia",
"address" : "177 Pacific Highway, North Sydney New South Wales 2060, Australia",
"latitude" : "-33.837053",
"addressInheritedFrom" : "d7941b24-72a7-4daf-a433-0cdfc80569bb",
"type" : "building",
"longitude" : "151.206266"
}
} , {
"nameSpace" : "ETA",
"attributes" : {
"member.etaCapable.direct" : "2",
"member.etaReady.direct" : "0",
"member.etaNotReady.direct" : "2",
"member.etaReadyNotEnabled.direct" : "0",
"member.etaEnabled.direct" : "0"
}
} ] ,
"groupTypeList" : [ "SITE" ] ,
"name" : "SYD5",
"instanceTenantId" : "5d817bf369136f00c74cb23b",
"id" : "d7941b24-72a7-4daf-a433-0cdfc80569bb",
"siteHierarchy" : "80e81504-0deb-4bfd-8c0c-ea96bb958805/ace74caf-6d83-425f-b0b6-05faccb29c06/d7941b24-72a7-4daf-a433-0cdfc80569bb",
"siteNameHierarchy" : "Global/AUS/SYD5"
} ]
}

 

イメージ

ソフトウェアのアップグレードのため、イメージ ID を見つけるには、imageNameでイメージを検索します。一部のプラットフォームの場合、これは名前と異なる場合があるので注意してください。


GET dna/intent/api/v1/image/importation?imageName=cat3k_caa-universalk9.16.09.05.SPA.bin

imageUuid のほか、イメージについてのその他のさまざまな情報(モデル番号など)が返されます。


{
"response": [
{
"imageUuid": "04d69fe0-d826-42e9-82c0-45363a2b6fc7",
"name": "cat3k_caa-universalk9.16.09.05.SPA.bin",
"family": "CAT3K_CAA",
"version": "16.9.5",
"md5Checksum": "559bda2a74c0a2a52b3aebd7341ff96b",
"shaCheckSum": "a01d8ab7121e50dc688b9a2a03bca187aab5272516c0df3cb7e261f16a1c8ac355880939fd0c24cc9a79e854985af
786c430d9b704925e17808353d70bf923f4",
"createdTime": "2020-05-26 04:20:42.904",
"imageType": "SYSTEM_SW",
"fileSize": "450283034 bytes",
"imageName": "cat3k_caa-universalk9.16.09.05.SPA.bin",
"applicationType": "",
"feature": "",
"fileServiceId": "94eccf65-a1dd-47ca-b7c4-f5dd1a8cdeb7",
"isTaggedGolden": false,
"imageSeries": [
"Switches and Hubs/Cisco Catalyst 3850 Series Ethernet Stackable Switch",
"Switches and Hubs/Cisco Catalyst 3650 Series Switches"
] ,

 

デバイスの追加

デバイスを追加するには、シリアル番号(serialNumber)と製品 ID(pid)を指定します。名前はオプションです。DNAC 1.3.3.7 の前には aaa パラメータを使用しません。aaa パラメータは、「aaa コマンド認証」での問題を解決する際に使用します。


POST dna/intent/api/v1/onboarding/pnp-device/import
[
{
"deviceInfo": {
"serialNumber": "12345678902",
"aaaCredentials": {
"username": "",
"password": ""
} ,
"userSudiSerialNos": [] ,
"hostname": "adam123",
"pid": "c9300",
"sudiRequired": false,
"stack": false
}
}
]

回答にはデバイス ID が含まれており、その他の属性は簡潔さのために削除されています。この時点で、デバイスは PnP に表示されていますが、クレームはされていません。


{
"successList": [
{
"version": 2,
"deviceInfo": {
"serialNumber": "12345678902",
"name": "12345678902",
"pid": "c9300",
"lastSyncTime": 0,
"addedOn": 1590471982430,
"lastUpdateOn": 1590471982430,
"firstContact": 0,
"lastContact": 0,
"state": "Unclaimed",
"tenantId": "5d817bf369136f00c74cb23b",
"id": "5eccad2e29da7c0008613b69"
}

 

サイトクレーム

サイトにデバイスをクレームするには、前のステップで得たサイト ID、イメージ ID、テンプレート ID (構成 ID)を使用します。特定のバージョンではなく、マスターテンプレート ID が使用される点に注意してください。マスターは、デフォルトで最新バージョンのテンプレートを取得します。タイプは“Default”になるはずです。スタックを使用している場合、タイプは“StackSwitch”となります。ワイヤレスアクセスポイントは、タイプフィールドを“AccessPoint”に設定します。


POST dna/intent/api/v1/onboarding/pnp-device/site-claim
{
"configInfo": {
"configId": "e156e9e6-653d-4016-85bd-f142ba0659f8",
"configParameters": []
} ,
"type": "Default",
"siteId": "d7941b24-72a7-4daf-a433-0cdfc80569bb",
"deviceId": "5eccad2e29da7c0008613b69",
"imageInfo": {
"skip": false,
"imageId": "04d69fe0-d826-42e9-82c0-45363a2b6fc7"
}
}

成功が返され、これが PnP UI に反映されます。


{
"response": "Device Claimed",
"version": "1.0"
}

 

スタックについて

DNAC PnPの主要なイノベーションの1つは、スタック番号の再割り当てに対応できるようになったことです。以前、スタックメンバへの電源投入は、トップからボトムまで、2分間空けることが推奨されていました。これは、インターフェイスの番号割り当てを決定的なものにするためです。スタックの番号再割り当ては、この問題への画期的な解決策です。2つのスタックケーブルメソッドの1つが使用可能で、かつ先頭スタックのスイッチのシリアル番号が必要です。
pre-plannedワークフローの API コールの例を2つ示します。1つ目は、デバイス追加コールです。スタックパラメータは True に設定する必要があります。


POST dna/intent/api/v1/onboarding/pnp-device/import
[
{
"deviceInfo": {
"serialNumber": "12345678902",
"aaaCredentials": {
"username": "",
"password": ""
} ,
"userSudiSerialNos": [] ,
"hostname": "adam123",
"pid": "c9300",
"sudiRequired": false,
"stack": true
}
}
]

2つ目はサイトクレームです。タイプを“StackSwitch”に変更し、2つの属性を追加する必要があります。
注記:“topOfStackSerialNumber”は、デバイスの追加に使用したシリアル番号と同じである必要があります。言い換えると、先頭スタックでの使用を意図したシリアル番号を使用して、デバイスを追加してください。スタックが DNAC にすべてのシリアル番号を提供するため、スタック内のどのスイッチがコンタクトを開始するかは関係ありません。


POST dna/intent/api/v1/onboarding/pnp-device/site-claim
{
"configInfo": {
"configId": "e156e9e6-653d-4016-85bd-f142ba0659f8",
"configParameters": []
} ,
"type": "StackSwitch",
"topOfStackSerialNumber":"12345678902",
"cablingScheme":"1A",

"siteId": "d7941b24-72a7-4daf-a433-0cdfc80569bb",
"deviceId": "5eccad2e29da7c0008613b69",
"imageInfo": {
"skip": false,
"imageId": "04d69fe0-d826-42e9-82c0-45363a2b6fc7"
}
}

 

次のステップ

このブログは、APIC-EM からの PnP API の移行に関するシンプルな例をご紹介しています。このスクリプトは、必要に応じて、スイッチスタッキングの処理にも使用できます。
Cisco DNA Center についてより詳しく知りたい方は、DevNet の Cisco DNA Centerにアクセスしてください。

お読みいただきありがとうございました。
@adamradford123

新しくなったDeveloper video channelをご覧ください。

取り上げてほしいトピックのご提案は、Twitterまで。

 

Tags: APIDevnet
Kazumasa Ikuta

シスコシステムズ合同会社 APJアーキテクチャー プリンシパルアーキテクト。2001 年入社。エリア担当 SE、通信事業者担当 SE、SDN応用技術室を経て、2021年よりアジア太平洋地域アーキテクチャーセントラルグループ所属、プリンシパルアーキテクト。主に企業向けのネットワーク運用管理全般および製品、SDNやネットワークプログラマビリティ関連、Cisco DevNetを担当。提案、構築、運用維持管理における技術サポート、本社開発部門と連携したアジア地域での製品や技術のロールアウトプラン策定と実行、対外的なプレゼンテーションなど、仕事を選ばず幅広く活動中。書籍:Ciscoネットワーク構築教科書[解説編](共著)Ciscoネットワーク構築教科書[設定編](共著)Cisco WAN 実践ケーススタディ(共著)