本页面介绍了如何使用 Security Command Center API 通知功能,包括以下示例:
- 创建
NotificationConfig
- 获取
NotificationConfig
- 更新
NotificationConfig
- 删除
NotificationConfig
- 列出
NotificationConfig
- 接收 Pub/Sub 通知
准备工作
要使用此页面上的示例,您需要完成设置发现结果通知指南。
要执行以下示例,您需要具有适当权限的身份和访问权限管理 (IAM) 角色:
- 获取和列出
NotificationConfig
:安全中心通知查看者或编辑者 - 更新和删除
NotificationConfig
:安全中心通知编辑者
详细了解 Security Command Center 角色。
创建 NotificationConfig
要创建 NotificationConfig
,您必须具有:
- 您要向其发送通知的现有 Pub/Sub 主题。
- 您的服务帐号或您用于运行
gcloud
工具命令的帐号所需的 IAM 角色。
如需了解详情,请参阅设置发现结果通知指南中的设置 Pub/Sub 主题步骤。
在创建 NotificationConfig
之前,请考虑以下事项:
- 每个组织只能有一定数量的
NotificationConfig
文件。如需了解详情,请参阅配额和限制。 - 您必须拥有组织管理员 IAM 角色,以便向通知服务帐号或
gcloud
工具帐号授予适当的角色。
NotificationConfig
包含一个 filter
字段,用于限制对有用事件的通知。此字段接受 Security Command Center API findings.list
方法中提供的所有过滤条件。
要使用 gcloud
命令行工具向帐号授予安全中心通知配置编辑者 IAM 角色,请执行以下操作:
设置环境变量:
设置您的组织名称:
export ORGANIZATION_ID=organization-id
设置您在设置发现结果通知时创建的服务帐号的电子邮件,或设置用于运行
gcloud
工具命令的帐号:设置用于运行
gcloud
工具命令的帐号的电子邮件:export EMAIL=your-username@email.com
或设置服务帐号的电子邮件:
export EMAIL=service-account-name@$CONSUMER_PROJECT.iam.gserviceaccount.com
向该服务帐号或用于
gcloud
工具命令的帐号授予必要的角色:向运行
gcloud
工具命令的帐号授予角色:gcloud organizations add-iam-policy-binding \ $ORGANIZATION_ID \ --member="user:$EMAIL" \ --role='roles/securitycenter.notificationConfigEditor'
或向服务帐号授予角色:
gcloud organizations add-iam-policy-binding \ $ORGANIZATION_ID \ --member="serviceAccount:$EMAIL" \ --role='roles/securitycenter.notificationConfigEditor'
向服务帐号或 gcloud
工具帐号授予权限之后,使用您选择的语言或平台创建 NotificationConfig
:
gcloud
# The numeric ID of the organization
ORGANIZATION_ID=organization-id
# The topic to which the notifications are published
PUBSUB_TOPIC="projects/project-id/topics/topic-id"
# The description for the NotificationConfig
DESCRIPTION="Notifies for active findings"
# Filters for active findings
FILTER="state=\"ACTIVE\""
gcloud scc notifications create notification-name \
--organization "$ORGANIZATION_ID" \
--description "$DESCRIPTION" \
--pubsub-topic $PUBSUB_TOPIC \
--filter "$FILTER"
Python
from google.cloud import securitycenter as securitycenter
client = securitycenter.SecurityCenterClient()
# TODO: organization_id = "your-org-id"
# TODO: notification_config_id = "your-config-id"
# TODO: pubsub_topic = "projects/{your-project-id}/topics/{your-topic-ic}"
# Ensure this ServiceAccount has the "pubsub.topics.setIamPolicy" permission on the new topic.
org_name = "organizations/{org_id}".format(org_id=organization_id)
created_notification_config = client.create_notification_config(
request={
"parent": org_name,
"config_id": notification_config_id,
"notification_config": {
"description": "Notification for active findings",
"pubsub_topic": pubsub_topic,
"streaming_config": {"filter": 'state = "ACTIVE"'},
},
}
)
print(created_notification_config)
Java
import com.google.cloud.securitycenter.v1.CreateNotificationConfigRequest;
import com.google.cloud.securitycenter.v1.NotificationConfig;
import com.google.cloud.securitycenter.v1.NotificationConfig.StreamingConfig;
import com.google.cloud.securitycenter.v1.SecurityCenterClient;
import java.io.IOException;
public static NotificationConfig createNotificationConfig(
String organizationId, String notificationConfigId, String projectId, String topicName)
throws IOException {
// String organizationId = "{your-org-id}";
// String notificationConfigId = {"your-unique-id"};
// String projectId = "{your-project}"";
// String topicName = "{your-topic}";
String orgName = String.format("organizations/%s", organizationId);
// Ensure this ServiceAccount has the "pubsub.topics.setIamPolicy" permission on the topic.
String pubsubTopic = String.format("projects/%s/topics/%s", projectId, topicName);
try (SecurityCenterClient client = SecurityCenterClient.create()) {
CreateNotificationConfigRequest request =
CreateNotificationConfigRequest.newBuilder()
.setParent(orgName)
.setConfigId(notificationConfigId)
.setNotificationConfig(
NotificationConfig.newBuilder()
.setDescription("Java notification config")
.setPubsubTopic(pubsubTopic)
.setStreamingConfig(
StreamingConfig.newBuilder().setFilter("state = \"ACTIVE\"").build())
.build())
.build();
NotificationConfig response = client.createNotificationConfig(request);
System.out.println(String.format("Notification config was created: %s", response));
return response;
}
}
Go
import (
"context"
"fmt"
"io"
securitycenter "cloud.google.com/go/securitycenter/apiv1"
securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1"
)
func createNotificationConfig(w io.Writer, orgID string, pubsubTopic string, notificationConfigID string) error {
// orgID := "your-org-id"
// pubsubTopic := "projects/{your-project}/topics/{your-topic}"
// notificationConfigID := "your-config-id"
ctx := context.Background()
client, err := securitycenter.NewClient(ctx)
if err != nil {
return fmt.Errorf("securitycenter.NewClient: %v", err)
}
defer client.Close()
req := &securitycenterpb.CreateNotificationConfigRequest{
Parent: fmt.Sprintf("organizations/%s", orgID),
ConfigId: notificationConfigID,
NotificationConfig: &securitycenterpb.NotificationConfig{
Description: "Go sample config",
PubsubTopic: pubsubTopic,
NotifyConfig: &securitycenterpb.NotificationConfig_StreamingConfig_{
StreamingConfig: &securitycenterpb.NotificationConfig_StreamingConfig{
Filter: `state = "ACTIVE"`,
},
},
},
}
notificationConfig, err := client.CreateNotificationConfig(ctx, req)
if err != nil {
return fmt.Errorf("Failed to create notification config: %v", err)
}
fmt.Fprintln(w, "New NotificationConfig created: ", notificationConfig)
return nil
}
Node.js
// npm install @google-cloud/security-center/
const {SecurityCenterClient} = require('@google-cloud/security-center');
const client = new SecurityCenterClient();
// organizationId = "your-org-id";
// configId = "your-config-name";
// pubsubTopic = "projects/{your-project}/topics/{your-topic}";
// Ensure this Service Account has the "pubsub.topics.setIamPolicy" permission on this topic.
const orgName = client.organizationPath(organizationId);
async function createNotificationConfig() {
const [response] = await client.createNotificationConfig({
parent: orgName,
configId: configId,
notificationConfig: {
description: 'Sample config for node.js',
pubsubTopic: pubsubTopic,
streamingConfig: {filter: 'state = "ACTIVE"'},
},
});
console.log('Notification config creation succeeded: ', response);
}
createNotificationConfig();
PHP
use Google\Cloud\SecurityCenter\V1\SecurityCenterClient;
use Google\Cloud\SecurityCenter\V1\NotificationConfig;
use Google\Cloud\SecurityCenter\V1\NotificationConfig\StreamingConfig;
/** Uncomment and populate these variables in your code */
// $organizationId = "{your-org-id}";
// $notificationConfigId = {"your-unique-id"};
// $projectId = "{your-project}"";
// $topicName = "{your-topic}";
$securityCenterClient = new SecurityCenterClient();
$organizationName = $securityCenterClient::organizationName($organizationId);
$pubsubTopic = $securityCenterClient::topicName($projectId, $topicName);
$streamingConfig = (new StreamingConfig())->setFilter("state = \"ACTIVE\"");
$notificationConfig = (new NotificationConfig())
->setDescription('A sample notification config')
->setPubsubTopic($pubsubTopic)
->setStreamingConfig($streamingConfig);
$response = $securityCenterClient->createNotificationConfig(
$organizationName,
$notificationConfigId,
$notificationConfig
);
printf('Notification config was created: %s' . PHP_EOL, $response->getName());
Ruby
require "google/cloud/security_center"
# Your organization id. e.g. for "organizations/123", this would be "123".
# org_id = "YOUR_ORGANZATION_ID"
# Your notification config id. e.g. for
# "organizations/123/notificationConfigs/my-config" this would be "my-config".
# config_id = "YOUR_CONFIG_ID"
# The PubSub topic where notifications will be published.
# pubsub_topic = "YOUR_TOPIC"
client = Google::Cloud::SecurityCenter.security_center
org_path = client.organization_path organization: org_id
notification_config = {
description: "Sample config for Ruby",
pubsub_topic: pubsub_topic,
streaming_config: { filter: 'state = "ACTIVE"' }
}
response = client.create_notification_config(
parent: org_path,
config_id: config_id,
notification_config: notification_config
)
puts "Created notification config #{config_id}: #{response}."
C#
using Google.Api.Gax.ResourceNames;
using Google.Cloud.SecurityCenter.V1;
using System;
///<summary> Create NotificationConfig Snippet. </summary>
public class CreateNotificationConfigSnippets
{
public static NotificationConfig CreateNotificationConfig(
string organizationId, string notificationConfigId, string projectId, string topicName)
{
OrganizationName orgName = new OrganizationName(organizationId);
TopicName pubsubTopic = new TopicName(projectId, topicName);
SecurityCenterClient client = SecurityCenterClient.Create();
CreateNotificationConfigRequest request = new CreateNotificationConfigRequest
{
ParentAsOrganizationName = orgName,
ConfigId = notificationConfigId,
NotificationConfig = new NotificationConfig
{
Description = ".Net notification config",
PubsubTopicAsTopicName = pubsubTopic,
StreamingConfig = new NotificationConfig.Types.StreamingConfig { Filter = "state = \"ACTIVE\"" }
}
};
NotificationConfig response = client.CreateNotificationConfig(request);
Console.WriteLine($"Notification config was created: {response}");
return response;
}
}
通知现已发布到您指定的 Pub/Sub 主题。要发布通知,Security Command Center 会使用 service-org-organization-id@gcp-sa-scc-notification.iam.gserviceaccount.com
形式的组织级层服务帐号,角色为 securitycenter.notificationServiceAgent
。需要组织级层的服务帐号角色才能接收通知。
获取 NotificationConfig
如需获取 NotificationConfig
,您必须具有包含 securitycenter.notification.get
权限的 IAM 角色。
gcloud
# The numeric ID of the organization and the name of the notification that you want to get
NOTIFICATION="organizations/organization-id/notificationConfigs/notification-name"
gcloud scc notifications describe $NOTIFICATION
Python
from google.cloud import securitycenter as securitycenter
client = securitycenter.SecurityCenterClient()
# TODO: organization_id = "your-org-id"
# TODO: notification_config_id = "your-config-id"
notification_config_name = "organizations/{org_id}/notificationConfigs/{config_id}".format(
org_id=organization_id, config_id=notification_config_id
)
notification_config = client.get_notification_config(
request={"name": notification_config_name}
)
print("Got notification config: {}".format(notification_config))
Java
import com.google.cloud.securitycenter.v1.NotificationConfig;
import com.google.cloud.securitycenter.v1.NotificationConfigName;
import com.google.cloud.securitycenter.v1.SecurityCenterClient;
import java.io.IOException;
public static NotificationConfig getNotificationConfig(
String organizationId, String notificationConfigId) throws IOException {
// String organizationId = "{your-org-id}";
// String notificationConfigId = "{config-id}";
try (SecurityCenterClient client = SecurityCenterClient.create()) {
NotificationConfig response =
client.getNotificationConfig(
NotificationConfigName.newBuilder()
.setOrganization(organizationId)
.setNotificationConfig(notificationConfigId)
.build());
System.out.println(String.format("Notification config: %s", response));
return response;
}
}
Go
import (
"context"
"fmt"
"io"
securitycenter "cloud.google.com/go/securitycenter/apiv1"
securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1"
)
func getNotificationConfig(w io.Writer, orgID string, notificationConfigID string) error {
// orgID := "your-org-id"
// notificationConfigID := "your-config-id"
ctx := context.Background()
client, err := securitycenter.NewClient(ctx)
if err != nil {
return fmt.Errorf("securitycenter.NewClient: %v", err)
}
defer client.Close()
req := &securitycenterpb.GetNotificationConfigRequest{
Name: fmt.Sprintf("organizations/%s/notificationConfigs/%s", orgID, notificationConfigID),
}
notificationConfig, err := client.GetNotificationConfig(ctx, req)
if err != nil {
return fmt.Errorf("Failed to retrieve notification config: %v", err)
}
fmt.Fprintln(w, "Received config: ", notificationConfig)
return nil
}
Node.js
// npm install @google-cloud/security-center/
const {SecurityCenterClient} = require('@google-cloud/security-center');
const client = new SecurityCenterClient();
// organizationId = "your-org-id";
// configId = "your-config-id";
const formattedConfigName = client.notificationConfigPath(
organizationId,
configId
);
async function getNotificationConfg() {
const [response] = await client.getNotificationConfig({
name: formattedConfigName,
});
console.log('Notification config: ', response);
}
getNotificationConfg();
PHP
use Google\Cloud\SecurityCenter\V1\SecurityCenterClient;
/** Uncomment and populate these variables in your code */
// $organizationId = '{your-org-id}';
// $notificationConfigId = {'your-unique-id'};
$securityCenterClient = new SecurityCenterClient();
$notificationConfigName = $securityCenterClient::notificationConfigName(
$organizationId,
$notificationConfigId
);
$response = $securityCenterClient->getNotificationConfig($notificationConfigName);
printf('Notification config was retrieved: %s' . PHP_EOL, $response->getName());
Ruby
require "google/cloud/security_center"
# Your organization id. e.g. for "organizations/123", this would be "123".
# org_id = "YOUR_ORGANZATION_ID"
# Your notification config id. e.g. for
# "organizations/123/notificationConfigs/my-config" this would be "my-config".
# config_id = "YOUR_CONFIG_ID"
client = Google::Cloud::SecurityCenter.security_center
config_path = client.notification_config_path organization: org_id,
notification_config: config_id
response = client.get_notification_config name: config_path
puts "Notification config fetched: #{response}"
C#
using Google.Cloud.SecurityCenter.V1;
using System;
/// <summary>Snippet for GetNotificationConfig</summary>
public class GetNotificationConfigSnippets
{
public static NotificationConfig GetNotificationConfig(string organizationId, string configId)
{
SecurityCenterClient client = SecurityCenterClient.Create();
NotificationConfigName notificationConfigName = new NotificationConfigName(organizationId, configId);
NotificationConfig response = client.GetNotificationConfig(notificationConfigName);
Console.WriteLine($"Notification config: {response}");
return response;
}
}
更新 NotificationConfig
要更新 NotificationConfig
,您必须具有包含 securitycenter.notification.update
权限的 IAM 角色。
使用字段掩码更新时,只有指定的字段才会更新。如果您不使用字段掩码,则 NotificationConfig
中的所有可变字段都将替换为新值。您可以使用字段掩码来更新 Pub/Sub 主题和说明。
要完成此示例,您必须订阅新主题,并且您的通知服务帐号必须具有该主题的 pubsub.topics.setIamPolicy
权限。要授予适当的角色,请执行以下操作:
设置环境变量:
设置主题 ID:
export TOPIC_ID=topic-id
为启用了通知 API 的项目设置项目 ID:
export CONSUMER_PROJECT=project-id
设置您在先前步骤中创建的服务帐号的电子邮件:
export SERVICE_ACCOUNT_EMAIL=service-account-name@$CONSUMER_PROJECT.iam.gserviceaccount.com
向通知服务帐号授予具有
pubsub.topics.setIamPolicy
权限的角色:gcloud pubsub topics add-iam-policy-binding \ projects/$CONSUMER_PROJECT/topics/$TOPIC_ID \ --member="serviceAccount:$SERVICE_ACCOUNT_EMAIL" \ --role='roles/pubsub.admin'
授予服务帐号角色后,使用您选择的语言更新 NotificationConfig
说明、Pub/Sub 主题和过滤条件:
gcloud
# The topic to which the notifications are published
PUBSUB_TOPIC="projects/project-id/topics/topic-id"
# The description for the NotificationConfig
DESCRIPTION="description"
# The numeric ID of the organization and the name of the notification that you want to update
NOTIFICATION="organizations/organization-id/notificationConfigs/notification-name"
gcloud scc notifications update $NOTIFICATION
--description "$DESCRIPTION" \
--pubsub-topic $PUBSUB_TOPIC \
--filter $FILTER
Python
from google.cloud import securitycenter as securitycenter
from google.protobuf import field_mask_pb2
client = securitycenter.SecurityCenterClient()
# TODO organization_id = "your-org-id"
# TODO notification_config_id = "config-id-to-update"
# TODO pubsub_topic = "projects/{new-project}/topics/{new-topic}"
# If updating a pubsub_topic, ensure this ServiceAccount has the
# "pubsub.topics.setIamPolicy" permission on the new topic.
notification_config_name = "organizations/{org_id}/notificationConfigs/{config_id}".format(
org_id=organization_id, config_id=notification_config_id
)
updated_description = "New updated description"
updated_filter = 'state = "INACTIVE"'
# Only description and pubsub_topic can be updated.
field_mask = field_mask_pb2.FieldMask(
paths=["description", "pubsub_topic", "streaming_config.filter"]
)
updated_notification_config = client.update_notification_config(
request={
"notification_config": {
"name": notification_config_name,
"description": updated_description,
"pubsub_topic": pubsub_topic,
"streaming_config": {"filter": updated_filter},
},
"update_mask": field_mask,
}
)
print(updated_notification_config)
Java
import com.google.cloud.securitycenter.v1.NotificationConfig;
import com.google.cloud.securitycenter.v1.NotificationConfig.StreamingConfig;
import com.google.cloud.securitycenter.v1.SecurityCenterClient;
import com.google.protobuf.FieldMask;
import java.io.IOException;
public static NotificationConfig updateNotificationConfig(
String organizationId, String notificationConfigId, String projectId, String topicName)
throws IOException {
// String organizationId = "{your-org-id}";
// String notificationConfigId = "{your-config-id}";
// String projectId = "{your-project}";
// String topicName = "{your-topic}";
String notificationConfigName =
String.format(
"organizations/%s/notificationConfigs/%s", organizationId, notificationConfigId);
// Ensure this ServiceAccount has the "pubsub.topics.setIamPolicy" permission on the topic.
String pubsubTopic = String.format("projects/%s/topics/%s", projectId, topicName);
NotificationConfig configToUpdate =
NotificationConfig.newBuilder()
.setName(notificationConfigName)
.setDescription("updated description")
.setPubsubTopic(pubsubTopic)
.setStreamingConfig(StreamingConfig.newBuilder().setFilter("state = \"ACTIVE\""))
.build();
FieldMask fieldMask =
FieldMask.newBuilder()
.addPaths("description")
.addPaths("pubsub_topic")
.addPaths("streaming_config.filter").build();
try (SecurityCenterClient client = SecurityCenterClient.create()) {
NotificationConfig updatedConfig = client.updateNotificationConfig(configToUpdate, fieldMask);
System.out.println(String.format("Notification config: %s", updatedConfig));
return updatedConfig;
}
}
Go
import (
"context"
"fmt"
"io"
securitycenter "cloud.google.com/go/securitycenter/apiv1"
securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1"
"google.golang.org/genproto/protobuf/field_mask"
)
func updateNotificationConfig(w io.Writer, orgID string, notificationConfigID string, updatedPubsubTopic string) error {
// orgID := "your-org-id"
// notificationConfigID := "your-config-id"
// updatedPubsubTopic := "projects/{new-project}/topics/{new-topic}"
ctx := context.Background()
client, err := securitycenter.NewClient(ctx)
if err != nil {
return fmt.Errorf("securitycenter.NewClient: %v", err)
}
defer client.Close()
updatedDescription := "Updated sample config"
updatedFilter := `state = "INACTIVE"`
req := &securitycenterpb.UpdateNotificationConfigRequest{
NotificationConfig: &securitycenterpb.NotificationConfig{
Name: fmt.Sprintf("organizations/%s/notificationConfigs/%s", orgID, notificationConfigID),
Description: updatedDescription,
PubsubTopic: updatedPubsubTopic,
NotifyConfig: &securitycenterpb.NotificationConfig_StreamingConfig_{
StreamingConfig: &securitycenterpb.NotificationConfig_StreamingConfig{
Filter: updatedFilter,
},
},
},
UpdateMask: &field_mask.FieldMask{
Paths: []string{"description", "pubsub_topic", "streaming_config.filter"},
},
}
notificationConfig, err := client.UpdateNotificationConfig(ctx, req)
if err != nil {
return fmt.Errorf("Failed to update notification config: %v", err)
}
fmt.Fprintln(w, "Updated NotificationConfig: ", notificationConfig)
return nil
}
Node.js
// npm install @google-cloud/security-center/
const {SecurityCenterClient} = require('@google-cloud/security-center');
const client = new SecurityCenterClient();
// organizationId = "your-org-id";
// configId = "your-config-id";
const formattedConfigName = client.notificationConfigPath(
organizationId,
configId
);
// pubsubTopic = "projects/{your-project}/topics/{your-topic}";
// Ensure this Service Account has the "pubsub.topics.setIamPolicy" permission on this topic.
async function updateNotificationConfig() {
const [response] = await client.updateNotificationConfig({
updateMask: {
paths: ['description', 'pubsub_topic', 'streaming_config.filter'],
},
notificationConfig: {
name: formattedConfigName,
description: 'Updated config description',
pubsubTopic: pubsubTopic,
streamingConfig: {filter: 'state = "INACTIVE"'},
},
});
console.log('notification config update succeeded: ', response);
}
updateNotificationConfig();
PHP
use Google\Cloud\SecurityCenter\V1\SecurityCenterClient;
use Google\Cloud\SecurityCenter\V1\NotificationConfig;
use Google\Cloud\SecurityCenter\V1\NotificationConfig\StreamingConfig;
use Google\Protobuf\FieldMask;
/** Uncomment and populate these variables in your code */
// $organizationId = '{your-org-id}';
// $notificationConfigId = {'your-unique-id'};
// $projectId = '{your-project}';
// $topicName = '{your-topic}';
$securityCenterClient = new SecurityCenterClient();
// Ensure this ServiceAccount has the 'pubsub.topics.setIamPolicy' permission on the topic.
// https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.topics/setIamPolicy
$pubsubTopic = $securityCenterClient::topicName($projectId, $topicName);
$notificationConfigName = $securityCenterClient::notificationConfigName($organizationId, $notificationConfigId);
$streamingConfig = (new StreamingConfig())->setFilter("state = \"ACTIVE\"");
$fieldMask = (new FieldMask())->setPaths(['description', 'pubsub_topic', 'streaming_config.filter']);
$notificationConfig = (new NotificationConfig())
->setName($notificationConfigName)
->setDescription('Updated description.')
->setPubsubTopic($pubsubTopic)
->setStreamingConfig($streamingConfig);
$response = $securityCenterClient->updateNotificationConfig($notificationConfig, [$fieldMask]);
printf('Notification config was updated: %s' . PHP_EOL, $response->getName());
Ruby
require "google/cloud/security_center"
# Your organization id. e.g. for "organizations/123", this would be "123".
# org_id = "YOUR_ORGANZATION_ID"
# Your notification config id. e.g. for
# "organizations/123/notificationConfigs/my-config" this would be "my-config".
# config_id = "YOUR_CONFIG_ID"
# Updated description of the notification config.
# description = "YOUR_DESCRIPTION"
# The PubSub topic where notifications will be published.
# pubsub_topic = "YOUR_TOPIC"
# Updated filter string for Notification config.
# filter = "UPDATED_FILTER"
client = Google::Cloud::SecurityCenter.security_center
config_path = client.notification_config_path organization: org_id,
notification_config: config_id
notification_config = { name: config_path }
notification_config[:description] = description unless description.nil?
notification_config[:pubsub_topic] = pubsub_topic unless pubsub_topic.nil?
notification_config[:streaming_config][:filter] = filter unless filter.nil?
paths = []
paths.push "description" unless description.nil?
paths.push "pubsub_topic" unless pubsub_topic.nil?
paths.push "streaming_config.filter" unless filter.nil?
update_mask = { paths: paths }
response = client.update_notification_config(
notification_config: notification_config,
update_mask: update_mask
)
puts response
C#
using Google.Cloud.SecurityCenter.V1;
using static Google.Cloud.SecurityCenter.V1.NotificationConfig.Types;
using Google.Protobuf.WellKnownTypes;
using System;
/// <summary>Snippet for UpdateNotificationConfig</summary>
public class UpdateNotificationConfigSnippets
{
public static NotificationConfig UpdateNotificationConfig(
string organizationId, string notificationConfigId, string projectId, string topicName)
{
NotificationConfigName notificationConfigName = new NotificationConfigName(organizationId, notificationConfigId);
TopicName pubsubTopic = new TopicName(projectId, topicName);
NotificationConfig configToUpdate = new NotificationConfig
{
NotificationConfigName = notificationConfigName,
Description = "updated description",
PubsubTopicAsTopicName = pubsubTopic,
StreamingConfig = new StreamingConfig { Filter = "state = \"INACTIVE\"" }
};
FieldMask fieldMask = new FieldMask { Paths = { "description", "pubsub_topic", "streaming_config.filter" } };
SecurityCenterClient client = SecurityCenterClient.Create();
NotificationConfig updatedConfig = client.UpdateNotificationConfig(configToUpdate, fieldMask);
Console.WriteLine($"Notification config updated: {updatedConfig}");
return updatedConfig;
}
}
删除 NotificationConfig
要删除 NotificationConfig
,您必须具有包含 securitycenter.notification.delete
权限的 IAM 角色。
删除 NotificationConfig
时,securitycenter.notificationServiceAgent
角色将保留在 Pub/Sub 主题上。如果您在任何其他 NotificationConfig
中使用 Pub/Sub 主题,请从主题中移除该角色。如需了解详情,请参阅访问控制。
使用您选择的语言删除 NotificationConfig
:
gcloud
# The numeric ID of the organization and the name of the notification that you want to delete
NOTIFICATION="organizations/organization-id/notificationConfigs/notification-name"
gcloud scc notifications delete $NOTIFICATION
Python
from google.cloud import securitycenter as securitycenter
client = securitycenter.SecurityCenterClient()
# TODO: organization_id = "your-org-id"
# TODO: notification_config_id = "your-config-id"
notification_config_name = "organizations/{org_id}/notificationConfigs/{config_id}".format(
org_id=organization_id, config_id=notification_config_id
)
client.delete_notification_config(request={"name": notification_config_name})
print("Deleted notification config: {}".format(notification_config_name))
Java
import com.google.cloud.securitycenter.v1.NotificationConfigName;
import com.google.cloud.securitycenter.v1.SecurityCenterClient;
import java.io.IOException;
public static boolean deleteNotificationConfig(String organizationId, String notificationConfigId)
throws IOException {
// String organizationId = "{your-org-id}";
// String notificationConfigId = "{config-id}";
NotificationConfigName notificationConfigName =
NotificationConfigName.newBuilder()
.setOrganization(organizationId)
.setNotificationConfig(notificationConfigId)
.build();
try (SecurityCenterClient client = SecurityCenterClient.create()) {
client.deleteNotificationConfig(notificationConfigName);
System.out.println(String.format("Deleted Notification config: %s", notificationConfigName));
}
return true;
}
Go
import (
"context"
"fmt"
"io"
securitycenter "cloud.google.com/go/securitycenter/apiv1"
securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1"
)
func deleteNotificationConfig(w io.Writer, orgID string, notificationConfigID string) error {
// orgID := "your-org-id"
// notificationConfigID := "config-to-delete"
ctx := context.Background()
client, err := securitycenter.NewClient(ctx)
if err != nil {
return fmt.Errorf("securitycenter.NewClient: %v", err)
}
defer client.Close()
name := fmt.Sprintf("organizations/%s/notificationConfigs/%s", orgID, notificationConfigID)
req := &securitycenterpb.DeleteNotificationConfigRequest{
Name: name,
}
if err = client.DeleteNotificationConfig(ctx, req); err != nil {
return fmt.Errorf("Failed to retrieve notification config: %v", err)
}
fmt.Fprintln(w, "Deleted config: ", name)
return nil
}
Node.js
// npm install @google-cloud/security-center/
const {SecurityCenterClient} = require('@google-cloud/security-center');
const client = new SecurityCenterClient();
// organizationId = "your-org-id";
// configId = "your-config-id";
const formattedConfigName = client.notificationConfigPath(
organizationId,
configId
);
async function deleteNotificationConfg() {
await client.deleteNotificationConfig({name: formattedConfigName});
console.log('Notification config deleted: ', formattedConfigName);
}
deleteNotificationConfg();
PHP
use Google\Cloud\SecurityCenter\V1\SecurityCenterClient;
/** Uncomment and populate these variables in your code */
// $organizationId = '{your-org-id}';
// $notificationConfigId = {'your-unique-id'};
$securityCenterClient = new SecurityCenterClient();
$notificationConfigName = $securityCenterClient::notificationConfigName(
$organizationId,
$notificationConfigId
);
$response = $securityCenterClient->deleteNotificationConfig($notificationConfigName);
print('Notification config was deleted' . PHP_EOL);
Ruby
require "google/cloud/security_center"
# Your organization id. e.g. for "organizations/123", this would be "123".
# org_id = "YOUR_ORGANZATION_ID"
# Your notification config id. e.g. for
# "organizations/123/notificationConfigs/my-config" this would be "my-config".
# config_id = "YOUR_CONFIG_ID"
client = Google::Cloud::SecurityCenter.security_center
config_path = client.notification_config_path organization: org_id,
notification_config: config_id
response = client.delete_notification_config name: config_path
puts "Deleted notification config #{config_id} with response: #{response}"
C#
using Google.Cloud.SecurityCenter.V1;
using System;
/// <summary>Snippet for DeleteNotificationConfig</summary>
public class DeleteNotificationConfigSnippets
{
public static bool DeleteNotificationConfig(string organizationId, string notificationConfigId)
{
NotificationConfigName notificationConfigName = new NotificationConfigName(organizationId, notificationConfigId);
SecurityCenterClient client = SecurityCenterClient.Create();
client.DeleteNotificationConfig(notificationConfigName);
Console.WriteLine($"Deleted Notification config: {notificationConfigName}");
return true;
}
}
列出 NotificationConfig
要列出 NotificationConfigs
,您必须拥有一个包含 securitycenter.notification.list
权限的 IAM 角色。
所有 Security Command Center API 列表均已分页。每个响应都会返回一个结果页面和一个返回下一页的令牌。默认 pageSize
为 10。您可以将页面大小配置为最小值 1,最大值 1000。
使用您选择的语言列出 NotificationConfigs
:
gcloud
# The numeric ID of the organization
ORGANIZATION=organization-id
gcloud scc notifications list $ORGANIZATION
Python
from google.cloud import securitycenter as securitycenter
client = securitycenter.SecurityCenterClient()
# TODO: organization_id = "your-org-id"
org_name = "organizations/{org_id}".format(org_id=organization_id)
notification_configs_iterator = client.list_notification_configs(
request={"parent": org_name}
)
for i, config in enumerate(notification_configs_iterator):
print("{}: notification_config: {}".format(i, config))
Java
import com.google.cloud.securitycenter.v1.NotificationConfig;
import com.google.cloud.securitycenter.v1.OrganizationName;
import com.google.cloud.securitycenter.v1.SecurityCenterClient;
import com.google.cloud.securitycenter.v1.SecurityCenterClient.ListNotificationConfigsPagedResponse;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
public static ImmutableList<NotificationConfig> listNotificationConfigs(String organizationId)
throws IOException {
// String organizationId = "{your-org-id}";
OrganizationName orgName =
OrganizationName.newBuilder().setOrganization(organizationId).build();
try (SecurityCenterClient client = SecurityCenterClient.create()) {
ListNotificationConfigsPagedResponse response = client.listNotificationConfigs(orgName);
ImmutableList<NotificationConfig> notificationConfigs =
ImmutableList.copyOf(response.iterateAll());
System.out.println(
String.format("List notifications response: %s", response.getPage().getValues()));
return notificationConfigs;
}
}
Go
import (
"context"
"fmt"
"io"
securitycenter "cloud.google.com/go/securitycenter/apiv1"
"google.golang.org/api/iterator"
securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1"
)
func listNotificationConfigs(w io.Writer, orgID string) error {
// orgId := "your-org-id"
ctx := context.Background()
client, err := securitycenter.NewClient(ctx)
if err != nil {
return fmt.Errorf("securitycenter.NewClient: %v", err)
}
defer client.Close()
req := &securitycenterpb.ListNotificationConfigsRequest{
Parent: fmt.Sprintf("organizations/%s", orgID),
}
it := client.ListNotificationConfigs(ctx, req)
for {
result, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
return fmt.Errorf("it.Next: %v", err)
}
fmt.Fprintln(w, "NotificationConfig: ", result)
}
return nil
}
Node.js
// npm install @google-cloud/security-center/
const {SecurityCenterClient} = require('@google-cloud/security-center');
const client = new SecurityCenterClient();
// organizationId = "your-org-id";
const orgName = client.organizationPath(organizationId);
async function listNotificationConfigs() {
const [resources] = await client.listNotificationConfigs({parent: orgName});
console.log('Received Notification configs: ');
for (const resource of resources) {
console.log(resource);
}
}
listNotificationConfigs();
PHP
use Google\Cloud\SecurityCenter\V1\SecurityCenterClient;
/** Uncomment and populate these variables in your code */
// $organizationId = '{your-org-id}';
$securityCenterClient = new SecurityCenterClient();
$organizationName = $securityCenterClient::organizationName($organizationId);
foreach ($securityCenterClient->listNotificationConfigs($organizationName) as $element) {
printf('Found notification config %s' . PHP_EOL, $element->getName());
}
print('Notification configs were listed' . PHP_EOL);
Ruby
require "google/cloud/security_center"
# Your organization id. e.g. for "organizations/123", this would be "123".
# org_id = "YOUR_ORGANZATION_ID"
client = Google::Cloud::SecurityCenter.security_center
org_path = client.organization_path organization: org_id
client.list_notification_configs(parent: org_path).each_page do |page|
page.each do |element|
puts element
end
end
C#
using Google.Api.Gax.ResourceNames;
using Google.Api.Gax;
using Google.Cloud.SecurityCenter.V1;
using System;
/// <summary>Snippet for ListNotificationConfig</summary>
public class ListNotificationConfigSnippets
{
public static PagedEnumerable<ListNotificationConfigsResponse, NotificationConfig> ListNotificationConfigs(string organizationId)
{
OrganizationName orgName = new OrganizationName(organizationId);
SecurityCenterClient client = SecurityCenterClient.Create();
PagedEnumerable<ListNotificationConfigsResponse, NotificationConfig> notificationConfigs = client.ListNotificationConfigs(orgName);
// Print Notification Configuration names.
foreach (var config in notificationConfigs)
{
Console.WriteLine(config.NotificationConfigName);
}
return notificationConfigs;
}
}
接收 Pub/Sub 通知
本部分提供了一个示例通知消息和示例,展示如何将 Pub/Sub 消息转换为包含发现结果的 NotificationMessage
。
通知以 JSON
格式发布到 Pub/Sub。以下是通知消息的示例:
{
"notificationConfigName": "organizations/organization-id/notificationConfigs/config-id",
"finding": {
"name": "organizations/organization-id/sources/source-id/findings/finding-id",
"parent": "organizations/organization-id/sources/source-id",
"state": "ACTIVE",
"category": "TEST-CATEGORY",
"securityMarks": {
"name": "organizations/organization-id/sources/source-id/findings/finding-id/securityMarks"
},
"eventTime": "2019-07-26T07:32:37Z",
"createTime": "2019-07-29T18:45:27.243Z"
}
}
使用您选择的语言将 Pub/Sub 消息转换为 NotificationMessage
:
gcloud
gcloud
工具不支持将 Pub/Sub 消息转换为 NotificationMessage
。您可以使用 gcloud
工具获取 NotificationMessage
,并直接在终端中输出 JSON
:
# The subscription used to receive published messages from a topic
PUBSUB_SUBSCRIPTION="projects/project-id/subscriptions/subscription-id"
gcloud pubsub subscriptions pull $PUBSUB_SUBSCRIPTION
Python
# Requires https://cloud.google.com/pubsub/docs/quickstart-client-libraries#pubsub-client-libraries-python
import concurrent
from google.cloud import pubsub_v1
from google.cloud.securitycenter_v1 import NotificationMessage
# TODO: project_id = "your-project-id"
# TODO: subscription_name = "your-subscription-name"
def callback(message):
print("Received message")
notification_msg = NotificationMessage.from_json(message.data)
print(
"Notification config name: {}".format(
notification_msg.notification_config_name
)
)
print("Finding: {}".format(notification_msg.finding))
# Ack the message to prevent it from being pulled again
message.ack()
subscriber = pubsub_v1.SubscriberClient()
subscription_path = subscriber.subscription_path(project_id, subscription_name)
streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
print("Listening for messages on {}...\n".format(subscription_path))
try:
streaming_pull_future.result(timeout=1) # Block for 1 second
except concurrent.futures.TimeoutError:
streaming_pull_future.cancel()
Java
import com.google.cloud.pubsub.v1.AckReplyConsumer;
import com.google.cloud.pubsub.v1.MessageReceiver;
import com.google.cloud.pubsub.v1.Subscriber;
import com.google.cloud.securitycenter.v1.NotificationMessage;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.util.JsonFormat;
import com.google.pubsub.v1.ProjectSubscriptionName;
import com.google.pubsub.v1.PubsubMessage;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class NotificationReceiver {
private NotificationReceiver() {}
static class NotificationMessageReceiver implements MessageReceiver {
@Override
public void receiveMessage(PubsubMessage message, AckReplyConsumer consumer) {
NotificationMessage.Builder notificationMessageBuilder = NotificationMessage.newBuilder();
try {
String jsonString = message.getData().toStringUtf8();
JsonFormat.parser().merge(jsonString, notificationMessageBuilder);
NotificationMessage notificationMessage = notificationMessageBuilder.build();
System.out.println(
String.format("Config id: %s", notificationMessage.getNotificationConfigName()));
System.out.println(String.format("Finding: %s", notificationMessage.getFinding()));
} catch (InvalidProtocolBufferException e) {
System.out.println("Could not parse message: " + e);
} finally {
consumer.ack();
}
}
}
public static void receiveNotificationMessages(String projectId, String subscriptionId) {
// String projectId = "{your-project}";
// String subscriptionId = "{your-subscription}";
ProjectSubscriptionName subscriptionName =
ProjectSubscriptionName.of(projectId, subscriptionId);
try {
Subscriber subscriber =
Subscriber.newBuilder(subscriptionName, new NotificationMessageReceiver()).build();
subscriber.startAsync().awaitRunning();
// This sets the timeout value of the subscriber to 10s.
subscriber.awaitTerminated(10_000, TimeUnit.MILLISECONDS);
} catch (IllegalStateException | TimeoutException e) {
System.out.println("Subscriber stopped: " + e);
}
}
}
Go
import (
"bytes"
"context"
"fmt"
"io"
"cloud.google.com/go/pubsub"
"github.com/golang/protobuf/jsonpb"
securitycenterpb "google.golang.org/genproto/googleapis/cloud/securitycenter/v1"
)
func receiveMessages(w io.Writer, projectID string, subscriptionName string) error {
// projectID := "your-project-id"
// subsriptionName := "your-subscription-name"
ctx := context.Background()
client, err := pubsub.NewClient(ctx, projectID)
if err != nil {
return fmt.Errorf("pubsub.NewClient: %v", err)
}
defer client.Close()
sub := client.Subscription(subscriptionName)
cctx, cancel := context.WithCancel(ctx)
err = sub.Receive(cctx, func(ctx context.Context, msg *pubsub.Message) {
var notificationMessage = new(securitycenterpb.NotificationMessage)
jsonpb.Unmarshal(bytes.NewReader(msg.Data), notificationMessage)
fmt.Fprintln(w, "Got finding: ", notificationMessage.GetFinding())
msg.Ack()
cancel()
})
if err != nil {
return fmt.Errorf("Receive: %v", err)
}
return nil
}
Node.js
const {PubSub} = require('@google-cloud/pubsub');
const {StringDecoder} = require('string_decoder');
// projectId = 'your-project-id'
// subscriptionId = 'your-subscription-id'
const subscriptionName =
'projects/' + projectId + '/subscriptions/' + subscriptionId;
const pubSubClient = new PubSub();
function listenForMessages() {
const subscription = pubSubClient.subscription(subscriptionName);
// message.data is a buffer array of json
// 1. Convert buffer to normal string
// 2. Convert json to NotificationMessage object
const messageHandler = message => {
const jsonString = new StringDecoder('utf-8').write(message.data);
const parsedNotificationMessage = JSON.parse(jsonString);
console.log(parsedNotificationMessage);
console.log(parsedNotificationMessage.finding);
// ACK when done with message
message.ack();
};
subscription.on('message', messageHandler);
// Set timeout to 10 seconds
setTimeout(() => {
subscription.removeListener('message', messageHandler);
}, 10000);
}
listenForMessages();
后续步骤
- 了解如何过滤通知。