알림 구성 만들기 및 관리

이 페이지에서는 다음 예시를 포함하여 Security Command Center API 알림 기능을 사용하는 방법을 설명합니다.

  • NotificationConfig 만들기
  • NotificationConfig 받기
  • NotificationConfig 업데이트
  • NotificationConfig 삭제
  • NotificationConfig 나열
  • Pub/Sub 알림 수신

또는 Security Command Center 프리미엄 고객은 Security Command Center 대시보드에서 Pub/Sub의 지속적 내보내기를 설정할 수도 있습니다.

시작하기 전에

이 페이지의 예시를 사용하려면 발견 항목 알림 설정 가이드를 완료해야 합니다.

다음 예시를 실행하려면 적절한 권한이 있는 Identity and Access Management(IAM) 역할이 필요합니다.

  • NotificationConfig 만들기: 보안 센터 알림 구성 편집자(roles/securitycenter.notificationConfigEditor)
  • NotificationConfig 가져오기 및 나열: 보안 센터 알림 구성 뷰어(roles/securitycenter.notificationConfigViewer) 또는 보안 센터 알림 구성 편집자(roles/securitycenter.notificationConfigEditor)
  • NotificationConfig 업데이트 및 삭제: 보안 센터 알림 편집자(roles/securitycenter.notificationConfigEditor)

notificationConfig에 액세스하는 주 구성원에게 적절한 역할을 부여하려면 다음 IAM 역할 중 하나가 있어야 합니다.

  • 조직 관리자(roles/resourcemanager.organizationAdmin)
  • 폴더 IAM 관리자(roles/resourcemanager.folderIamAdmin)
  • 프로젝트 IAM 관리자(roles/resourcemanager.projectIamAdmin)

Security Command Center의 IAM 역할은 조직, 폴더, 프로젝트 수준에서 부여할 수 있습니다. 발견 항목, 애셋, 보안 소스를 보거나 수정하거나 만들거나 업데이트할 수 있는 기능은 액세스 권한이 부여된 수준에 따라 다릅니다. Security Command Center 역할에 대해 자세히 알아보려면 액세스 제어를 참조하세요.

데이터 상주 및 알림

Security Command Center에 데이터 상주가 사용 설정된 경우 Pub/Sub(notificationConfig 리소스)에 대한 지속적인 내보내기를 정의하는 구성은 데이터 상주 제어의 대상이 되며 Security Command Center 위치에 저장됩니다.

Security Command Center 위치의 발견 항목을 Pub/Sub로 내보내려면 발견 항목과 동일한 Security Command Center 위치에 지속적 내보내기를 구성해야 합니다.

지속적 내보내기에 사용된 필터는 상주 제어가 적용되는 데이터를 포함할 수 있기 때문에 이를 만들기 전에 올바른 위치를 지정해야 합니다. Security Command Center는 내보내기를 만드는 위치를 제한하지 않습니다.

지속적 내보내기는 생성되는 위치에만 저장되며 다른 위치에서 보거나 수정할 수 없습니다.

지속적 내보내기를 만든 후에는 해당 위치를 변경할 수 없습니다. 위치를 변경하려면 지속적 내보내기를 삭제하고 새 위치에 다시 만들어야 합니다.

API 호출을 사용해서 지속적 내보내기를 검색하려면 notificationConfig의 전체 리소스 이름에 위치를 지정해야 합니다. 예를 들면 다음과 같습니다.

GET https://securitycenter.googleapis.com/v2/{name=organizations/123/locations/eu/notificationConfigs/my-pubsub-export-01}

마찬가지로 gcloud CLI를 사용하여 지속적 내보내기를 가져오려면 구성의 전체 리소스 이름 또는 --locations 플래그를 사용하여 위치를 지정해야 합니다. 예를 들면 다음과 같습니다.

gcloud scc notifications describe myContinuousExport organizations/123 \
    --location=locations/us

NotificationConfig 만들기

NotificationConfig를 만들려면 다음이 필요합니다.

  • 알림을 보낼 기존 Pub/Sub 주제
  • notificationConfig를 만드는 주 구성원에 필요한 IAM 역할

자세한 내용은 발견 항목 알림 설정 가이드의 Pub/Sub 주제 설정 단계를 참조하세요.

NotificationConfig를 만들기 전에 각 조직에는 제한된 수의 NotificationConfig 파일이 있을 수 있습니다. 자세한 내용은 할당량 및 한도를 참조하세요.

NotificationConfig에는 알림을 유용한 이벤트로 제한하는 filter 필드가 포함되어 있습니다. 이 필드는 Security Command Center API findings.list 메서드에서 사용할 수 있는 모든 필터를 허용합니다.

NotificationConfig를 만들 때 Google Cloud 리소스 계층 구조(조직, 폴더 또는 프로젝트)에서 NotificationConfig의 상위 요소를 지정합니다. NotificationConfig를 검색, 업데이트 또는 삭제해야 하는 경우 참조할 때 상위 조직, 폴더 또는 프로젝트의 숫자 ID를 포함해야 합니다.

원하는 언어 또는 플랫폼을 사용하여 NotificationConfig를 만들려면 다음 안내를 따르세요.

gcloud

gcloud scc notifications create NOTIFICATION_NAME \
--PARENT=PARENT_ID \
--location=LOCATION
--description="NOTIFICATION_DESCRIPTION" \
--pubsub-topic=PUBSUB_TOPIC \
--filter="FILTER"

다음을 바꿉니다.

  • NOTIFICATION_NAME: 알림의 이름입니다. 이름은 1~128자(영문 기준) 사이여야 하며 영숫자 문자, 밑줄, 하이픈만 포함해야 합니다.
  • PARENT: 알림이 적용되는 리소스 계층 구조의 범위(organization, folder 또는 project)입니다.
  • PARENT_ID: organizations/123, folders/456, projects/789 형식으로 지정된 상위 조직, 폴더 또는 프로젝트의 ID입니다.
  • LOCATION: 데이터 상주가 사용 설정된 경우 알림을 만들 Security Command Center 위치를 지정합니다. 결과 notificationConfig 리소스는 이 위치에만 저장됩니다. 이 위치에서 발급된 발견 항목만 Pub/Sub로 전송됩니다.

    데이터 상주가 사용 설정되지 않은 경우 --location 플래그를 지정하면 Security Command Center API v2를 사용하여 알림이 생성되고 플래그에 대한 유효한 유일한 값은 global입니다.

  • NOTIFICATION_DESCRIPTION: 알림에 대한 설명입니다(1,024자 이내). .

  • PUBSUB_TOPIC: 알림을 수신할 Pub/Sub 주제입니다. 형식은 projects/PROJECT_ID/topics/TOPIC입니다.

  • FILTER: Pub/Sub로 전송되는 발견 항목을 선택하기 위해 정의하는 표현식입니다. 예를 들면 state="ACTIVE"입니다.

Python

다음 샘플은 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

def create_notification_config(parent_id, notification_config_id, pubsub_topic):
    """
    Args:
        parent_id: must be in one of the following formats:
            "organizations/{organization_id}"
            "projects/{project_id}"
            "folders/{folder_id}"
        notification_config_id: "your-config-id"
        pubsub_topic: "projects/{your-project-id}/topics/{your-topic-ic}"

    Ensure this ServiceAccount has the "pubsub.topics.setIamPolicy" permission on the new topic.
    """
    from google.cloud import securitycenter as securitycenter

    client = securitycenter.SecurityCenterClient()

    created_notification_config = client.create_notification_config(
        request={
            "parent": parent_id,
            "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

다음 샘플은 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.


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 class CreateNotificationConfigSnippets {

  public static void main(String[] args) throws IOException {
    // parentId: must be in one of the following formats:
    //    "organizations/{organization_id}"
    //    "projects/{project_id}"
    //    "folders/{folder_id}"
    String parentId = String.format("organizations/%s", "ORG_ID");
    String notificationConfigId = "{config-id}";
    String projectId = "{your-project}";
    String topicName = "{your-topic}";

    createNotificationConfig(parentId, notificationConfigId, projectId, topicName);
  }

  // Crete a notification config.
  // Ensure the ServiceAccount has the "pubsub.topics.setIamPolicy" permission on the new topic.
  public static NotificationConfig createNotificationConfig(
      String parentId, String notificationConfigId, String projectId, String topicName)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (SecurityCenterClient client = SecurityCenterClient.create()) {

      // Ensure this ServiceAccount has the "pubsub.topics.setIamPolicy" permission on the topic.
      String pubsubTopic = String.format("projects/%s/topics/%s", projectId, topicName);

      CreateNotificationConfigRequest request =
          CreateNotificationConfigRequest.newBuilder()
              .setParent(parentId)
              .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.printf("Notification config was created: %s%n", response);
      return response;
    }
  }
}

Go

다음 샘플은 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
)

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: %w", err)
	}
	defer client.Close()

	req := &securitycenterpb.CreateNotificationConfigRequest{
		// Parent must be in one of the following formats:
		//		"organizations/{orgId}"
		//		"projects/{projectId}"
		//		"folders/{folderId}"
		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: %w", err)
	}
	fmt.Fprintln(w, "New NotificationConfig created: ", notificationConfig)

	return nil
}

Node.js

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

// npm install '@google-cloud/security-center'
const {SecurityCenterClient} = require('@google-cloud/security-center');

const client = new SecurityCenterClient();

// parent: must be in one of the following formats:
//    `organizations/${organization_id}`
//    `projects/${project_id}`
//    `folders/${folder_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 parent = `organizations/${organizationId}`;

async function createNotificationConfig() {
  const [response] = await client.createNotificationConfig({
    parent: parent,
    configId: configId,
    notificationConfig: {
      description: 'Sample config for node.js',
      pubsubTopic: pubsubTopic,
      streamingConfig: {filter: 'state = "ACTIVE"'},
    },
  });
  console.log('Notification config creation succeeded: ', response);
}

createNotificationConfig();

PHP

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

use Google\Cloud\SecurityCenter\V1\Client\SecurityCenterClient;
use Google\Cloud\SecurityCenter\V1\CreateNotificationConfigRequest;
use Google\Cloud\SecurityCenter\V1\NotificationConfig;
use Google\Cloud\SecurityCenter\V1\NotificationConfig\StreamingConfig;

/**
 * @param string $organizationId        Your org ID
 * @param string $notificationConfigId  A unique identifier
 * @param string $projectId             Your Cloud Project ID
 * @param string $topicName             Your topic name
 */
function create_notification(
    string $organizationId,
    string $notificationConfigId,
    string $projectId,
    string $topicName
): void {
    $securityCenterClient = new SecurityCenterClient();
    // 'parent' must be in one of the following formats:
    //		"organizations/{orgId}"
    //		"projects/{projectId}"
    //		"folders/{folderId}"
    $parent = $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);
    $createNotificationConfigRequest = (new CreateNotificationConfigRequest())
        ->setParent($parent)
        ->setConfigId($notificationConfigId)
        ->setNotificationConfig($notificationConfig);

    $response = $securityCenterClient->createNotificationConfig($createNotificationConfigRequest);
    printf('Notification config was created: %s' . PHP_EOL, $response->getName());
}

Ruby

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

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

# You can also use 'project_id' or 'folder_id' as a parent.
# client.project_path project: project_id
# client.folder_path folder: folder_id
parent = 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:              parent,
  config_id:           config_id,
  notification_config: notification_config
)
puts "Created notification config #{config_id}: #{response}."

C#

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.


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)
    {
        // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
        //      ProjectName projectName = new ProjectName(projectId);
        //      FolderName folderName = new FolderName(folderId);
        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 주제에 게시됩니다.

알림을 게시하려면 service-org-ORGANIZATION_ID@gcp-sa-scc-notification.iam.gserviceaccount.com 형식으로 서비스 계정이 생성됩니다. 이 서비스 계정은 첫 번째 NotificationConfig를 만들 때 생성되며 알림 구성을 만들 때 PUBSUB_TOPIC에 대한 IAM 정책에 securitycenter.notificationServiceAgent 역할이 자동으로 부여됩니다. 알림이 작동하려면 서비스 계정 역할이 필요합니다.

NotificationConfig 가져오기

NotificationConfig를 가져오려면 securitycenter.notification.get 권한이 포함된 IAM 역할이 있어야 합니다.

gcloud

gcloud scc notifications describe PARENT_TYPE/PARENT_ID/locations/LOCATION/notificationConfigs/NOTIFICATION_NAME

다음을 바꿉니다.

  • 알림 구성에 지정된 리소스 계층 구조의 수준에 따라 PARENT_TYPEorganizations, folders 또는 projects로 바꿉니다.
  • PARENT_ID를 상위 리소스의 숫자 ID로 바꿉니다.
  • LOCATION: 데이터 상주가 사용 설정되었거나 API v2를 사용하여 notificationConfig 리소스가 생성된 경우에 필요합니다.

    데이터 상주가 사용 설정된 경우 알림이 저장되는 Security Command Center 위치를 지정합니다.

    데이터 상주가 사용 설정되지 않았으면 Security Command Center API v2를 사용하여 notificationConfig 리소스가 생성된 경우에만 /locations/LOCATION을 포함합니다. 이 경우 유효한 유일한 위치는 global입니다.

  • NOTIFICATION_NAME: 알림의 이름입니다.

Python

다음 샘플은 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

def get_notification_config(parent_id, notification_config_id):
    """
    Args:
        parent_id: must be in one of the following formats:
            "organizations/{organization_id}"
            "projects/{project_id}"
            "folders/{folder_id}"
        notification_config_id: "your-config-id"
    """
    from google.cloud import securitycenter as securitycenter

    client = securitycenter.SecurityCenterClient()

    notification_config_name = (
        f"{parent_id}/notificationConfigs/{notification_config_id}"
    )

    notification_config = client.get_notification_config(
        request={"name": notification_config_name}
    )
    print(f"Got notification config: {notification_config}")

Java

다음 샘플은 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.


import com.google.cloud.securitycenter.v1.NotificationConfig;
import com.google.cloud.securitycenter.v1.SecurityCenterClient;
import java.io.IOException;

public class GetNotificationConfigSnippets {

  public static void main(String[] args) throws IOException {
    // parentId: must be in one of the following formats:
    //    "organizations/{organization_id}"
    //    "projects/{project_id}"
    //    "folders/{folder_id}"
    String parentId = String.format("organizations/%s", "ORG_ID");

    String notificationConfigId = "{config-id}";

    getNotificationConfig(parentId, notificationConfigId);
  }

  // Retrieve an existing notification config.
  public static NotificationConfig getNotificationConfig(
      String parentId, String notificationConfigId) throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (SecurityCenterClient client = SecurityCenterClient.create()) {
      NotificationConfig response =
          client.getNotificationConfig(String.format("%s/notificationConfigs/%s",
              parentId, notificationConfigId));

      System.out.printf("Notification config: %s%n", response);
      return response;
    }
  }
}

Go

다음 샘플은 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
)

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: %w", err)
	}
	defer client.Close()

	// Parent must be in one of the following formats:
	//		"organizations/{orgId}"
	//		"projects/{projectId}"
	//		"folders/{folderId}"
	parent := fmt.Sprintf("organizations/%s", orgID)
	req := &securitycenterpb.GetNotificationConfigRequest{
		Name: fmt.Sprintf("%s/notificationConfigs/%s", parent, notificationConfigID),
	}

	notificationConfig, err := client.GetNotificationConfig(ctx, req)
	if err != nil {
		return fmt.Errorf("Failed to retrieve notification config: %w", err)
	}
	fmt.Fprintln(w, "Received config: ", notificationConfig)

	return nil
}

Node.js

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

// npm install @google-cloud/security-center/
const {SecurityCenterClient} = require('@google-cloud/security-center');

const client = new SecurityCenterClient();

// formattedConfigName: You can also use
//    `client.projectNotificationConfigPath(projectId, configId)` or
//    `client.folderNotificationConfigPath(folderId, configId)`.
// configId = "your-config-id";
const formattedConfigName = client.organizationNotificationConfigPath(
  organizationId,
  configId
);

async function getNotificationConfg() {
  const [response] = await client.getNotificationConfig({
    name: formattedConfigName,
  });
  console.log('Notification config: ', response);
}

getNotificationConfg();

PHP

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

use Google\Cloud\SecurityCenter\V1\Client\SecurityCenterClient;
use Google\Cloud\SecurityCenter\V1\GetNotificationConfigRequest;

/**
 * @param string $organizationId        Your org ID
 * @param string $notificationConfigId  A unique identifier
 */
function get_notification(string $organizationId, string $notificationConfigId): void
{
    $securityCenterClient = new SecurityCenterClient();
    $notificationConfigName = $securityCenterClient::notificationConfigName(
        // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
        $organizationId,
        $notificationConfigId
    );
    $getNotificationConfigRequest = (new GetNotificationConfigRequest())
        ->setName($notificationConfigName);

    $response = $securityCenterClient->getNotificationConfig($getNotificationConfigRequest);
    printf('Notification config was retrieved: %s' . PHP_EOL, $response->getName());
}

Ruby

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

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

# You can also use 'project_id' or 'folder_id' as a parent.
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#

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.


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();
        // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
        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 권한이 있어야 합니다.

필요한 권한을 부여한 후 원하는 언어를 사용하여 NotificationConfig 설명, Pub/Sub 주제, 필터를 업데이트합니다.

gcloud

gcloud scc notifications update PARENT_TYPE/PARENT_ID/locations/LOCATION/notificationConfigs/NOTIFICATION_NAME
--description="NOTIFICATION_DESCRIPTION" \
--pubsub-topic=PUBSUB_TOPIC \
--filter="FILTER"

다음을 바꿉니다.

  • 알림 구성에 지정된 리소스 계층 구조의 수준에 따라 PARENT_TYPEorganizations, folders 또는 projects로 바꿉니다.
  • PARENT_ID를 상위 리소스의 숫자 ID로 바꿉니다.
  • LOCATION: 데이터 상주가 사용 설정되었거나 API v2를 사용하여 notificationConfig가 생성된 경우에 필요합니다.

    데이터 상주가 사용 설정된 경우 알림이 저장되는 Security Command Center 위치를 지정합니다.

    데이터 상주가 사용 설정되지 않은 경우 Security Command Center API v2를 사용하여 notificationConfig 리소스를 만든 경우에만 전체 이름에 /locations/LOCATION을 포함하거나 --location 플래그를 지정합니다. 이 경우 유효한 유일한 위치는 global입니다.

  • NOTIFICATION_NAME: 알림의 이름입니다.

  • NOTIFICATION_DESCRIPTION: 알림에 대한 설명입니다(1,024자 이내). .

  • PUBSUB_TOPIC: 알림을 수신할 Pub/Sub 주제입니다. 형식은 projects/PROJECT_ID/topics/TOPIC입니다.

  • FILTER: Pub/Sub로 전송되는 발견 항목을 선택하기 위해 정의하는 표현식입니다. 예를 들면 state="ACTIVE"입니다.

Python

다음 샘플은 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

def update_notification_config(parent_id, notification_config_id, pubsub_topic):
    """
    Args:
        parent_id: must be in one of the following formats:
            "organizations/{organization_id}"
            "projects/{project_id}"
            "folders/{folder_id}"
        notification_config_id: "config-id-to-update"
        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.
    """
    from google.cloud import securitycenter as securitycenter
    from google.protobuf import field_mask_pb2

    client = securitycenter.SecurityCenterClient()

    notification_config_name = (
        f"{parent_id}/notificationConfigs/{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

다음 샘플은 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.


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 class UpdateNotificationConfigSnippets {

  public static void main(String[] args) throws IOException {
    // parentId: must be in one of the following formats:
    //    "organizations/{organization_id}"
    //    "projects/{project_id}"
    //    "folders/{folder_id}"
    String parentId = String.format("organizations/%s", "ORG_ID");
    String notificationConfigId = "{config-id}";
    String projectId = "{your-project}";
    String topicName = "{your-topic}";

    updateNotificationConfig(parentId, notificationConfigId, projectId, topicName);
  }

  // Update an existing notification config.
  // If updating a Pubsub Topic, ensure the ServiceAccount has the
  // "pubsub.topics.setIamPolicy" permission on the new topic.
  public static NotificationConfig updateNotificationConfig(
      String parentId, String notificationConfigId, String projectId, String topicName)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (SecurityCenterClient client = SecurityCenterClient.create()) {

      String notificationConfigName =
          String.format(
              "%s/notificationConfigs/%s", parentId, 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();

      NotificationConfig updatedConfig = client.updateNotificationConfig(configToUpdate, fieldMask);

      System.out.printf("Notification config: %s%n", updatedConfig);
      return updatedConfig;
    }
  }
}

Go

다음 샘플은 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
	"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: %w", err)
	}
	defer client.Close()

	updatedDescription := "Updated sample config"
	updatedFilter := `state = "INACTIVE"`
	// Parent must be in one of the following formats:
	//		"organizations/{orgId}"
	//		"projects/{projectId}"
	//		"folders/{folderId}"
	parent := fmt.Sprintf("organizations/%s", orgID)
	req := &securitycenterpb.UpdateNotificationConfigRequest{
		NotificationConfig: &securitycenterpb.NotificationConfig{
			Name:        fmt.Sprintf("%s/notificationConfigs/%s", parent, 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: %w", err)
	}

	fmt.Fprintln(w, "Updated NotificationConfig: ", notificationConfig)

	return nil
}

Node.js

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

// npm install @google-cloud/security-center/
const {SecurityCenterClient} = require('@google-cloud/security-center');

const client = new SecurityCenterClient();

// formattedConfigName: You can also use
//    `client.projectNotificationConfigPath(projectId, configId)` or
//    `client.folderNotificationConfigPath(folderId, configId)`.
// configId = "your-config-id";
const formattedConfigName = client.organizationNotificationConfigPath(
  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

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

use Google\Cloud\SecurityCenter\V1\Client\SecurityCenterClient;
use Google\Cloud\SecurityCenter\V1\NotificationConfig;
use Google\Cloud\SecurityCenter\V1\NotificationConfig\StreamingConfig;
use Google\Cloud\SecurityCenter\V1\UpdateNotificationConfigRequest;
use Google\Protobuf\FieldMask;

/**
 * @param string $organizationId        Your org ID
 * @param string $notificationConfigId  A unique identifier
 * @param string $projectId             Your Cloud Project ID
 * @param string $topicName             Your topic name
 */
function update_notification(
    string $organizationId,
    string $notificationConfigId,
    string $projectId,
    string $topicName
): void {
    $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);
    // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
    $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);
    $updateNotificationConfigRequest = (new UpdateNotificationConfigRequest())
        ->setNotificationConfig($notificationConfig);

    $response = $securityCenterClient->updateNotificationConfig($updateNotificationConfigRequest);
    printf('Notification config was updated: %s' . PHP_EOL, $response->getName());
}

Ruby

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

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

# You can also use 'project_id' or 'folder_id' as a parent.
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#

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.


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)
    {
        // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
        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

gcloud scc notifications delete PARENT_TYPE/PARENT_ID/locations/LOCATION/notificationConfigs/NOTIFICATION_NAME

다음을 바꿉니다.

  • 알림 구성에 지정된 리소스 계층 구조의 수준에 따라 PARENT_TYPEorganizations, folders 또는 projects로 바꿉니다.
  • PARENT_ID를 상위 리소스의 숫자 ID로 바꿉니다.
  • LOCATION: 데이터 상주가 사용 설정되었거나 API v2를 사용하여 notificationConfig가 생성된 경우에 필요합니다.

    데이터 상주가 사용 설정된 경우 알림이 저장되는 Security Command Center 위치를 지정합니다.

    데이터 상주가 사용 설정되지 않은 경우 Security Command Center API v2를 사용하여 notificationConfig를 만든 경우에만 전체 이름에 /locations/LOCATION을 포함하거나 --location 플래그를 지정합니다. 이 경우 유효한 유일한 위치는 global입니다.

  • NOTIFICATION_NAME: 알림의 이름입니다.

Python

다음 샘플은 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

def delete_notification_config(parent_id, notification_config_id):
    """
    Args:
        parent_id: must be in one of the following formats:
            "organizations/{organization_id}"
            "projects/{project_id}"
            "folders/{folder_id}"
        notification_config_id: "your-config-id"
    """
    from google.cloud import securitycenter as securitycenter

    client = securitycenter.SecurityCenterClient()

    notification_config_name = (
        f"{parent_id}/notificationConfigs/{notification_config_id}"
    )

    client.delete_notification_config(request={"name": notification_config_name})
    print(f"Deleted notification config: {notification_config_name}")

Java

다음 샘플은 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.


import com.google.cloud.securitycenter.v1.SecurityCenterClient;
import java.io.IOException;

public class DeleteNotificationConfigSnippets {

  public static void main(String[] args) throws IOException {
    // parentId: must be in one of the following formats:
    //    "organizations/{organization_id}"
    //    "projects/{project_id}"
    //    "folders/{folder_id}"
    String parentId = String.format("organizations/%s", "ORG_ID");

    String notificationConfigId = "{config-id}";

    deleteNotificationConfig(parentId, notificationConfigId);
  }

  // Delete a notification config.
  public static boolean deleteNotificationConfig(String parentId, String notificationConfigId)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (SecurityCenterClient client = SecurityCenterClient.create()) {

      client.deleteNotificationConfig(String.format("%s/notificationConfigs/%s",
          parentId, notificationConfigId));

      System.out.printf("Deleted Notification config: %s%n", notificationConfigId);
    }
    return true;
  }
}

Go

다음 샘플은 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
)

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: %w", err)
	}
	defer client.Close()

	// Parent must be in one of the following formats:
	//		"organizations/{orgId}"
	//		"projects/{projectId}"
	//		"folders/{folderId}"
	parent := fmt.Sprintf("organizations/%s", orgID)
	name := fmt.Sprintf("%s/notificationConfigs/%s", parent, notificationConfigID)
	req := &securitycenterpb.DeleteNotificationConfigRequest{
		Name: name,
	}

	if err = client.DeleteNotificationConfig(ctx, req); err != nil {
		return fmt.Errorf("Failed to retrieve notification config: %w", err)
	}
	fmt.Fprintln(w, "Deleted config: ", name)

	return nil
}

Node.js

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

// npm install @google-cloud/security-center/
const {SecurityCenterClient} = require('@google-cloud/security-center');

const client = new SecurityCenterClient();

// formattedConfigName: You can also use
//    `client.projectNotificationConfigPath(projectId, configId)` or
//    `client.folderNotificationConfigPath(folderId, configId)`.
// configId = "your-config-id";
const formattedConfigName = client.organizationNotificationConfigPath(
  organizationId,
  configId
);

async function deleteNotificationConfg() {
  await client.deleteNotificationConfig({name: formattedConfigName});
  console.log('Notification config deleted: ', formattedConfigName);
}

deleteNotificationConfg();

PHP

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

use Google\Cloud\SecurityCenter\V1\Client\SecurityCenterClient;
use Google\Cloud\SecurityCenter\V1\DeleteNotificationConfigRequest;

/**
 * @param string $organizationId        Your org ID
 * @param string $notificationConfigId  A unique identifier
 */
function delete_notification(string $organizationId, string $notificationConfigId): void
{
    $securityCenterClient = new SecurityCenterClient();
    $notificationConfigName = $securityCenterClient::notificationConfigName(
        // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
        $organizationId,
        $notificationConfigId
    );
    $deleteNotificationConfigRequest = (new DeleteNotificationConfigRequest())
        ->setName($notificationConfigName);

    $securityCenterClient->deleteNotificationConfig($deleteNotificationConfigRequest);
    print('Notification config was deleted' . PHP_EOL);
}

Ruby

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

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

# You can also use 'project_id' or 'folder_id' as a parent.
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#

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.


using Google.Cloud.SecurityCenter.V1;
using System;

/// <summary>Snippet for DeleteNotificationConfig</summary>
public class DeleteNotificationConfigSnippets
{
    public static bool DeleteNotificationConfig(string organizationId, string notificationConfigId)
    {
        // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
        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에서 최대 1,000으로 구성할 수 있습니다.

원하는 언어를 사용하여 NotificationConfigs을 나열합니다.

gcloud

gcloud scc notifications list PARENT_TYPE/PARENT_ID/locations/LOCATION

다음을 바꿉니다.

  • PARENT_TYPE을 알림을 나열해야 하는 범위에 따라 organizations, folders 또는 projects로 바꿉니다.
  • PARENT_ID를 상위 리소스의 숫자 ID로 바꿉니다.
  • LOCATION: 데이터 상주가 사용 설정되었거나 API v2를 사용하여 notificationConfig 리소스가 생성된 경우에 필요합니다.

    데이터 상주가 사용 설정된 경우 알림이 저장되는 Security Command Center 위치를 지정합니다.

    데이터 상주가 사용 설정되지 않은 경우 Security Command Center API v2를 사용하여 만든 notificationConfig 리소스를 만든 경우에만 이름에 /locations/LOCATION을 포함하거나 명령어에 --location 플래그를 포함하며, 유효한 유일한 위치는 global입니다.

Python

다음 샘플은 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

def list_notification_configs(parent_id):
    """
    Args:
        parent_id: must be in one of the following formats:
            "organizations/{organization_id}"
            "projects/{project_id}"
            "folders/{folder_id}"
    """
    from google.cloud import securitycenter as securitycenter

    client = securitycenter.SecurityCenterClient()

    notification_configs_iterator = client.list_notification_configs(
        request={"parent": parent_id}
    )
    for i, config in enumerate(notification_configs_iterator):
        print(f"{i}: notification_config: {config}")

Java

다음 샘플은 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.


import com.google.cloud.securitycenter.v1.NotificationConfig;
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 class ListNotificationConfigSnippets {

  public static void main(String[] args) throws IOException {
    // parentId: must be in one of the following formats:
    //    "organizations/{organization_id}"
    //    "projects/{project_id}"
    //    "folders/{folder_id}"
    String parentId = String.format("organizations/%s", "ORG_ID");

    listNotificationConfigs(parentId);
  }

  // List notification configs present in the given parent.
  public static ImmutableList<NotificationConfig> listNotificationConfigs(String parentId)
      throws IOException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the "close" method on the client to safely clean up any remaining background resources.
    try (SecurityCenterClient client = SecurityCenterClient.create()) {

      ListNotificationConfigsPagedResponse response = client.listNotificationConfigs(parentId);

      ImmutableList<NotificationConfig> notificationConfigs =
          ImmutableList.copyOf(response.iterateAll());

      System.out.printf("List notifications response: %s%n", response.getPage().getValues());
      return notificationConfigs;
    }
  }
}

Go

다음 샘플은 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

import (
	"context"
	"fmt"
	"io"

	securitycenter "cloud.google.com/go/securitycenter/apiv1"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
	"google.golang.org/api/iterator"
)

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: %w", err)
	}
	defer client.Close()

	req := &securitycenterpb.ListNotificationConfigsRequest{
		// Parent must be in one of the following formats:
		//		"organizations/{orgId}"
		//		"projects/{projectId}"
		//		"folders/{folderId}"
		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: %w", err)
		}

		fmt.Fprintln(w, "NotificationConfig: ", result)
	}

	return nil
}

Node.js

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

// npm install @google-cloud/security-center/
const {SecurityCenterClient} = require('@google-cloud/security-center');

const client = new SecurityCenterClient();

// parent: must be in one of the following formats:
//    `organizations/${organization_id}`
//    `projects/${project_id}`
//    `folders/${folder_id}`
const parent = `organizations/${organizationId}`;

async function listNotificationConfigs() {
  const [resources] = await client.listNotificationConfigs({parent: parent});
  console.log('Received Notification configs: ');
  for (const resource of resources) {
    console.log(resource);
  }
}

listNotificationConfigs();

PHP

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

use Google\Cloud\SecurityCenter\V1\Client\SecurityCenterClient;
use Google\Cloud\SecurityCenter\V1\ListNotificationConfigsRequest;

/**
 * @param string $organizationId        Your org ID
 */
function list_notification(string $organizationId): void
{
    $securityCenterClient = new SecurityCenterClient();
    // 'parent' must be in one of the following formats:
    //		"organizations/{orgId}"
    //		"projects/{projectId}"
    //		"folders/{folderId}"
    $parent = $securityCenterClient::organizationName($organizationId);
    $listNotificationConfigsRequest = (new ListNotificationConfigsRequest())
        ->setParent($parent);

    foreach ($securityCenterClient->listNotificationConfigs($listNotificationConfigsRequest) as $element) {
        printf('Found notification config %s' . PHP_EOL, $element->getName());
    }

    print('Notification configs were listed' . PHP_EOL);
}

Ruby

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.

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

# You can also use 'project_id' or 'folder_id' as a parent.
# client.project_path project: project_id
# client.folder_path folder: folder_id
parent = client.organization_path organization: org_id

client.list_notification_configs(parent: parent).each_page do |page|
  page.each do |element|
    puts element
  end
end

C#

다음 샘플에서는 v1 API를 사용합니다. v2의 샘플을 수정하려면 v1v2로 바꾸고 /locations/LOCATION을 리소스 이름에 추가합니다.

대부분의 리소스의 경우 /PARENT/PARENT_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 PARENTorganizations, folders 또는 projects입니다.

발견 항목의 경우 /sources/SOURCE_ID 뒤에 /locations/LOCATION을 리소스 이름에 추가합니다. 여기서 SOURCE_ID는 발견 항목을 실행한 Security Command Center 서비스의 ID입니다.


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)
    {
        // You can also use 'projectId' or 'folderId' instead of the 'organizationId'.
        //      ProjectName projectName = new ProjectName(projectId);
        //      FolderName folderName = new FolderName(folderId);
        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 CLI는 Pub/Sub 메시지를 NotificationMessage로 변환할 수 없습니다. gcloud CLI를 사용하여 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

다음을 바꿉니다.

  • PROJECT_ID를 프로젝트 ID로 바꿉니다.
  • SUBSCRIPTION_ID를 구독 ID로 바꿉니다.

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 the data received for debugging purpose if needed
    print(f"Received message: {message.data}")

    notification_msg = NotificationMessage.from_json(message.data)

    print(
        "Notification config name: {}".format(
            notification_msg.notification_config_name
        )
    )
    print(f"Finding: {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(f"Listening for messages on {subscription_path}...\n")
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() {
  }

  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);
    }
  }

  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();
      }
    }
  }
}

Go

import (
	"bytes"
	"context"
	"fmt"
	"io"

	"cloud.google.com/go/pubsub"
	"cloud.google.com/go/securitycenter/apiv1/securitycenterpb"
	"github.com/golang/protobuf/jsonpb"
)

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: %w", 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: %w", 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();

PHP

use Google\Cloud\PubSub\PubSubClient;

/**
 * @param string $projectId             Your Cloud Project ID
 * @param string $subscriptionId        Your subscription ID
 */
function receive_notification(string $projectId, string $subscriptionId): void
{
    $pubsub = new PubSubClient([
        'projectId' => $projectId,
    ]);
    $subscription = $pubsub->subscription($subscriptionId);

    foreach ($subscription->pull() as $message) {
        printf('Message: %s' . PHP_EOL, $message->data());
        // Acknowledge the Pub/Sub message has been received, so it will not be pulled multiple times.
        $subscription->acknowledge($message);
    }
}

다음 단계