Taegis SDK for Python スキーマの探索🔗
はじめに🔗
from taegis_sdk_python import GraphQLService
service = GraphQLService()
schema = service.core.get_sync_schema()
主な関心領域🔗
query_typesmutation_typessubscription_typestype_map
サポートされているGraphQLのクエリ/ミューテーション/サブスクリプションを確認するには、適切な *_types.fields アクセサを使用します。以下の例では query_types を使用しますが、mutation_types や subscription_types も同様に利用できます。
{'getAccessPoint': <GraphQLField <GraphQLObjectType 'AccessPoint'>>,
'getAccessPointTemplate': <GraphQLField <GraphQLObjectType 'AccessPointCloudFormation'>>,
'aggregatedAlertsPerEndpoint': <GraphQLField <GraphQLNonNull <GraphQLObjectType 'AggregatedAlertsPerEndpointResult'>>>,
'aggregatedLicensedEndpointDeploymentRatio': <GraphQLField <GraphQLNonNull <GraphQLObjectType 'AggregatedLicensedEndpointDeploymentRatioResult'>>>,
'aggregatedMeanTimeToAcknowledgeMetrics': <GraphQLField <GraphQLNonNull <GraphQLObjectType 'AggregatedMeanTimeToAcknowledgeResult'>>>,
'aggregatedMeanTimeToResolveMetrics': <GraphQLField <GraphQLNonNull <GraphQLObjectType 'AggregatedMeanTimeToResolveResult'>>>,
...
<truncationed for readability>
戻り値フィールド名🔗
フィールドへのアクセスは、Pythonの辞書と同じ方法(ブラケット [] または .get() を使用)で行います。
または
ここでは、alertsServiceSearch が AlertsResponse オブジェクトを返すことがわかります。
エンドポイント引数🔗
引数名の一覧を取得します。
引数の型名を取得できます。
これは SearchRequestInput オブジェクトです。
このエンドポイントは in という1つの引数を取りますが、この引数が受け入れるフィールドはまだわかりません。
{'cql_query': <graphql.type.definition.GraphQLInputField at 0x7f8ee49f9490>,
'offset': <graphql.type.definition.GraphQLInputField at 0x7f8ee49f94c0>,
'limit': <graphql.type.definition.GraphQLInputField at 0x7f8ee49f94f0>,
'search_id': <graphql.type.definition.GraphQLInputField at 0x7f8ee49f9520>}
すべてのフィールド型がGraphQLScalarTypeになるまでこの操作を繰り返します。一部の項目はリストや非null型の場合があり、これらは of_type アクセサで展開できます。
戻り値フィールド🔗
.type.fields を使って戻り値フィールドの辞書を取得できます。各フィールドに対して .type や .of_type を組み合わせて使用し、スカラー型またはenum型に到達するまで繰り返すことで、リクエスト可能な内容を特定します。
{'status': <GraphQLField <GraphQLEnumType 'RPCResponseStatus'>>,
'reason': <GraphQLField <GraphQLScalarType 'String'>>,
'alerts': <GraphQLField <GraphQLObjectType 'AlertsList'>>,
'search_id': <GraphQLField <GraphQLScalarType 'String'>>}
{'list': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLObjectType 'Alert2'>>>>,
'total_results': <GraphQLField <GraphQLScalarType 'Int'>>,
'next_offset': <GraphQLField <GraphQLScalarType 'Int'>>,
'previous_offset': <GraphQLField <GraphQLScalarType 'Int'>>,
'last_offset': <GraphQLField <GraphQLScalarType 'Int'>>,
'first_offset': <GraphQLField <GraphQLScalarType 'Int'>>,
'total_parts': <GraphQLField <GraphQLScalarType 'Int'>>,
'part': <GraphQLField <GraphQLScalarType 'Int'>>,
'group_by': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLObjectType 'AggregationResponse'>>>>}
list のようなフィールドの場合、複数の定義を展開する必要があることがわかります:GraphQLField (type) -> GraphQLList (of_type) -> GraphQLNonNull (of_type)。
schema.query_type.fields['alertsServiceSearch'].type.fields["alerts"].type.fields["list"].type.of_type.of_type.fields
{'id': <GraphQLField <GraphQLNonNull <GraphQLScalarType 'ID'>>>,
'group_key': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLScalarType 'String'>>>>,
'metadata': <GraphQLField <GraphQLObjectType 'AlertsMetadata'>>,
'visibility': <GraphQLField <GraphQLEnumType 'Visibility'>>,
'attack_technique_ids': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLScalarType 'String'>>>>,
'tenant_id': <GraphQLField <GraphQLScalarType 'String'>>,
'parent_tenant_id': <GraphQLField <GraphQLScalarType 'String'>>,
'suppressed': <GraphQLField <GraphQLScalarType 'Boolean'>>,
'suppression_rules': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLObjectType 'AlertRuleReference'>>>>,
'alerting_rules': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLObjectType 'AlertRuleReference'>>>>,
'status': <GraphQLField <GraphQLEnumType 'ResolutionStatus'>>,
'resolution_reason': <GraphQLField <GraphQLScalarType 'String'>>,
'resolution_history': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLObjectType 'ResolutionMetadata'>>>>,
'severity_history': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLObjectType 'SeverityUpdate'>>>>,
'tags': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLScalarType 'String'>>>>,
'sensor_types': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLScalarType 'String'>>>>,
'entities': <GraphQLField <GraphQLObjectType 'EntityRelationships'>>,
'key_entities': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLObjectType 'EntityMetadata'>>>>,
'event_ids': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLObjectType 'AuxiliaryEvent'>>>>,
'observation_ids': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLObjectType 'Observation'>>>>,
'investigation_ids': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLObjectType 'Investigation'>>>>,
'collection_ids': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLObjectType 'Collection'>>>>,
'enrichment_details': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLObjectType 'EnrichmentDetail'>>>>,
'third_party_details': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLObjectType 'ThirdPartyDetail'>>>>,
'reference_details': <GraphQLField <GraphQLList <GraphQLNonNull <GraphQLObjectType 'ReferenceDetail'>>>>,
'priority': <GraphQLField <GraphQLObjectType 'AlertPriority'>>,
'threat_score': <GraphQLField <GraphQLScalarType 'Float32'>>,
'events_metadata': <GraphQLField <GraphQLObjectType 'AlertEventMetadata'>>,
'alertPrioritization': <GraphQLField <GraphQLObjectType 'AlertPrioritization'>>}
任意のクエリの構築🔗
ここまでで有効なGraphQLクエリを構築できるようになりました。例として alertsServiceSearch を使用します。変数は引数の調査から取得します。トップ引数 in のフィールド cql_query を使用します。戻り値フィールドにはクエリの status とアラートIDのリストを取得します。
任意のメソッドには以下が含まれます:
execute_queryexecute_mutationexecute_subscription
service.core.execute_query(
endpoint="alertsServiceSearch",
variables={
"in": {
"cql_query": "FROM alert EARLIEST=-1d | head 10"
}
},
output="""
status
alerts {
list {
id
}
}
"""
)
{'alertsServiceSearch': {'status': 'OK',
'alerts': {'list': [{'id': 'alert://priv:event-filter:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:event-filter:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:event-filter:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:event-filter:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:event-filter:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:email:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:email:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:event-filter-ql:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:event-filter:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:event-filter:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'}]}}}
生クエリの構築🔗
ここまでで有効なGraphQLクエリを構築できるようになりました。例として alertsServiceSearch を使用します。変数は引数の調査から取得します。トップ引数 in のフィールド cql_query を使用します。戻り値フィールドにはクエリの status とアラートIDのリストを取得します。GraphQLクエリ文字列の詳細については GraphQL Learn を参照してください。
execute() はクエリとミューテーションで動作します。subscribe() はサブスクリプションで使用します。
service.core.execute(
query_string="""
query MyAlertsServiceSearch($in: SearchRequestInput) {
alertsServiceSearch(in: $in) {
status
alerts {
list {
id
}
}
}
}
"""
variables={
"in": {
"cql_query": "FROM alert EARLIEST=-1d | head 10"
}
},
)
{'alertsServiceSearch': {'status': 'OK',
'alerts': {'list': [{'id': 'alert://priv:event-filter:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:event-filter:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:event-filter:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:event-filter:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:event-filter:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:email:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:email:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:event-filter-ql:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:event-filter:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'},
{'id': 'alert://priv:event-filter:00000:0000000000000:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'}]}}}
スキーマファイル🔗
スキーマオブジェクトを schema.graphql 形式にパースできます。これにより GraphQLのドキュメント に従ったGraphQLスキーマ定義ドキュメントが生成されます。
from taegis_sdk_python import GraphQLService
from graphql.utilities import print_schema
service = GraphQLService()
schema = service.core.get_sync_schema()
print(print_schema(schema))
input AbsoluteTimeRedQLQueryInput {
query: String!
referenceTime: Time!
currentTime: Time!
}
type AccessPoint {
tenantID: String!
arn: String!
alias: String!
principal: [String!]!
}
...
<truncated for readability>
特殊なケース🔗
すべてのAPIが同じ構成の背後にあるわけではありません。tenants や events などのAPIは特別な構成がされている場合があります。探索や実行には core ではなく、これらのサービスを使用するのが最適です。特殊な構成のケースは、各サービスの __init__ クラスメソッド内の __init__.py ファイルで確認できます。構成はアップデートごとに変更される可能性があります。堅牢なコードのためには、適切なサービスを使用してクエリ、ミューテーション、サブスクリプションを実行してください。