Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gcp - add security policy resource, actions, docs #4537

Open
wants to merge 16 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
50 changes: 50 additions & 0 deletions tools/c7n_gcp/c7n_gcp/resources/loadbalancer.py
Expand Up @@ -11,6 +11,9 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import re

from c7n.utils import type_schema, local_session
from c7n_gcp.actions import MethodAction
from c7n_gcp.provider import resources
Expand Down Expand Up @@ -435,3 +438,50 @@ def get(client, resource_info):
return client.execute_command('get', {
'project': resource_info['project_id'],
'address': resource_info['resourceName'].rsplit('/', 1)[-1]})


@resources.register('loadbalancer-security-policy')
class LoadBalancingSecurityPolicy(QueryResourceManager):
"""GCP resource: https://cloud.google.com/compute/docs/reference/rest/v1/securityPolicies"""
class resource_type(TypeInfo):
service = 'compute'
version = 'v1'
component = 'securityPolicies'
id = 'name'

@staticmethod
def get(client, resource_info):
return client.execute_command(
'get', {'project': resource_info['project_id'],
'securityPolicy': resource_info['policy_name']})


@LoadBalancingSecurityPolicy.action_registry.register('delete')
class LoadBalancingSecurityPolicyDelete(MethodAction):
"""
`Deletes <https://cloud.google.com/compute/docs/reference/rest/v1/securityPolicies/delete>`_
a security policy

:Example:

.. code-block:: yaml

policies:
- name: security-policy-delete
description: Deletes a security policy
resource: gcp.loadbalancer-security-policy
filters:
- type: value
key: name
value: test-policy
actions:
- delete
"""

schema = type_schema('delete')
method_spec = {'op': 'delete'}
path_param_re = re.compile('.*?/projects/(.*?)/global/securityPolicies/(.*)')

def get_resource_params(self, m, r):
project, policy = self.path_param_re.match(r['selfLink']).groups()
return {'project': project, 'securityPolicy': policy}
35 changes: 35 additions & 0 deletions tools/c7n_gcp/tests/data/events/security-policy-insert.json
@@ -0,0 +1,35 @@
{
"protoPayload": {
"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
"authenticationInfo": {
"principalEmail": "alex.karpitski@gmail.com"
},
"requestMetadata": {
"callerIp": "86.57.255.90",
"callerSuppliedUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0,gzip(gfe)"
},
"serviceName": "compute.googleapis.com",
"methodName": "v1.compute.securityPolicies.insert",
"resourceName": "projects/cloud-custodian/global/securityPolicies/custodian-policy",
"request": {
"@type": "type.googleapis.com/compute.securityPolicies.insert"
}
},
"insertId": "lx87dgccpc",
"resource": {
"type": "network_security_policy",
"labels": {
"project_id": "cloud-custodian",
"policy_name": "custodian-policy"
}
},
"timestamp": "2019-06-10T10:57:35.441Z",
"severity": "NOTICE",
"logName": "projects/cloud-custodian/logs/cloudaudit.googleapis.com%2Factivity",
"operation": {
"id": "operation-1560164254035-58af60c272ca4-13cbcc67-cf2532c9",
"producer": "compute.googleapis.com",
"last": true
},
"receiveTimestamp": "2019-06-10T10:57:35.767352814Z"
}
Binary file not shown.
@@ -0,0 +1,33 @@
{
"body": {
"status": "RUNNING",
"kind": "compute#operation",
"name": "operation-1563970404502-58e6c3c664aba-dcd340d4-2b8ecd55",
"startTime": "2019-07-24T05:13:24.885-07:00",
"insertTime": "2019-07-24T05:13:24.871-07:00",
"targetId": "3190174424025658786",
"targetLink": "https://www.googleapis.com/compute/v1/projects/mitrop-custodian/global/securityPolicies/test-policy",
"operationType": "delete",
"progress": 0,
"id": "2914139019100419467",
"selfLink": "https://www.googleapis.com/compute/v1/projects/mitrop-custodian/global/operations/operation-1563970404502-58e6c3c664aba-dcd340d4-2b8ecd55",
"user": "test-sa@mitrop-custodian.iam.gserviceaccount.com"
},
"headers": {
"status": "200",
"content-length": "661",
"x-xss-protection": "1; mode=block",
"x-content-type-options": "nosniff",
"transfer-encoding": "chunked",
"expires": "Mon, 01 Jan 1990 00:00:00 GMT",
"vary": "Origin, X-Origin",
"server": "GSE",
"-content-encoding": "gzip",
"pragma": "no-cache",
"cache-control": "no-cache, no-store, max-age=0, must-revalidate",
"date": "Wed, 24 Jul 2019 12:13:25 GMT",
"x-frame-options": "SAMEORIGIN",
"alt-svc": "quic=\":443\"; ma=2592000; v=\"46,43,39\"",
"content-type": "application/json; charset=UTF-8"
}
}
@@ -0,0 +1,51 @@
{
"body": {
"items": [
{
"kind": "compute#securityPolicy",
"description": "",
"rules": [
{
"kind": "compute#securityPolicyRule",
"description": "Default rule, higher priority overrides it",
"priority": 2147483647,
"action": "deny(403)",
"preview": false,
"match": {
"config": {
"srcIpRanges": [
"*"
]
},
"versionedExpr": "SRC_IPS_V1"
}
}
],
"fingerprint": "Z24gwNyGiDY=",
"creationTimestamp": "2019-07-24T05:13:01.504-07:00",
"id": "3190174424025658786",
"selfLink": "https://www.googleapis.com/compute/v1/projects/mitrop-custodian/global/securityPolicies/test-policy",
"name": "test-policy"
}
],
"kind": "compute#securityPolicyList",
"id": "projects/mitrop-custodian/global/securityPolicies"
},
"headers": {
"status": "200",
"content-length": "921",
"x-xss-protection": "0",
"content-location": "https://www.googleapis.com/compute/v1/projects/mitrop-custodian/global/securityPolicies?alt=json",
"x-content-type-options": "nosniff",
"transfer-encoding": "chunked",
"vary": "Origin, X-Origin, Referer",
"server": "ESF",
"etag": "CXIqos5e5a090wyoB1lyJdqs9Zs=/iA-C-XdSyt7N5CakCj2oLwlGTlg=",
"cache-control": "private",
"date": "Wed, 24 Jul 2019 12:13:24 GMT",
"x-frame-options": "SAMEORIGIN",
"alt-svc": "quic=\":443\"; ma=2592000; v=\"46,43,39\"",
"content-type": "application/json; charset=UTF-8",
"-content-encoding": "gzip"
}
}
@@ -0,0 +1,23 @@
{
"body": {
"kind": "compute#securityPolicyList",
"id": "projects/mitrop-custodian/global/securityPolicies"
},
"headers": {
"status": "200",
"content-length": "104",
"x-xss-protection": "0",
"content-location": "https://www.googleapis.com/compute/v1/projects/mitrop-custodian/global/securityPolicies?filter=name+%3D+test-policy&alt=json",
"x-content-type-options": "nosniff",
"transfer-encoding": "chunked",
"vary": "Origin, X-Origin, Referer",
"server": "ESF",
"etag": "1pF9-Uuc-VC0-U23e2KnYPBZvoc=/o8NjldE3q2IFFwgqffOTF11N8nQ=",
"cache-control": "private",
"date": "Wed, 24 Jul 2019 12:13:30 GMT",
"x-frame-options": "SAMEORIGIN",
"alt-svc": "quic=\":443\"; ma=2592000; v=\"46,43,39\"",
"content-type": "application/json; charset=UTF-8",
"-content-encoding": "gzip"
}
}
@@ -0,0 +1,46 @@
{
"body": {
"kind": "compute#securityPolicy",
"description": "",
"rules": [
{
"kind": "compute#securityPolicyRule",
"description": "default rule",
"priority": 2147483647,
"action": "allow",
"preview": false,
"match": {
"config": {
"srcIpRanges": [
"*"
]
},
"versionedExpr": "SRC_IPS_V1"
}
}
],
"fingerprint": "FINvklB-_14=",
"creationTimestamp": "2019-06-10T03:57:34.426-07:00",
"id": "6573393147442989425",
"selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/global/securityPolicies/custodian-policy",
"name": "custodian-policy"
},
"headers": {
"status": "200",
"content-length": "615",
"transfer-encoding": "chunked",
"expires": "Mon, 10 Jun 2019 11:24:55 GMT",
"vary": "Origin, X-Origin",
"-content-encoding": "gzip",
"date": "Mon, 10 Jun 2019 11:24:55 GMT",
"x-xss-protection": "1; mode=block",
"content-location": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/global/securityPolicies/custodian-policy?alt=json",
"x-content-type-options": "nosniff",
"server": "GSE",
"etag": "\"-fYh9tEWdh96DhmWT6inupualOI=/zC3piU_l2E_owUxg9xVG1RQjb3A=\"",
"cache-control": "private, max-age=0, must-revalidate, no-transform",
"x-frame-options": "SAMEORIGIN",
"alt-svc": "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"",
"content-type": "application/json; charset=UTF-8"
}
}
@@ -0,0 +1,52 @@
{
"body": {
"items": [
{
"kind": "compute#securityPolicy",
"description": "",
"rules": [
{
"kind": "compute#securityPolicyRule",
"description": "default rule",
"priority": 2147483647,
"action": "allow",
"preview": false,
"match": {
"config": {
"srcIpRanges": [
"*"
]
},
"versionedExpr": "SRC_IPS_V1"
}
}
],
"fingerprint": "FINvklB-_14=",
"creationTimestamp": "2019-06-10T03:57:34.426-07:00",
"id": "6573393147442989425",
"selfLink": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/global/securityPolicies/custodian-policy",
"name": "custodian-policy"
}
],
"kind": "compute#securityPolicyList",
"id": "projects/cloud-custodian/global/securityPolicies"
},
"headers": {
"status": "200",
"content-length": "791",
"transfer-encoding": "chunked",
"expires": "Mon, 10 Jun 2019 10:57:48 GMT",
"vary": "Origin, X-Origin",
"-content-encoding": "gzip",
"date": "Mon, 10 Jun 2019 10:57:48 GMT",
"x-xss-protection": "1; mode=block",
"content-location": "https://www.googleapis.com/compute/v1/projects/cloud-custodian/global/securityPolicies?alt=json",
"x-content-type-options": "nosniff",
"server": "GSE",
"etag": "\"PeQw31vIyhRsGLdaDBrnw-R1GNc=/c8dugSi_JHBb02hjaAfNsQRe1mQ=\"",
"cache-control": "private, max-age=0, must-revalidate, no-transform",
"x-frame-options": "SAMEORIGIN",
"alt-svc": "quic=\":443\"; ma=2592000; v=\"46,44,43,39\"",
"content-type": "application/json; charset=UTF-8"
}
}
60 changes: 60 additions & 0 deletions tools/c7n_gcp/tests/test_loadbalancer.py
Expand Up @@ -672,3 +672,63 @@ def test_loadbalancer_global_address_get(self):
self.assertEqual(len(instances), 1)
self.assertEqual(instances[0]['kind'], 'compute#address')
self.assertEqual(instances[0]['name'], 'custodian-global-address-0')


class LoadBalancingSecurityPolicyTest(BaseTest):
def test_loadbalancer_security_policy_query(self):
project_id = 'cloud-custodian'
resource_name = 'custodian-policy'
session_factory = self.replay_flight_data(
'loadbalancer-security-policy-query', project_id=project_id)

policy = self.load_policy(
{'name': 'gcp-security-policy-dryrun',
'resource': 'gcp.loadbalancer-security-policy'},
session_factory=session_factory)
resources = policy.run()

self.assertEqual(resources[0]['name'], resource_name)

def test_loadbalancer_security_policy_get(self):
resource_name = 'custodian-policy'
session_factory = self.replay_flight_data(
'loadbalancer-security-policy-get')

policy = self.load_policy(
{'name': 'gcp-security-policy-audit',
'resource': 'gcp.loadbalancer-security-policy',
'mode': {
'type': 'gcp-audit',
'methods': ['v1.compute.securityPolicies.insert']
}},
session_factory=session_factory)

exec_mode = policy.get_execution_mode()
event = event_data('security-policy-insert.json')
resources = exec_mode.run(event, None)
self.assertEqual(resources[0]['name'], resource_name)

def test_loadbalancer_security_policy_delete(self):
project_id = 'mitrop-custodian'
factory = self.replay_flight_data('loadbalancer-security-policy-delete',
project_id=project_id)

p = self.load_policy(
{'name': 'gcp-security-policy-delete',
'resource': 'gcp.loadbalancer-security-policy',
'filters': [{'name': 'test-policy'}],
'actions': ['delete']},
session_factory=factory)

resources = p.run()
self.assertEqual(len(resources), 1)

if self.recording:
sleep(5)

client = p.resource_manager.get_client()
result = client.execute_query(
'list', {'project': project_id,
'filter': 'name = test-policy'})

self.assertEqual(result.get('items', []), [])