Skip to content
This repository was archived by the owner on Sep 5, 2023. It is now read-only.

Commit 24816bd

Browse files
authored
docs: add v1p1beta1 notifications samples (#9)
1 parent 6374db9 commit 24816bd

5 files changed

+370
-0
lines changed

docs/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
google-cloud-pubsub==1.3.0
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#!/usr/bin/env python
2+
#
3+
# Copyright 2020 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
"""Demos for working with notification configs."""
17+
18+
19+
def create_notification_config(organization_id, notification_config_id, pubsub_topic):
20+
21+
# [START scc_create_notification_config]
22+
from google.cloud import securitycenter_v1p1beta1 as securitycenter
23+
from google.cloud.securitycenter_v1p1beta1.proto.notification_config_pb2 import (
24+
NotificationConfig,
25+
)
26+
27+
client = securitycenter.SecurityCenterClient()
28+
29+
# TODO: organization_id = "your-org-id"
30+
# TODO: notification_config_id = "your-config-id"
31+
# TODO: pubsub_topic = "projects/{your-project-id}/topics/{your-topic-ic}"
32+
# Ensure this ServiceAccount has the "pubsub.topics.setIamPolicy" permission on the new topic.
33+
34+
org_name = "organizations/{org_id}".format(org_id=organization_id)
35+
36+
created_notification_config = client.create_notification_config(
37+
org_name,
38+
notification_config_id,
39+
{
40+
"description": "Notification for active findings",
41+
"pubsub_topic": pubsub_topic,
42+
"event_type": NotificationConfig.FINDING,
43+
"streaming_config": {"filter": 'state = "ACTIVE"',},
44+
},
45+
)
46+
47+
print(created_notification_config)
48+
# [END scc_create_notification_config]
49+
return created_notification_config
50+
51+
52+
def delete_notification_config(organization_id, notification_config_id):
53+
54+
# [START scc_delete_notification_config]
55+
from google.cloud import securitycenter_v1p1beta1 as securitycenter
56+
57+
client = securitycenter.SecurityCenterClient()
58+
59+
# TODO: organization_id = "your-org-id"
60+
# TODO: notification_config_id = "your-config-id"
61+
62+
notification_config_name = "organizations/{org_id}/notificationConfigs/{config_id}".format(
63+
org_id=organization_id, config_id=notification_config_id
64+
)
65+
66+
client.delete_notification_config(notification_config_name)
67+
print("Deleted notification config: {}".format(notification_config_name))
68+
# [END scc_delete_notification_config]
69+
return True
70+
71+
72+
def get_notification_config(organization_id, notification_config_id):
73+
74+
# [START scc_get_notification_config]
75+
from google.cloud import securitycenter_v1p1beta1 as securitycenter
76+
77+
client = securitycenter.SecurityCenterClient()
78+
79+
# TODO: organization_id = "your-org-id"
80+
# TODO: notification_config_id = "your-config-id"
81+
82+
notification_config_name = "organizations/{org_id}/notificationConfigs/{config_id}".format(
83+
org_id=organization_id, config_id=notification_config_id
84+
)
85+
86+
notification_config = client.get_notification_config(notification_config_name)
87+
print("Got notification config: {}".format(notification_config))
88+
# [END scc_get_notification_config]
89+
return notification_config
90+
91+
92+
def list_notification_configs(organization_id):
93+
94+
# [START scc_list_notification_configs]
95+
from google.cloud import securitycenter_v1p1beta1 as securitycenter
96+
97+
client = securitycenter.SecurityCenterClient()
98+
99+
# TODO: organization_id = "your-org-id"
100+
org_name = "organizations/{org_id}".format(org_id=organization_id)
101+
102+
notification_configs_iterator = client.list_notification_configs(org_name)
103+
for i, config in enumerate(notification_configs_iterator):
104+
print("{}: notification_config: {}".format(i, config))
105+
# [END scc_list_notification_configs]
106+
return notification_configs_iterator
107+
108+
109+
def update_notification_config(organization_id, notification_config_id, pubsub_topic):
110+
# [START scc_update_notification_config]
111+
from google.cloud import securitycenter_v1p1beta1 as securitycenter
112+
from google.protobuf import field_mask_pb2
113+
114+
client = securitycenter.SecurityCenterClient()
115+
116+
# TODO organization_id = "your-org-id"
117+
# TODO notification_config_id = "config-id-to-update"
118+
# TODO pubsub_topic = "projects/{new-project}/topics/{new-topic}"
119+
# If updating a pubsub_topic, ensure this ServiceAccount has the
120+
# "pubsub.topics.setIamPolicy" permission on the new topic.
121+
122+
notification_config_name = "organizations/{org_id}/notificationConfigs/{config_id}".format(
123+
org_id=organization_id, config_id=notification_config_id
124+
)
125+
126+
updated_description = "New updated description"
127+
128+
# Only description and pubsub_topic can be updated.
129+
field_mask = field_mask_pb2.FieldMask(paths=["description", "pubsub_topic"])
130+
131+
updated_notification_config = client.update_notification_config(
132+
{
133+
"name": notification_config_name,
134+
"description": updated_description,
135+
"pubsub_topic": pubsub_topic,
136+
},
137+
update_mask=field_mask,
138+
)
139+
140+
print(updated_notification_config)
141+
# [END scc_update_notification_config]
142+
return updated_notification_config
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/usr/bin/env python
2+
#
3+
# Copyright 2020 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
"""Demo for receiving notifications."""
17+
18+
19+
def receive_notifications(project_id, subscription_name):
20+
# [START scc_receive_notifications]
21+
# Requires https://cloud.google.com/pubsub/docs/quickstart-client-libraries#pubsub-client-libraries-python
22+
from google.cloud import pubsub_v1
23+
from google.cloud.securitycenter_v1p1beta1.proto.notification_message_pb2 import (
24+
NotificationMessage,
25+
)
26+
from google.protobuf import json_format
27+
28+
# TODO: project_id = "your-project-id"
29+
# TODO: subscription_name = "your-subscription-name"
30+
31+
def callback(message):
32+
print("Received message")
33+
34+
notification_msg = NotificationMessage()
35+
json_format.Parse(message.data, notification_msg)
36+
37+
print(
38+
"Notification config name: {}".format(
39+
notification_msg.notification_config_name
40+
)
41+
)
42+
print("Finding: {}".format(notification_msg.finding))
43+
44+
# Ack the message to prevent it from being pulled again
45+
message.ack()
46+
47+
subscriber = pubsub_v1.SubscriberClient()
48+
subscription_path = subscriber.subscription_path(project_id, subscription_name)
49+
50+
streaming_pull_future = subscriber.subscribe(subscription_path, callback=callback)
51+
52+
print("Listening for messages on {}...\n".format(subscription_path))
53+
try:
54+
streaming_pull_future.result(timeout=1) # Block for 1 second
55+
except:
56+
streaming_pull_future.cancel()
57+
# [END scc_receive_notifications]
58+
return True

docs/v1p1beta1/snippets_test.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#!/usr/bin/env python
2+
#
3+
# Copyright 2020 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
"""Tests for snippets."""
17+
18+
import os
19+
import uuid
20+
21+
from google.cloud import securitycenter_v1p1beta1 as securitycenter
22+
from google.cloud.securitycenter_v1p1beta1.proto.notification_config_pb2 import (
23+
NotificationConfig,
24+
)
25+
import pytest
26+
27+
import snippets_notification_configs
28+
import snippets_notification_receiver
29+
30+
ORG_ID = os.environ["GCLOUD_ORGANIZATION"]
31+
PROJECT_ID = os.environ["GCLOUD_PROJECT"]
32+
PUBSUB_TOPIC = os.environ["GCLOUD_PUBSUB_TOPIC"]
33+
PUBSUB_SUBSCRIPTION = os.environ["GCLOUD_PUBSUB_SUBSCRIPTION"]
34+
35+
CREATE_CONFIG_ID = "new-notification-pytest" + str(uuid.uuid1())
36+
DELETE_CONFIG_ID = "new-notification-pytest" + str(uuid.uuid1())
37+
GET_CONFIG_ID = "new-notification-pytest" + str(uuid.uuid1())
38+
UPDATE_CONFIG_ID = "new-notification-pytest" + str(uuid.uuid1())
39+
40+
41+
def cleanup_notification_config(notification_config_id):
42+
client = securitycenter.SecurityCenterClient()
43+
44+
notification_config_name = "organizations/{org_id}/notificationConfigs/{config_id}".format(
45+
org_id=ORG_ID, config_id=notification_config_id
46+
)
47+
client.delete_notification_config(notification_config_name)
48+
49+
50+
@pytest.fixture
51+
def new_notification_config_for_update():
52+
client = securitycenter.SecurityCenterClient()
53+
54+
org_name = "organizations/{org_id}".format(org_id=ORG_ID)
55+
56+
created_notification_config = client.create_notification_config(
57+
org_name,
58+
UPDATE_CONFIG_ID,
59+
{
60+
"description": "Notification for active findings",
61+
"pubsub_topic": PUBSUB_TOPIC,
62+
"event_type": NotificationConfig.FINDING,
63+
"streaming_config": {"filter": "",},
64+
},
65+
)
66+
yield created_notification_config
67+
cleanup_notification_config(UPDATE_CONFIG_ID)
68+
69+
70+
@pytest.fixture
71+
def new_notification_config_for_get():
72+
client = securitycenter.SecurityCenterClient()
73+
74+
org_name = "organizations/{org_id}".format(org_id=ORG_ID)
75+
76+
created_notification_config = client.create_notification_config(
77+
org_name,
78+
GET_CONFIG_ID,
79+
{
80+
"description": "Notification for active findings",
81+
"pubsub_topic": PUBSUB_TOPIC,
82+
"event_type": NotificationConfig.FINDING,
83+
"streaming_config": {"filter": "",},
84+
},
85+
)
86+
yield created_notification_config
87+
cleanup_notification_config(GET_CONFIG_ID)
88+
89+
90+
@pytest.fixture
91+
def deleted_notification_config():
92+
client = securitycenter.SecurityCenterClient()
93+
94+
org_name = "organizations/{org_id}".format(org_id=ORG_ID)
95+
96+
created_notification_config = client.create_notification_config(
97+
org_name,
98+
DELETE_CONFIG_ID,
99+
{
100+
"description": "Notification for active findings",
101+
"pubsub_topic": PUBSUB_TOPIC,
102+
"event_type": NotificationConfig.FINDING,
103+
"streaming_config": {"filter": "",},
104+
},
105+
)
106+
return created_notification_config
107+
108+
109+
def test_create_notification_config():
110+
created_notification_config = snippets_notification_configs.create_notification_config(
111+
ORG_ID, CREATE_CONFIG_ID, PUBSUB_TOPIC
112+
)
113+
assert created_notification_config is not None
114+
115+
cleanup_notification_config(CREATE_CONFIG_ID)
116+
117+
118+
def test_delete_notification_config(deleted_notification_config):
119+
assert (
120+
snippets_notification_configs.delete_notification_config(
121+
ORG_ID, DELETE_CONFIG_ID
122+
)
123+
== True
124+
)
125+
126+
127+
def test_get_notification_config(new_notification_config_for_get):
128+
retrieved_config = snippets_notification_configs.get_notification_config(
129+
ORG_ID, GET_CONFIG_ID
130+
)
131+
assert retrieved_config is not None
132+
133+
134+
def test_list_notification_configs():
135+
iterator = snippets_notification_configs.list_notification_configs(ORG_ID)
136+
assert iterator is not None
137+
138+
139+
def test_update_notification_config(new_notification_config_for_update):
140+
updated_config = snippets_notification_configs.update_notification_config(
141+
ORG_ID, UPDATE_CONFIG_ID, PUBSUB_TOPIC
142+
)
143+
assert updated_config is not None
144+
145+
146+
def test_receive_notifications():
147+
assert (
148+
snippets_notification_receiver.receive_notifications(
149+
PROJECT_ID, PUBSUB_SUBSCRIPTION
150+
)
151+
== True
152+
)

noxfile.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,26 @@ def snippets(session):
147147
session.env['GCLOUD_ORGANIZATION'] = '1081635000895'
148148
else:
149149
session.skip('Credentials must be set via environment variable.')
150+
if not os.environ.get('GCLOUD_PROJECT', ''):
151+
if 'KOKORO_GFILE_DIR' in os.environ:
152+
session.env['GCLOUD_PROJECT'] = 'project-a-id'
153+
else:
154+
session.skip('Credentials must be set via environment variable.')
155+
if not os.environ.get('GCLOUD_PUBSUB_TOPIC', ''):
156+
if 'KOKORO_GFILE_DIR' in os.environ:
157+
session.env['GCLOUD_PUBSUB_TOPIC'] = 'projects/project-a-id/topics/notifications-sample-topic'
158+
else:
159+
session.skip('Credentials must be set via environment variable.')
160+
if not os.environ.get('GCLOUD_PUBSUB_SUBSCRIPTION', ''):
161+
if 'KOKORO_GFILE_DIR' in os.environ:
162+
session.env['GCLOUD_PUBSUB_SUBSCRIPTION'] = 'notification_sample_subscription'
163+
else:
164+
session.skip('Credentials must be set via environment variable.')
150165

151166

152167
# Install all test dependencies, then install local packages in place.
153168
session.install('mock', 'pytest')
169+
session.install("-r", "docs/requirements.txt")
154170
session.install('-e', '.')
155171
session.run(
156172
'py.test',
@@ -160,6 +176,7 @@ def snippets(session):
160176
os.path.join('docs', 'snippets_orgs.py'),
161177
os.path.join('docs', 'snippets_findings.py'),
162178
os.path.join('docs', 'snippets_security_marks.py'),
179+
os.path.join('docs', 'v1p1beta1', 'snippets_test.py'),
163180

164181

165182
*session.posargs

0 commit comments

Comments
 (0)