2017年10月22日日曜日

CISCO MERAKI APIの利用(2)

CISCO MERAKI APIを使ってデータベース化してみます。
Organization -> Network -> Device -> Client の順で作成します。

(1) テーブルの作成
organizations, networks, terminals, clientsテーブルを作成します。
organizationsテーブル
CREATE TABLE IF NOT EXISTS `organizations` (
`id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


networksテーブル
CREATE TABLE IF NOT EXISTS `networks` (
`id` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`organization_id` int(11) NOT NULL,
`timeZone` varchar(255) DEFAULT NULL,
`tags` varchar(255) DEFAULT NULL,
`type` varchar(255) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


terminalsテーブル
CREATE TABLE IF NOT EXISTS `terminals` (
`id` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`network_id` varchar(255) NOT NULL,
`lanip` varchar(255) DEFAULT NULL,
`mac` varchar(255) DEFAULT NULL,
`lat` double DEFAULT NULL,
`lng` double DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
`model` varchar(255) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


clientsテーブル
CREATE TABLE IF NOT EXISTS `clients` (
`id` varchar(255) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`terminal_id` varchar(255) NOT NULL,
`mdnsName` varchar(255) DEFAULT NULL,
`dhcpHostname` varchar(255) DEFAULT NULL,
`mac` varchar(255) DEFAULT NULL,
`ip` varchar(255) DEFAULT NULL,
`vlan` varchar(255) DEFAULT NULL,
`sent` int(11) DEFAULT NULL,
`recv` int(11) DEFAULT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


(2) API関数群の作成
API関数については、関数名をapiテーブル名としてAppControllerの中に作成します。
 
public function apiOrganization(){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://dashboard.meraki.com/api/v0/organizations/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: application / json",
"postman-token: 328a4947-4d6d-4152-0042-3c95b79f541a",
"x-cisco-meraki-api-key: naisyo"
),
CURLOPT_FOLLOWLOCATION => TRUE
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
/*
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
*/
$res = json_decode($response);
return $res;
}
public function apiNetwork($organization_id = NULL){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://dashboard.meraki.com/api/v0/organizations/".$organization_id."/networks",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: application / json",
"postman-token: 5a044421-38e9-58d1-5c1b-344513ee9bb2",
"x-cisco-meraki-api-key: naisyo"
),
CURLOPT_FOLLOWLOCATION => TRUE
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
$res = json_decode($response);
return $res;
}
public function apiTerminal($network_id = NULL){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://dashboard.meraki.com/api/v0/networks/".$network_id."/devices",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: application / json",
"postman-token: 75399286-ba00-ddcf-8037-959e7db17ff6",
"x-cisco-meraki-api-key: naisyo"
),
CURLOPT_FOLLOWLOCATION => TRUE
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
$res = json_decode($response);
return $res;
}
public function apiClient($terminal_id = NULL){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://dashboard.meraki.com/api/v0/devices/".$terminal_id."/clients?timespan=600",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: application / json",
"postman-token: 9b62c72d-46ba-615b-0426-2f790551fbb1",
"x-cisco-meraki-api-key: naisyo"
),
CURLOPT_FOLLOWLOCATION => TRUE
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
$res = json_decode($response);
return $res;
}
}
~
view raw AppController hosted with ❤ by GitHub


apiOrganization関数呼び出しをします。OrganizationsControllerに記述します。
public function getOrganization() {
$this->Organization->recursive = 0;
$this->set('organizations', $this->Paginator->paginate());
$result = $this->apiOrganization();
$data = array(
'id' => $result[0]->id,
'name' => $result[0]->name,
);
$this->Organization->save($data);
return $this->redirect(array('action' => 'index'));
}
view raw getOrganization hosted with ❤ by GitHub


次にネットワークを取得します。これもOrganizationsControllerに記述します。
public function getNetwork($id = null) {
if (!$this->Organization->exists($id)) {
throw new NotFoundException(__('Invalid organization'));
}
$options = array('conditions' => array('Organization.' . $this->Organization->primaryKey => $id));
$this->set('organization', $this->Organization->find('first', $options));
APP::import('Model','Network');
$this->Network = new Network;
$results = $this->apiNetwork($id);
foreach($results as $result){
$data = array(
'id' => $result->id,
'name' => $result->name,
'organization_id' => $result->organizationId,
'timeZone' => $result->timeZone,
'tags' => $result->tags,
'type' => $result->type
);
$this->Network->save($data);
}
return $this->redirect(array('controller' => 'networks','action' => 'index'));
}
view raw getNetwork hosted with ❤ by GitHub


次にデバイスを取得します。これはNetworksControllerに記述します。
public function getTerminal($id = null) {
if (!$this->Network->exists($id)) {
throw new NotFoundException(__('Invalid network'));
}
$options = array('conditions' => array('Network.' . $this->Network->primaryKey => $id));
$this->set('network', $this->Network->find('first', $options));
APP::import('Model','Terminal');
$this->Terminal = new Terminal;
$results = $this->apiTerminal($id);
foreach($results as $result){
$data = array(
'id' => $result->serial,
'name' => $result->name,
'network_id' => $result->networkId,
'lanip' => $result->lanIp,
'mac' => $result->mac,
'lat' => $result->lat,
'lng' => $result->lng,
'address' => $result->address,
'model' => $result->model,
);
$this->Terminal->save($data);
}
return $this->redirect(array('controller' => 'terminals','action' => 'index'));
}
view raw getTerminal hosted with ❤ by GitHub


次にクライアント情報を取得します。これはTerminalsControllerに記述します。
public function getClient($id = null) {
if (!$this->Terminal->exists($id)) {
throw new NotFoundException(__('Invalid terminal'));
}
$options = array('conditions' => array('Terminal.' . $this->Terminal->primaryKey => $id));
$this->set('terminal', $this->Terminal->find('first', $options));
APP::import('Model','Client');
$this->Client = new Client;
$results = $this->apiClient($id);
foreach($results as $result){
$data = array(
'id' => $result->id,
'name' => $result->description,
'terminal_id' => $id,
'mdnsName' => $result->mdnsName,
'dhcpHostname' => $result->dhcpHostname,
'mac' => $result->mac,
'ip' => $result->ip,
'vlan' => $result->vlan,
'sent' => $result->usage->sent,
'recv' => $result->usage->recv,
);
$this->Client->save($data);
}
return $this->redirect(array('controller' => 'clients','action' => 'index'));
}
view raw getClient hosted with ❤ by GitHub

これで情報を取得できました。

(3) Client情報の自動化
Client APIでは時刻がありません。取得した時刻を利用時刻とみなしてやってみます。
Client情報は随時更新されるので、5分に一度取得するようにします。
Shellを作成します。
app]$ vi Console/Command/MerakiShell.php
<?php
class MerakiShell extends Shell {
function main () {
App::import('Model','Terminal');
$this->Terminal = new Terminal;
$this->Terminal->recursive = 0;
$terminals = $this->Terminal->find('all');
APP::import('Model','Client');
$this->Client = new Client;
foreach($terminals as $terminal){
$results = $this->apiClient($terminal['Terminal']['id']);
foreach($results as $result){
$data = array(
'id' => $result->id,
'name' => $result->description,
'terminal_id' => $terminal['Terminal']['id'],
'mdnsName' => $result->mdnsName,
'dhcpHostname' => $result->dhcpHostname,
'mac' => $result->mac,
'ip' => $result->ip,
'vlan' => $result->vlan,
'sent' => $result->usage->sent,
'recv' => $result->usage->recv,
);
$this->Client->save($data);
}
}
}
public function apiClient($terminal_id = NULL){
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://dashboard.meraki.com/api/v0/devices/".$terminal_id."/clients?timespan=600",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: application / json",
"postman-token: 9b62c72d-46ba-615b-0426-2f790551fbb1",
"x-cisco-meraki-api-key: naisyo"
),
CURLOPT_FOLLOWLOCATION => TRUE
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
$res = json_decode($response);
return $res;
}
}
?>
view raw MerakiShell.php hosted with ❤ by GitHub


シェルスクリプトを作成
app]$ vi Vendor/MerakiShell.sh
#!/bin/bash

cd /home/ms000/www/oc/app
Console/cake meraki

権限を与えておきます。
app]$ chmod +x Vendor/MerakiShell.sh

cronに登録します。
app]$ crontab -e
0-59/5 * * * * /home/ms000/www/oc/app/Vendor/MerakiShell.sh

これでクライアント情報が自動で取得できるようになりました。

0 件のコメント:

コメントを投稿