このドキュメントでは、CLSモジュール内で提供される機能を利用して、データの変換、プッシュ、または取り込みを可能にする新しいCloud Log Shipperプラグインを作成する方法について説明します。 このガイドに従えば、開発者は技術的な問題なく、独自に新しいプラグインを作成できるようになるはずです。
前提条件
- Python 3.xのプログラミング経験(中級レベル)。
- Netskope CE プラットフォームへのアクセス。
- プラグインを作成する必要のある製品またはソリューションへのAPIまたはPython SDKへのアクセス。
- 製品に対する最低限の権限を持つアカウント。
ログシッパーモジュール
Cloud ExchangeプラットフォームとそのCloud Log Shipperモジュールには、高度なカスタマイズを可能にする豊富な機能セットが付属しているため、以下に示すプラットフォームのさまざまな側面についてよく理解しておくことをお勧めします。
注:このモジュールは、Netskopeからサードパーティ製ツールへのデータ共有をサポートしています。
Netskopeの概念と用語
- コア: CEコアエンジンは、サードパーティ製プラグインとそのライフサイクルメソッドを管理します。プラットフォームと対話してさまざまなタスクを実行するための API エンドポイントがあります。
- モジュール:さまざまなワークフローを実行するために、モジュール固有のプラグインを呼び出す機能的なコード領域。CLSは、 Cloud Exchangeで動作するCloud Exchangeモジュールの1つです。
- プラグイン: プラグインとは Netskopeテナントから収集した情報/ログを変換してサードパーティに送信する、または取り込むロジックを備えたPythonパッケージ
- プラグイン構成:プラグイン構成とは、必要なパラメータで構成され、CEコアエンジンによって情報の変換、プッシュ、または取り込みのためにスケジュールされるプラグインクラスオブジェクトのことです。
- マッピング:プラットフォームに送信するデータの形式。これをマッピングと呼びます。
開発ガイドライン
- すべての Python コードのパッケージ ディレクトリ構造を使用します。
- プラグインパッケージに同梱されているすべてのサードパーティライブラリについて、既知の脆弱性がないか確認してください。
- 標準的なPythonのコーディング規約を必ず守ってください。(https://peps.python.org/pep-0008/)
- flake8 lint チェックを実行し、ドキュメント文字列チェックを有効にした状態で合格することを確認してください。1 行の最大長は 80 文字である必要があります。
- タイムスタンプ値を人間が読みやすい形式に変換します(エポックからDateTimeオブジェクトへ)。UIに表示される時刻が、現地のタイムゾーンであることを確認してください。
- 可能であれば、プラグインで設定パラメータを追加する際に、デフォルト値を追加してください。
- Pythonで記述されたスクリプトや統合機能については、必ず単体テストを作成してください。下記の「単体テスト」のセクションを参照してください。
- プラグインアーキテクチャは状態の保存を可能にする一方で、状態管理のために巨大なオブジェクトを保存することを回避します。
- プラグインのドキュメントリプションにリンクが含まれている場合は、ドキュメントページにリダイレクトするハイパーリンクである必要があります。 詳細については、CTE Trend Micro Vision Oneプラグインを参照してください。
- ロガーメッセージとトーストメッセージには、APIトークンとパスワードタイプのフィールド値を含めてはいけません。
- プラグインの機能開発においては、ページネーションを常に考慮に入れるべきです。
- ステータスコード429に対する再試行メカニズムを必ず追加してください。
- validateメソッドに渡されるパラメータを適切に検証し、すべてのパラメータに対して適切なヘルプテキストを提供します。
- 障害や重大な状況(レート制限、ペイロードサイズの超過など)が発生した場合に通知を発生させ、プラグインの状態をユーザーに通知するための通知オブジェクト。
- CE プラットフォームによって渡されるロガー オブジェクトを使用して、適切なロギング メカニズムを実装してください。 運用チームがトラブルシューティングを行う際に役立つよう、十分なログ記録が行われるようにしてください。通知に機密データが記録されたり、漏洩したりしないようにしてください。
- すべてのパラメータに対して適切なヘルプテキスト(ツールチップ)を提供してください。可能であれば、ツールチップでそのパラメータの重要性を説明するようにしてください。
- プラグイン設定パラメータには必ず意味のある名前とデスクリプションを指定してください。
- パラメータには、適切な設定タイプ(テキスト、数値、パスワード、選択式、複数選択式)を指定してください。
- アウトバウンド リクエスト (API/SDK) の作成中に、CE プラットフォームによって渡されるプロキシ構成辞書と SSL 証明書検証フラグを必ず使用してください。
- 必須ではないパラメーターの値を取得するようにしてください .get() メソッドを作成し、 .get() を使用するときにデフォルト値を提供します 方法。
- プラグインディレクトリ名(例:sample_plugin)がmanifest.jsonと一致していることを確認してください。IDフィールド
- API呼び出しを行う際には、ユーザーエージェントをヘッダーに追加する必要があります。ユーザーエージェントのフォーマット: Netskope -ce-
– – – 詳細については、URE Microsoft Azure AD または URE CrowdStrike Identity Protect プラグインを参照してください。注: プラグインのバージョンは動的に取得する必要があり、 Netskope -ce- を取得するには、 string は core で定義されたメソッドを使います。 - API トークンとパスワード フィールドでは、strip() を使用しないでください。
- ログ メッセージは「」で始まるはずです。
プラグイン [設定名]: “。例: “CLS Chronicle プラグイン [Chronicle 設定名]: 「. [これは提案です。設定名は避けることができます]。(logger.info(“ プラグイン: ”)) - エラーログを記録する際には、可能であれば例外のトレースバックも追加すべきです。使う: self.logger.error(error, details=traceback.format_exc())
- トーストメッセージには以下を含めるべきではありません
プラグイン: メッセージ内。 - API呼び出し中および呼び出し後に、適切な例外とステータスコードを捕捉するようにしてください。可能であれば、開発者はリクエストを行うためのヘルパーメソッドを作成し、必要に応じて適切なパラメータを指定してこのメソッドを呼び出すことができます。
- CHANGELOG.md ファイルには、追加、変更、修正などの適切なタグと、ユーザーにとって分かりやすいメッセージを追加して更新する必要があります。ファイル名がCHANGELOG.mdと完全に一致していることを確認してください。
- Pythonコードに脆弱性がないか確認してください。
プラグインの作成
このセクションでは、プラグインをゼロから作成するプロセスについて説明します。
NetskopeOSSの公開GitHubリポジトリからサンプルプラグインをダウンロードしてください。
開発環境のセットアップ
Python
当システムはPython3(バージョン3.7以降)を使用しています。開発環境にPython3がインストールされていることを確認してください。Pytest は単体テストを実行するために使います。
付属のPythonライブラリ
次の Python ライブラリがNetskope CE プラットフォームに含まれています。
図書館名 | バージョン |
|---|---|
aiofiles | 22.1.0 |
amqp | 5.1.1 |
anyio | 3.6.2 |
asgiref | 3.6.0 |
attrs | 22.2.0 |
azure-core | 1.26.2 |
azure-storage-blob | 12.14.1 |
bcrypt | 4.0.1 |
boto3 | 1.26.51 |
botocore | 1.29.51 |
billiard | 3.6.4.0 |
celery | 5.2.7 |
cabby | 0.1.23 |
cachetools | 5.2.1 |
celerybeat-mongo | 0.2.0 |
certifi | 2022.12.7 |
cffi | 1.15.1 |
chardet | 5.1.0 |
charset-normalizer | 3.0.1 |
click | 8.1.3 |
click-didyoumean | 0.3.0 |
click-plugins | 1.1.1 |
click-repl | 0.2.0 |
colorama | 0.4.6 |
colorlog | 6.7.0 |
cryptography | 39.0.0 |
cybox | 2.1.0.21 |
defusedxml | 0.7.1 |
dnspython | 2.3.0 |
docker | 6.0.1 |
fastapi | 0.89.1 |
furl | 2.1.3 |
google-api-core | 2.11.0 |
google-auth | 2.16.0 |
google-cloud-core | 2.3.2 |
google-cloud-pubsub | 2.13.12 |
google-cloud-pubsublite | 1.6.0 |
google-cloud-storage | 2.7.0 |
google-crc32c | 1.5.0 |
google-resumable-media | 2.4.0 |
googleapis-common-protos | 1.58.0 |
grpc-google-iam-v1 | 0.12.6 |
grpcio | 1.51.1 |
grpcio-status | 1.51.1 |
gunicorn | 20.1.0 |
h11 | 0.14.0 |
idna | 3.4 |
importlib-metadata | 6.0.0 |
isodate | 0.6.1 |
jmespath | 1.0.1 |
jsonpath | 0.82 |
jsonschema | 4.17.3 |
kombu | 5.2.4 |
libcst | 0.3.21 |
libtaxii | 1.1.119 |
lxml | 4.9.2 |
mongoengine | 0.25.0 |
more-itertools | 9.0.0 |
MarkupSafe | 2.1.2 |
memory-profiler | 0.61.0 |
mixbox | 1.0.5 |
mongoquery | 1.4.2 |
msrest | 0.7.1 |
multidict | 6.0.4 |
mypy-extensions | 0.4.3 |
netskopesdk | 0.0.25 |
numpy | 1.23.5 |
oauthlib | 3.2.2 |
onelogin | 3.1.0 |
ordered-set | 4.1.0 |
orderedmultidict | 1.0.1 |
overrides | 6.5.0 |
pandas | 1.5.0 |
packaging | 23.0 |
passlib | 1.7.4 |
pycparser | 2.21 |
prompt-toolkit | 3.0.36 |
proto-plus | 1.22.2 |
protobuf | 4.21.12 |
psutil | 5.9.4 |
pydantic | 1.10.4 |
pyasn1 | 0.4.8 |
pyasn1-modules | 0.2.8 |
PyJWT | 2.6.0 |
pymongo | 4.3.3 |
pyparsing | 3.0.9 |
python-dateutil | 2.8.2 |
pyrsistent | 0.19.3 |
python-multipart | 0.0.5 |
python3-saml | 1.15.0 |
pytz | 2022.7.1 |
PyYAML | 6.0 |
requests | 2.28.2 |
requests-oauthlib | 1.3.1 |
rsa | 4.9 |
six | 1.16.0 |
starlette | 0.22.0 |
sniffio | 1.3.0 |
s3transfer | 0.6.0 |
stix | 1.2.0.11 |
taxii2-client | 2.3.0 |
typing-inspect | 0.8.0 |
typing-utils | 0.1.0 |
typing_extensions | 4.4.0 |
urllib3 | 1.26.14 |
uvicorn | 0.20.0 |
vine | 5.0.0 |
wcwidth | 0.2.6 |
weakrefmethod | 1.0.3 |
websocket-client | 1.4.2 |
Werkzeug | 2.2.2 |
xmlsec | 1.3.11 |
zipp | 3.11.0 |
requests-mock | 1.7.0 |
カスタムプラグインライブラリを含む
Netskopeは、プラグインが必要とするサードパーティ製のPythonライブラリをすべてプラグインパッケージ自体にバンドルすることを推奨しています。pipインストーラーは、このバンドルを実現するために使用します。ディレクトリを入力として受け取るスイッチが用意されています。 ディレクトリが指定されている場合、pipはそのディレクトリにパッケージをインストールします。
例えば、以下のコマンドを実行すると、「cowsay」パッケージが「lib」ディレクトリにインストールされます。
> pip install cowsay --target ./lib
これに関する公式ドキュメントについては、https://pip.pypa.io/en/stable/reference/pip_install/#cmdoption-t を参照してください。
上記のlibフォルダからモジュールをインポートする際は、 絶対インポートではなく相対インポートを使用する必要があります。 以下に示すように
from .lib import cowsay
IDE
推奨されるIDEはPyCharmまたはVisual Studio Codeです。
プラグインディレクトリ構造
このセクションでは、ログシッパープラグインの典型的なディレクトリ構造について説明します。
/sample_plugin/ ├── /utils/ ├── syslog_cef_generator.py ├── syslog_constants.py ├── syslog_exceptions.py ├── syslog_helper.py ├── syslog_ssl.py ├── syslog_validator.py ├── __init__.py ├── CHANGELOG.md ├── icon.png ├── main.py ├── mappings.json └── manifest.json
- __init__.py:CEコードでは、すべてのプラグインパッケージはPythonモジュールとして扱われます。すべてのプラグインパッケージに空の「__init__.py」が含まれていることを確認してください。ファイル。
- icon.png: プラグインのアイコンロゴ。これは、UI 上のプラグインのチクレットと設定カードに表示されます。ロゴには、推奨サイズ 300*50 ピクセルまたは同様のアスペクト比の透明なバックグランドが必要です。
- CHANGELOG.md:このファイルにはプラグインの更新に関する詳細が含まれており、「追加」、「変更」、「修正」などの適切なタグと、ユーザーにとって分かりやすい適切なメッセージを追加して更新する必要があります。
- main.py:このPythonファイルには、transform、push、validateメソッドの具体的な実装を含むPluginクラスが含まれています。
- manifest.json:プラグインパッケージのマニフェストファイル。設定可能なすべてのパラメータとそのデータ型に関する情報が含まれています。このファイルには、プラグインの統合に関する詳細情報も記載されています。
- Mappings.json:このファイルには、プラグインに必要なデフォルトのマッピングファイルが含まれています。 プラグイン用。 指定されていない場合は manifest.json ファイルで指定されているデフォルトのマッピングが使用されますが、そのようなマッピングファイルが見つからないため、 Cloud Exchangeエラーをスローします。
- utils/: このディレクトリは ユーティリティ関数を記述するためのもので、プラグインの要件に応じてさまざまなファイルが含まれています。 ここにsyslogプラグイン固有のファイルが表示されます。
- syslog_cef_generator.py: ジェネレーターファイルには、プラグイン用に選択されたマッピングファイルに基づいて、 Netskope jsonデータをサードパーティがサポートするデータタイプに変換するロジックが含まれています。
- syslog_constants.py:このファイルには、プラグイン全体で使用できる定数が含まれています。 BASE_URL、Severity マップなど。
- syslog_exceptions.py:このファイルには、マッピング検証例外やデータ形式固有の例外など、プラグインによって発生する可能性のあるカスタム例外が含まれています。
- syslog_helper.py:このファイルには、マッピングスキーマを検証したり、データ型に基づいてマッピングファイルを取得したりするためのヘルパー関数が含まれています。
- syslog_ssl.py:このファイルには、サードパーティプラットフォームとの接続を確立するためのロジックが含まれています。
- syslog_validator.py:このファイルには、設定パラメータの検証に加え、マッピングや接続に関連する検証も含まれています。
リストされているファイルのうち、「utils」フォルダと「mappings.json」を除くファイルは、プラグインの統合に必須ですが、開発者は特定の統合要件に基づいて他のファイルを追加できます。
注:プラグインディレクトリ名 (例: sample_plugin) が manifest.json と一致していることを確認してください。IDフィールド
CHANGELOG.md
これはプラグインの更新に関する詳細情報を含むファイルであり、追加済み、変更済み、修正済みなどの適切なタグと、ユーザーにとって分かりやすい適切なメッセージを追加して更新する必要があります。
- 追加: 新しい機能が追加されたときにそれを使う
- 修正済み: バグやエラーが修正された場合に使用します。
- 変更: プラグインの既存の実装に変更があった場合
変更履歴のサンプル.md
# 1.0.1 ## Fixed - Fixed pagination when there are more than 10k Logs # 1.0.0 ## Added - Initial release.
Mappings.json
これはプラグインのマッピングファイルを含むJSONファイルであり、CLSモジュールがNetskopeデータをプラグインがサポートするデータタイプに変換する際に読み込まれます。
- Mappings.json の一般的なパラメータには次のものがあります。
- name: (文字列) マッピングファイルの名前。(必須)
- jsonData: (string) すべてのフィールドをJSONエスケープ文字列としてマッピングしたフィールド。(必須)
- isDefault: (boolean) このマッピングファイルがデフォルトかどうかを指定します。ユーザーはデフォルトのマッピングを削除/編集することはできません。(デフォルト値:False)(オプション)
- Log Shipperプラグインには、必ずマッピングファイルを作成する必要があります。マッピングには、プラグインがサポートする適切な型とサブタイプを含める必要があります。変換を行わない場合でも、プラグインはサブタイプを定義する必要があります。例えば:
{ "taxonomy": { "json": { "events": { "application": [], "page": [] } } } } - サンプルのmappings.jsonファイル。
{ "name": "Default Mappings", "jsonData": "{\"delimiter\":\"|\",\"syslog_map_version\":\"2.0.3\",\"cef_version\":\"0\",\"validator\":\"valid_extensions.csv\",\"taxonomy\":{\"logs\":{\"info\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"warning\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"error\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}}},\"webtx\":{\"v2\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}}},\"alerts\":{\"anomaly\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"dlp\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"malware\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"policy\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"CompromisedCredential\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"LegalHold\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"Malsite\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"Quarantine\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"Remediation\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"SecurityAssessment\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"Watchlist\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"uba\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}}},\"events\":{\"infrastructure\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"page\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"application\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"audit\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}},\"network\":{\"header\":{\"Target_Field\":{\"default_value\":\"Netskope\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}},\"extension\":{\"Target_Field\":{\"default_value\":\"default_value\",\"mapping_field\":\"Netskope_Field\",\"transformation\":\"String\"}}}},\"json\":{\"alerts\":{\"anomaly\":[],\"dlp\":[],\"malware\":[],\"policy\":[],\"CompromisedCredential\":[],\"LegalHold\":[],\"Malsite\":[],\"Quarantine\":[],\"Remediation\":[],\"SecurityAssessment\":[],\"Watchlist\":[],\"uba\":[]},\"events\":{\"application\":[],\"audit\":[],\"infrastructure\":[],\"page\":[],\"network\":[]}}}}"
Manifest.json
これは、プラグインに関連するメタ情報を格納する JSON ファイルです。このファイルは、CLS モジュールによって読み込まれ、UI にプラグインを表示するとともに、必要な構成パラメータ、プラグイン ID、プラグイン名など、プラグインに関する詳細情報を CLS モジュールが把握できるようにします。
- CLSがプラグインオブジェクトを適切にインスタンス化できるように、すべてのプラグインには必要な情報を含むこのファイルが含まれている必要があります。
- マニフェスト.json の一般的なパラメーターには次のものがあります。
- name: (文字列) プラグインの名前。(必須)
- id: (文字列) プラグインパッケージのID。Cloud Exchangeにインストールされているすべてのプラグインで、一意であることを確認してください。IDはプラグインパッケージのディレクトリ名と一致する必要があります。(必須)
- version: (文字列) プラグインのバージョン。MAJOR.MINOR.PATCH の使用 (例:1.0.1)バージョン管理方式は推奨されますが、特に制限はありません。(必須)
- 型: (配列) プラグインでサポートされているデータ型の型。使用可能なデータタイプは、「アラート」、「イベント」、「webtx」、「ログ」です。
- デスクリプション: (文字列) プラグインのデスクリプション。 プラグインの機能と使用方法について説明した詳細なデスクリプションを提供します。 (元。– このプラグインは、SIEM プラットフォームにデータを取り込むために使用されます)。 デスクリプションはプラグイン設定カードに表示されます。 (必須)。デスクトップリプションにリンクが含まれている場合は、プレーンテキストではなくハイパーリンクにする必要があります。
- マッピング:送信先のデータフォーマットの種類。(必須)(このパラメータは、プラグインのマッピングファイル内の「name」パラメータと同一である必要があります。)
- 設定: (配列) プラグインに必要なすべてのパラメーターに関する情報 (名前、タイプ、ID など) を含む JSON オブジェクトの配列。ネストされた JSON オブジェクトによくあるパラメーターについては、以下で説明します。
- ラベル:パラメータの名前。これはプラグインの設定ページに表示されます。(必須)
- key: プラグイン設定が使用される Python dict オブジェクト内のキーとして使用される一意のパラメーター キー。 (必須)
- type: パラメータの値の型。使用可能な値は、「text」、「password」、「number」、「choice」、「multichoice」です。(必須)詳細については、下記の「プラグイン設定パラメータの種類」セクションを参照してください。
- default: このパラメータのデフォルト値。この値は、CLS UI のプラグイン設定ページに表示されます。サポートされているデータ型は、「テキスト」、「数値」、「リスト」(複数選択型の場合)です。(必須)
- mandatory: このパラメータが必須かどうかを示すブール値。パラメータが必須の場合、CLS UI ではパラメータに空の値を指定することはできません。許容される値は「true」と「false」です。(必須)
- デスクリプション: パラメータと期待値に関する詳細を提供する、パラメータのヘルプ テキスト レベルのデスクリプション。 この文字列は、プラグインの設定ページにヘルプテキストとして表示されます。(必須)
- 選択肢:キーと値をJSONキーとして含むJSONオブジェクトのリスト。このパラメータは
'type': 'choice and multichoice`のみでサポートされています。
Plugin Configuration Parameter types
プラグインのmanifest.jsonファイルのconfigurationセクションに、必要なプラグイン設定パラメータがすべて記載されていることを確認してください。
Password Parameter
このパラメータは、API エンドポイントでの認証のためのシークレット/パスワードを保存するために使用されます。 パスワードを型とするパラメータは、プラグイン設定ページにパスワード入力欄が表示され、プラットフォームによって難読化および暗号化されます。
サンプルJSON
"configuration": [
{
"label": "API Token",
"key": "api_token",
"type": "password"
},
]
プラグイン設定画面:

Text Parameter
このパラメータは、ベースURL、ユーザー名などの文字列情報を格納します。 このパラメータは、プラグイン設定ページに通常のテキスト入力欄として表示されます。
サンプルJSON
"configuration": [
{
"label": "Tenant Name",
"key": "tenant_name",
"type": "text"
},
]
プラグイン設定画面:

Number Parameter
このパラメータは数値/浮動小数点値を保存するために使用されます。 このパラメータは、プラグイン設定ページに数値入力ボックスとして表示されます。(注:これはCloud Threat Exchangeプラグイン開発ガイドからの抜粋です)
サンプルJSON
"configuration": [
{
"label": "Maximum File hash list size in MB.",
"key": "max_size",
"type": "number"
},
]
プラグイン設定画面:

Choice Parameter
Use this parameter for storing any enumeration parameter values. This parameter will have a dropdown box on the plugin configuration page.
サンプルJSON
{
"label": "Syslog Protocol",
"key": "syslog_protocol",
"type": "choice",
"choices": [
{
"key": "TLS",
"value": "TLS"
},
{
"key": "UDP",
"value": "UDP"
},
{
"key": "TCP",
"value": "TCP"
}
],
"default": "UDP",
"mandatory": true,
"description": "Protocol to be used while ingesting data."
},
プラグイン設定画面:

入力項目を選択した後:

Multichoice Parameter
このパラメータは、複数の選択肢の値を保存するために使用します。 このパラメータは、プラグイン設定ページにドロップダウンボックスとして表示され、複数の値を選択できるようになります。(注:これはCloud Threat Exchangeプラグイン開発ガイドからの抜粋です。)
使う 'multichoice' パラメータはマニフェストファイルに含まれますが、「必須」パラメータは False のままにしてください。
サンプルJSON
"configuration": [
{
"label": "Severity",
"key": "severity",
"type": "multichoice",
"choices": [
{
"key": "Unknown",
"value": "unknown"
},
{
"key": "Low",
"value": "low"
},
{
"key": "Medium",
"value": "medium"
},
{
"key": "High",
"value": "high"
},
{
"key": "Critical",
"value": "critical"
}
],
"default": [
"critical",
"high",
"medium",
"low",
"unknown"
],
"mandatory": false,
"description": "Only indicators with matching severity will be saved."
}
]
プラグイン設定ビュー:

Toggle Parameter
このパラメータはブール値を格納します。トグル有効はTrue、トグル無効はFalseです。
生ログを変換します('transformData'):
If enabled, Raw logs will be transformed using selected mapping file, else raw logs will be sent to SIEM. The ingestion may be affected if the SIEM does not accept raw logs format.(Default: True)
システム プロキシ ('proxy'):
Use system proxy configured in Settings.(Default: False)
プラグイン設定ビュー:
注:このパラメータはCoreによって提供されるものであり、プラグインのmanifest.jsonファイルから追加することはできません。
main.py
このPythonファイルには、プラグインの中核となる実装が含まれています。
Standard Imports
from netskope.integrations.cls.plugin_base import ( PluginBase, ValidationResult, PushResult, )
PluginBase Variables
PluginBase は、プラグインのライフサイクル メソッド中に使用できる変数へのアクセスを提供します。 以下は変数の一覧です。
変数名 | Usage | デスクリプション |
自己名、 | self.logger.error(“Message”) self.logger.warn(“メッセージ”) self.logger.info(“Message”) | ロガーハンドルはコアによって提供されます。このオブジェクトを使用して重要なイベントを記録します。 ログはCE監査ログに表示されます。詳細については、 「ログ記録」を参照してください。 |
self.configuration | self.configuration. 得る( | プラグインインスタンスの設定オブジェクトのJSON表現。これを使用して、認証クレデンシャル、サーバーの詳細などの構成属性にアクセスします。manifest.json に記載されている属性のキー名を使用します。 |
self.last_run_at | self.last_run_at:self.last_run_at.timestamp() の場合 この形式は、最後の実行時間をエポック形式に変換するためのものです。 | このプラグインが正常に実行された最新の時刻を示す日時値。 |
self.storage | Log Shipperは、プラグインが状態を維持するためのメカニズムを提供します。このオブジェクトは、後続の呼び出しで必要となる状態を保持します。 このオブジェクトのデータ型はPythonの辞書型です。 | |
self.notifier | self.notifier.info(“message”) self.notifier.warn(“message”) self.notifier.error(“message”) | このオブジェクトは、CEコアの通知機能のハンドルを提供します。このオブジェクトを使用して、通知をプラットフォームにプッシュします。 通知はCLS UI上に表示されます。メッセージには、ユーザーが読んで必要な行動をとれるように、要約された情報が含まれていることを確認してください。 例えば: Netskopeプラグインの通知機能。push()メソッドが製品の8MB制限を超えた場合。 |
self.use_proxy | requests.get(url=url, プロキシ=self.proxy) | システムのプロキシ設定が設定されている場合はそのハンドル、設定されていない場合は {}。 |
self.ssl_validation | requests.get(url=url,verify=self.ssl_validation) | REST API呼び出しに対してSSL検証を強制するかどうかを示すブール値。 |
self.source | helper.get_tenant_cls(self.source) | データ取得元のプラグイン名を含む文字列値。 |
self.mappings | get_syslog_mappings( self.mappings,データ型) | プラグインのマッピング情報を含むJSON文字列。 |
プラグインクラス
- プラグインクラスはPluginBaseクラスを継承する必要があります。PluginBase クラスはNetskope .integrations.cls.plugin_baseで定義されています。
- Plugin クラスがプッシュと変換の実装を提供していることを確認してください。使用ケースに応じて、プル、検証、マッピング、またはソース メソッドを実装できます。
- プラグインの機能開発においては、ページネーションを常に考慮に入れるべきです。
- プラグインクラスには、サードパーティAPIとの接続と認証を確立するために必要なすべてのパラメータが含まれます。
- PLUGIN_NAME、LIMITなどの定数は宣言する必要があります。
"""Sample plugin implementation.
This is a sample implementation of base PluginBase class. Which explains the concrete implementation of the base class.
"""
from netskope.common.utils import AlertsHelper
from netskope.integrations.cls.plugin_base import (
PluginBase,
ValidationResult,
PushResult,
)
PLUGIN_NAME = "<module> <plugin_name> Plugin"
class SamplePlugin(PluginBase):
"""SamplePlugin class having concrete implementation for transforming and pushing logs.
This class is responsible for implementing transform, push and validate methods with proper return types,
so that it's lifecycle execution can be scheduled by the CLS core engine.
"""
Def Transform()
これはPluginBaseクラスの抽象メソッドです。
- このメソッドは、ログを別のプラットフォームに送信するために変換するロジックを実装します。
- Netskopeのイベント/アラートを変換するためのヘルパー関数とジェネレーター関数を作成できます。
- この方法では、「生ログを変換する」トグルの「transformData」変数は、「トグルパラメータ」のセクションで説明されているように適切に処理する必要があります。
def transform(self, raw_data, data_type, subtype) -> List:
"""To Transform the raw netskope JSON data into target platform supported data formats."""
try:
# Get the mapping file content
except Exception as err:
self.logger.error(f”{PLUGIN_NAME}: An error occurred while getting mapping. Error: {str(err)}"
)
raise
# Initialize generator/helper objects if required
transformed_data = []
for data in raw_data:
# Map headers and extensions as per mapping file
# append transformed data in the transformed_data list
return transformed_data
Def Push()
これはPluginBaseクラスの抽象メソッドです。
- このメソッドは、CE プラットフォームによって変換されたログを製品 API エンドポイントまたはソケット接続にプッシュするロジックを実装します。
- 変換されたデータを含むすべてのデータを受信し、その後送信します。データをプッシュするには、あらゆる種類の戦略を使用できます。 ソケット接続であれ、REST APIであれ。
- このメソッドは、CE プラットフォームが変換されたデータを受信したときに呼び出されます。
- APIエンドポイントがサポートする最大ペイロードサイズを超えた場合は必ず対処してください。 このケースに対処する方法は複数考えられます。
- API エンドポイントがペイロード サイズが固定された複数のリクエストをサポートしている場合は、データをチャンクで送信します。
- API エンドポイントが複数のリクエストをサポートしていない場合 (つまり、 (1回のAPI呼び出しでのみプッシュできます)プラグインは残りのログをスキップして、共有フィルターを調整するようにユーザーに通知するか、ペイロードサイズ超過のエラーで失敗することができます。
- 接続とHTTPレスポンスコードに関するすべての例外を処理し、エラーが発生した場合は、エラーメッセージとロガーとともに例外を発生させます。
- API呼び出しを行う際には、ユーザーエージェントをヘッダーに追加する必要があります。ユーザーエージェントのフォーマット:Netskope-ce-
– –。 - このメソッドでは、「システム プロキシを使う」トグルの「プロキシ」変数を API 呼び出し中に使う必要があります。
- PushResultオブジェクト(PushResultデータモデルを参照)を、プッシュ操作が成功したかどうかを示す成功フラグとともに返します。
def push(self, transformed_data, data_type, subtype) -> PushResult:
""Push the logs to the 3rd party systems.
This method will be invoked while pushing the logs with 3rd party systems.It takes in transformed_data, data_type and subtype as arguments while pushing this data via sockets to the 3rd party platform.
"""
try:
# API Calls or Socket write operations to push the data
except Exception as err:
self.logger.error(f”{PLUGIN_NAME}: Error occurred during pushing data. Error: {str(err)}"
)
raise
定義 Validate()
これはPluginBaseクラスの抽象メソッドです。
- このメソッドは、プラグイン構成を作成する際に渡されたプラグイン構成および認証パラメータを検証します。
- このメソッドは、新しい設定が作成または更新された場合にのみ呼び出されます。
- プラグイン設定の検証メソッドでは、空欄の検証と型チェックの検証を別々に行う必要があります。
- 必須パラメータがすべて適切なデータ型で渡されていることを検証します。
- 認証パラメータと API エンドポイントを検証して、プラグインのライフサイクルがスムーズに実行されるようにします。
- 検証中に、API トークンとパスワード フィールドを除く、ベース URL、電子メール、ユーザー名などの構成パラメータに対して、strip() を使用します。
- 検証の成功または失敗を示す成功フラグと、検証失敗の理由を含む検証メッセージを含むValidationResultオブジェクト(ValidationResultデータモデルを参照)を返します。
def validate(self, data):
"""Validate the Plugin configuration parameters.
Validation for all the parameters mentioned in the manifest.json for the existence and
data type. Method returns the netskope.integrations.cls.plugin_base.ValidationResult object with success = True in the case
of successful validation and success = False and a error message in the case of failure.
Args:
data (dict): Dict object having all the Plugin configuration parameters.
Returns:
netskope.integrations.cls
.plugin_base.ValidateResult: ValidateResult object with success flag and message.
"""
self.logger.info(f"{PLUGIN_NAME}: Executing validate method for Sample plugin")
if (
"secret_field_id1" not in data
or not data["secret_field_id1"]
or type(data["secret_field_id1"]) != str
):
self.logger.error(
データモデル
このセクションでは、データモデルとその特性を一覧表示します。
PushResultクラス
- このクラスには、製品 API エンドポイントへのインジケーターのプッシュ操作の結果が含まれます。
- 成功フラグはプッシュ操作の結果を示し、メッセージフラグは失敗した場合に適切なエラーメッセージを示す必要があります。 (成功の場合は、成功フラグがTrueのシンプルな成功メッセージが返されます。)
Data Model Properties
名前 | タイプ | デスクリプション |
success | bool | 成功フラグは、プッシュ操作が成功したか失敗したか、その結果を示します。 |
message | string | メッセージフィールドは失敗の場合のエラーを示します。 成功の場合には、シンプルな成功メッセージでも構いません。 |
from netskope.integrations.cls.plugin_base import PushResult
PushResult(
success=True,
message="Successfully pushed data to 3rd party."
)
ValidationResultクラス
- このクラスには、プラグインの新しい設定を作成する際にPluginオブジェクトに渡されるプラグイン設定パラメータに対する検証プロセスの結果が含まれています。
- validate メソッドに渡されるすべてのパラメータが、データ型と値に対して検証されていることを確認してください。
- Validate メソッドは、検証操作の結果を示す成功フラグと、検証が失敗した場合に適切なエラーメッセージを含むメッセージフィールドを持つ、このクラスのオブジェクトを返します。 (成功した場合は、成功フラグがTrueのシンプルな成功メッセージを返す必要があります。)
Data Model Properties
名前 | タイプ | デスクリプション |
success | bool | 成功フラグは、検証操作が成功したか失敗したか、その結果を示します。 |
message | string | メッセージフィールドは失敗の場合のエラーを示します。 成功の場合には、シンプルな成功メッセージでも構いません。 |
rom netskope.integrations.cls.plugin_base import ValidationResult
ValidationResult(
success=True,
message="Validation Successful for Sample plugin"
)
ログ記録
Log Shipperは、ログ記録用のロガーオブジェクトへのハンドルを提供します。
- コード内でprint文を使用することは避けてください。
- このオブジェクトは、タイムスタンプフィールドを使用して中央のCEデータベースにログを記録します。サポートされているログレベルは、情報、警告、エラーです。
- API認証情報やその他の機密情報がログメッセージに漏洩しないようにしてください。
- CE プラットフォームによって渡されるロガー オブジェクトを使用して、適切なロギング メカニズムを実装してください。
- 運用チームがトラブルシューティングを行う際に役立つよう、十分なログ記録が行われるようにしてください。
- 通知やログに機密データが記録されたり、漏洩したりしないようにしてください。
self.logger.error(
f"{PLUGIN_NAME}: Error log-message goes here."
)
self.logger.warn(
f"{PLUGIN_NAME}: Warning log-message goes here."
)
self.logger.info(
f"{PLUGIN_NAME}: Info log-message goes here."
)
通知
Log Shipper は通知オブジェクトのハンドルを提供します。このハンドルは Log Shipper UI 上で通知を生成するために使用できます。
- このオブジェクトは、CE プラットフォームから Plugin オブジェクトに渡されます。 すべてのプラグイン統合は ユーザーに即座に通知する必要のある障害が発生した場合はいつでもこのオブジェクトを使用できます。 通知のタイムスタンプは CE プラットフォームによって管理されます。
- このオブジェクトは、UI上に通知を表示し、障害の深刻度に応じて色分けを行います。サポートされている通知の重要度は、情報、警告、エラーです。
- 通知メッセージに、API認証情報やその他の機密情報が含まれていないことを確認してください。
- 障害や重大な状況(レート制限、ペイロードサイズの超過など)が発生した場合に通知を発生させ、プラグインの状態をユーザーに通知するための通知オブジェクト。
self.notifier.info(
f"{PLUGIN_NAME}: Info notification-message goes here."
)
self.notifier.error(
f"{PLUGIN_NAME}: Error notification-message goes here."
)
self.notifier.warn(
f"{PLUGIN_NAME}: Warning notification-message goes here."
)
Testing
Linting
ビルドプロセスの一環として、いくつかのリンターを実行して、 プログラミングエラー、スタイルエラー、および潜在的なセキュリティ問題を検出します。
Flake8
これは基本的なリンターです。必要な依存関係がすべて揃っていなくても実行でき、不要なエラーを検出します。 また このリンターを使用して、標準的な Python PEP8 フォーマットスタイルを強制します。 まれに、このリンターから返されるエラーや警告を無効にする必要が生じる場合があります。エラーを無効にしたい行に、次のようなインラインコメントを追加することで、この操作を実行できます。
# noqa:
例えば、
example = lambda: 'example' # noqa: E731
インラインコメントを追加する際は、必ず無効化するエラーコードを含めてください。そうすれば、同じ行に他のエラーがあった場合も報告されます。
詳細はこちら: https://flake8.pycqa.org/en/latest/user/violations.html#in-line-ignoring-errors 。
Flake8リンターでは、PEP8スタイルのドキュメント文字列チェックも有効になっています。したがって、すべての関数/モジュールに適切なドキュメンテーション文字列が追加されていることを確認してください。
単体テスト
単体テストを実施し、コードの小さな単位を隔離された状態で、かつ決定論的にテストするようにしてください。単体テストでは、外部 API との通信や モックの使用を避けるようにしてください。 単体テストによってコードカバレッジが70%以上であることを確認してください。
環境設定
単体テストを行うには、統合または自動化スクリプトをプラグイン(ディレクトリ)構造で開発する必要があります。 セットアップを実行するために必要なすべてのPythonモジュール依存関係をインストールするには、PIPを使用します。 テストを実行する前に、CEコアリポジトリのrequirements.txtに記載されている必要な依存関係をすべてインストールしてください。
ユニットテストを作成する
ユニットテストは、以下の名前の別のPythonファイルに記述してください。
Mocking
モックにはpytest-mockを使います。 pytest-mockはデフォルトで有効になっており、上記の基本環境にインストールされています。モッカーオブジェクトを使うには、テスト関数のパラメータとしてパスするだけです。モッカーは プラグインクラスオブジェクトと外部APIの両方をモックできます。
例えば、
def test_push(mocker, common_config):
"""To test push method of CLSPlugin."""
cls_plugin = CLS_Plugin(
<name>,
common_config,
None,
None,
logger,
source="<source_name>",
mappings=<mapping_json_string>,
)
# Initialize required classes
syslogger = logging.getLogger(
"SYSLOG_LOGGER_{}".format(threading.get_ident())
)
mocker.patch(
"netskope.plugins.Default.cls.main.CLSPlugin.init_handler",
return_value=syslogger,
)
try:
cls_plugin.push(data, data_type, subtype)
except Exception as e:
assert False, f"Push raised exception: {e}"
ユニットテストを実行する
$ PYTHONPATH=. pytest
プラグインをCloud Exchangeにデプロイする
プラグインをパッケージ化する
CEは、開発されたプラグインをzip形式とtar.gz形式で提供することを想定しています。
パッケージを圧縮するには、以下のコマンドを実行してください。
zip -r sample_plugin.zip sample_plugin
以下のコマンドを実行してtar.gzパッケージを生成します。
tar -zcvf sample_plugin.tar.gz sample_plugin
プラグインをアップロードする
このzipファイルまたはtar.gzファイルをCloud Exchangeにデプロイするには:
- Cloud Exchangeにログインしてください。
- Settings > Pluginsへ移動してください。
- Add New Pluginをクリックしてください。

- Browseをクリックしてください。

- zipファイルまたはtar.gzファイルSelect 。

- Uploadをクリックしてください。
Add a Repo
プラグインをデプロイするには、Cloud Exchangeにリポジトリを追加してください。





