ChatGPTの実践例の記録③「laravelでfortigateのapi機能で設定を変更する」


# ChatGPTの実践例の記録③ 2024.01.20

* **本記事でわかること**

chatGPTを使ったITエンジニアリング、問題解決の方法(自分の作業メモ)

* **今回のトピック・テーマ**

## 「laravelでfortigateのapi機能で設定を変更する」


※記事末尾に単語の補足あり

## ターン➀

### 自分:　質問
```bash
達成したいこと
・「laravelでfortigateのapi機能で設定を変更する」
あなたが行うこと
・どのファイルにどのようなコードを追記するかなど具体的なことを踏まえて、達成のための手順を示す
条件
・APIキーはすでに持っています
・guzzleを使用してください
・自己署名のサイトのセキュリティエラーを起こさないようにしてください。
```
### ChatGPT:　回答
```ChatGPT
「LaravelでFortiGateのAPI機能を使って設定を変更する」ための手順を説明します。Guzzle HTTPクライアントを使用し、自己署名サイトのセキュリティエラーを回避する方法も含めます。

事前準備
Guzzleのインストール: まずLaravelプロジェクトにGuzzleをインストールします。ターミナルで以下のコマンドを実行してください。

bash
Copy code
composer require guzzlehttp/guzzle
設定ファイルの準備: API接続に必要な情報（ベースURL、APIキーなど）を設定ファイルに保存します。.envファイルに以下の行を追加してください。

makefile
Copy code
FORTIGATE_BASE_URL=あなたのFortiGateデバイスのURL
FORTIGATE_API_KEY=あなたのAPIキー
コードの実装
以下の手順でLaravelにFortiGateのAPI機能を実装します。

新しいコントローラーの作成: FortiGateControllerを作成します。ターミナルで以下のコマンドを実行してください。

bash
Copy code
php artisan make:controller FortiGateController
コントローラーの編集: FortiGateControllerにAPI通信のための関数を追加します。以下のようなコードを記述します。

php
Copy code
<?php

namespace App\Http\Controllers;

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\Request;

class FortiGateController extends Controller
{
    public function updateConfig(Request $request)
    {
        $client = new Client([
            'base_uri' => env('FORTIGATE_BASE_URL'),
            'verify' => false, // 自己署名の証明書の警告を無視
            'headers' => [
                'Authorization' => 'Bearer ' . env('FORTIGATE_API_KEY'),
                'Accept'        => 'application/json',
            ],
        ]);

        try {
            $response = $client->request('PUT', '/api/v2/config', [
                'json' => $request->all() // ここに変更内容を入れる
            ]);

            return response()->json([
                'success' => true,
                'data' => json_decode($response->getBody()->getContents())
            ]);
        } catch (GuzzleException $e) {
            return response()->json([
                'success' => false,
                'message' => $e->getMessage()
            ], 500);
        }
    }
}
ルーティングの設定: routes/web.php または routes/api.php（APIとして使用する場合）に新しいルートを追加します。

php
Copy code
Route::put('/fortigate/config', [FortiGateController::class, 'updateConfig']);
テスト
APIテスト: Postmanや別のHTTPクライアントを使用して、作成したエンドポイントにリクエストを送信し、FortiGateの設定が変更されるか確認します。

エラーハンドリング: エラーが発生した場合のハンドリングも重要です。上記のコードではGuzzleの例外を捉えてJSONレスポンスとして返しています。

これでLaravelを使用してFortiGateのAPI機能で設定を変更する基本的な構成が完成しました。具体的なAPIエンドポイントやJSONの内容は、FortiGateのAPIドキュメンテーションに従って調整してください。
```
* **感想**

中々クオリティの高い回答が返ってきた。

## ターン②

### 自分:　質問
* **質問の方針**

回答でシンプルに気になったことを聞く。

```bash
あなたのFortiGateデバイスのURL
とはipaddressですか？それともエンドポイントのURLですか？
```
### ChatGPT:　回答
```ChatGPT
「あなたのFortiGateデバイスのURL」という記述は、FortiGateデバイスにアクセスするためのベースURLを指しています。これは一般的にデバイスのIPアドレス、またはネットワーク内で設定されたホスト名になります。

FortiGateのAPIを使用する場合、ベースURLは通常以下のいずれかになります：

IPアドレス: FortiGateデバイスの直接的なIPアドレス。例えば、https://192.168.1.1。
ホスト名: ネットワーク内でFortiGateに割り当てられたホスト名。例えば、https://fortigate.mydomain.local。
どちらを使用するかは、FortiGateデバイスの設定やネットワーク構成に依存します。最終的なURLは、FortiGateのAPIにアクセスするために必要なHTTP/HTTPSプロトコルとポート番号を含む完全なアドレスになることに注意してください。

たとえば、.envファイルで設定する場合は以下のようになります：

arduino
Copy code
FORTIGATE_BASE_URL=https://192.168.1.1
または

arduino
Copy code
FORTIGATE_BASE_URL=https://fortigate.mydomain.local
このURLはGuzzle HTTPクライアントによってAPIリクエストを送信する際のベースとして使用されます。
```
* **感想** 

回答に納得し理解した。

## ターン③

### 自分:質問
* **質問の方針**

実際に現在動いているFortiGateなので、変に設定は変えたくない。ので、そのままchatGPTにその旨を伝える。
それと、一回目の回答で気になっていたAPIテストについて何も知らないので具体的に聞いてみる。


```bash
「実際の動作に影響しないような、設定変更が確認できるだけ程度の設定変更事項」をあなたが提案して、その通りにコードを書きなおしてください。また、その設定方法も提示してください。使用している機種はfortigate60eです。

また、APIテストの方法、手順を具体的に示してください。
```
### ChatGPT:　回答
```ChatGPT
FortiGate 60Eで実際の動作に影響を与えずに設定変更を確認できる簡単な例として、「ログ設定の変更」を提案します。ログ設定を変更することで、実際のネットワークの動作には影響せず、API経由での設定変更が可能かどうかを確認できます。

設定変更の提案：ログレベルの変更
ログレベルを変更することは、システムに影響を与えることなく、設定の変更が確認できます。たとえば、ログレベルを「情報」から「警告」に変更するなどです。

コードの変更
以下はFortiGateControllerのupdateConfigメソッドをログレベルを変更するように書き換えたものです。ここでは、ログレベルを「information」から「warning」に変更する例を示します。

php
Copy code
public function updateLogLevel(Request $request)
{
    $client = new Client([
        'base_uri' => env('FORTIGATE_BASE_URL'),
        'verify' => false, // 自己署名の証明書の警告を無視
        'headers' => [
            'Authorization' => 'Bearer ' . env('FORTIGATE_API_KEY'),
            'Accept'        => 'application/json',
        ],
    ]);

    try {
        $response = $client->request('PUT', '/api/v2/cmdb/log/gui-display', [
            'json' => [
                'fortianalyzer-log-level' => 'warning' // ログレベルを変更
            ]
        ]);

        return response()->json([
            'success' => true,
            'data' => json_decode($response->getBody()->getContents())
        ]);
    } catch (GuzzleException $e) {
        return response()->json([
            'success' => false,
            'message' => $e->getMessage()
        ], 500);
    }
}
APIテストの手順
Postmanのインストール: PostmanはAPIテストに広く使用されるツールです。Postmanの公式ウェブサイトからダウンロードしてインストールします。

新しいリクエストの作成:

Postmanを開き、「New」をクリックして「Request」を選択します。
リクエストに名前を付け、適切なコレクションに保存します。
リクエストの設定:

メソッドを「PUT」に設定します。
URLにはLaravelサーバーの対応するエンドポイント（例: http://localhost:8000/fortigate/config）を入力します。
「Headers」セクションで、必要に応じてContent-Typeをapplication/jsonに設定します。
「Body」セクションを選択し、rawを選択してJSON形式でデータを入力します。例えば、空のJSON {} を使用できます。
リクエストの送信:

設定が完了したら、「Send」ボタンをクリックしてリクエストを送信します。
レスポンスの確認:

Postmanの下部に表示されるレスポンスを確認します。成功した場合、FortiGateからのレスポンスがJSON形式で表示されます。
これらの手順に従って、FortiGateのAPIをテストすることができます。APIの具体的なエンドポイントやパラメータは、FortiGateのドキュメントやAPIリファレンスを参照して適宜調整してください。
```
* **感想**

回答の通りにコードを追記し、Postmanについて少し調べインストールして実行した。しかし、APIで取得したJOSONファイルの中にはlog-levelらしき項目はなかった。

## ターン④

### 自分: 質問
* **質問の方針**

感想より、コードを修正するようにchatGPTに質問する。

```bash
現在のlogレベルを取得するコードを追加して、また手順を書き直してください。
```
### ChatGPT:　回答
```ChatGPT
FortiGateの現在のログレベルを取得するためのコードをFortiGateControllerに追加し、その後にログレベルを変更する手順を含めた新しい手順を示します。

コードの変更
ログレベルを取得するメソッドの追加: まずは、現在のログレベルを取得するためのメソッドをFortiGateControllerに追加します。
php
Copy code
public function getCurrentLogLevel()
{
    $client = new Client([
        'base_uri' => env('FORTIGATE_BASE_URL'),
        'verify' => false, // 自己署名の証明書の警告を無視
        'headers' => [
            'Authorization' => 'Bearer ' . env('FORTIGATE_API_KEY'),
            'Accept'        => 'application/json',
        ],
    ]);

    try {
        $response = $client->request('GET', '/api/v2/cmdb/log/gui-display');

        return response()->json([
            'success' => true,
            'data' => json_decode($response->getBody()->getContents())
        ]);
    } catch (GuzzleException $e) {
        return response()->json([
            'success' => false,
            'message' => $e->getMessage()
        ], 500);
    }
}
ルーティングの設定の更新: routes/web.php または routes/api.php に新しいルートを追加します。
php
Copy code
Route::get('/fortigate/log-level', [FortiGateController::class, 'getCurrentLogLevel']);
APIテストの手順
ログレベルの取得:

Postmanを開き、新しいリクエストを作成します。
メソッドを「GET」に設定し、URLにhttp://localhost:8000/fortigate/log-level（または適切なURL）を入力します。
「Send」ボタンをクリックしてリクエストを送信し、現在のログレベルを確認します。
ログレベルの変更:

新しいリクエストを作成または編集します。
メソッドを「PUT」に設定し、URLにhttp://localhost:8000/fortigate/config（または適切なURL）を入力します。
「Headers」セクションでContent-Typeをapplication/jsonに設定します。
「Body」セクションを選択し、rawを選択して、変更するログレベルのJSONデータ（例：{"fortianalyzer-log-level": "warning"}）を入力します。
「Send」ボタンをクリックしてリクエストを送信します。
変更後のログレベルの確認:

再度「GET」リクエストを/fortigate/log-levelに送信して、変更が反映されたことを確認します。
これらの手順により、FortiGateの現在のログレベルを取得し、新しい値に変更した後、変更が適用されたかどうかを確認できます。APIのエンドポイントやJSONの内容は、FortiGateのドキュメントに基づいて調整してください。
```
* **感想**

書かれたように修正したが、得られたJSONファイル内にはlog-levelの記載はなさそうだった。

##  ターン⑤

### 自分:　質問
* **質問の方針**

感想より、そのままJSONファイルの内容※➀をコピペして質問してみる。

```bash

※➀JSONファイルの内容は省略します。

GETメソッドでこのような情報が得られました。logレベルの情報は取得できていますか？
```
### ChatGPT:　回答
```ChatGPT
提供されたJSONレスポンスを見ると、logセクションにgui-displayの情報が含まれていますが、この部分にはログレベルに関する具体的な情報は含まれていないようです。通常、ログレベルに関する情報はlog-levelやseverityなどのキーで表されることが一般的です。

FortiGateのAPIとそのバージョンによっては、ログレベルの情報が異なるエンドポイントにあるか、または異なる形式で提供される可能性があります。したがって、ログレベルに関する正確な情報を取得するには、FortiGateのAPIドキュメントを参照するか、別のAPIエンドポイントを試す必要があるかもしれません。

FortiGateのAPIドキュメントに基づいて、ログレベルに関連する正しいAPIエンドポイントを特定し、そのエンドポイントに対してGETリクエストを実行することをお勧めします。

もしドキュメントで適切なエンドポイントが見つからない場合、FortiGateのサポートチームに連絡して、ログレベル情報を取得するための正しいAPIエンドポイントや方法について尋ねることも検討してください。FortiGateのAPIはバージョンやモデルによって異なる可能性があるため、モデルやソフトウェアのバージョンに関する情報も提供すると良いでしょう。
```
* **感想** 

わからないので、frotinetの公式サイト、fortigateのドキュメント、データシート当たってみるが、どのページにもエンドポイントに関する詳細な記述がなかった。３時間くらいずっと探してもなかった。しかし、最後にそれらしきfortigateのAPIのレファレンスページがあったので後日確認してみようと思う。
log-levelがapiで取得できなかったが、それ以外の基本情報が取得できていたことは大きな収穫となった。いくつかのエンドポイントでそれを確認できた。
また、PostmanというAPI検証が簡単にできるツールは知らなかったので知れてよかった。いちいちブラウザページを実装することになるところだった。


## おまけ
ChatGPTのほかにClaudAI,Bingなどを複数AIを併用しているが、主にメインChatGPTを使用している。自分の体感で申し訳ないが、ClaudAIは読解力が高い(頭がいい？)ので事実であることに重きを置いている。そうなると、正確な情報しか出力しないようになるので相対的に広範な知識を網羅できなくなる。ChatGPTは事実確認しながら付き合わないといけないが、全体で見てそちらのほうが効率がいい気がする。それと、調べものはBingに任せればいいかなと思ってるから。



* **単語の補足**

Laravel: PHPで書かれたWebアプリケーションフレームワーク
FortiGate: フォーティネット社が開発したネットワークセキュリティアプライアンス
API: アプリケーションプログラミングインターフェースの略で、ソフトウェアアプリケーション同士が相互に通信するための手段
Guzzle: PHPで書かれたHTTPクライアントライブラリで、HTTPリクエストを送信するための多くの機能を提供するソフトウェア
※ChatGPT4を使用