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

Add Snippets for working with Assets in Cloud Security Command Center. #4690

Merged
merged 13 commits into from
Mar 27, 2019
27 changes: 27 additions & 0 deletions .kokoro/presubmit/securitycenter-it.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Format: //devtools/kokoro/config/proto/build.proto
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is to configure running integration tests found in the google-cloud-clients directory. Is that the intent here, or is this just for samples?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was intending this to be for samples, is there a mechanism to do that, or is it just best effort?


# Configure the docker image for kokoro-trampoline.
env_vars: {
key: "TRAMPOLINE_IMAGE"
value: "gcr.io/cloud-devrel-kokoro-resources/java8"
}

env_vars: {
key: "INTEGRATION_TEST_ARGS"
value: "google-cloud-clients/google-cloud-pubsub"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this right?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Old, code, I've removed all configuration.

}

env_vars: {
key: "JOB_TYPE"
value: "integration"
}

env_vars: {
key: "GCLOUD_ORGANIZATION"
value: "1081635000895"
}

env_vars: {
key: "GOOGLE_APPLICATION_CREDENTIALS"
value: "keystore/73713_cscc_it_service_account"
}
4 changes: 4 additions & 0 deletions google-cloud-examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-spanner</artifactId>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-securitycenter</artifactId>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-speech</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
package com.google.cloud.examples.securitycenter.snippets;
emkornfield marked this conversation as resolved.
Show resolved Hide resolved


import static com.google.cloud.ServiceOptions.getDefaultProjectId;

import com.google.cloud.securitycenter.v1beta1.ListAssetsRequest;
import com.google.cloud.securitycenter.v1beta1.ListAssetsResponse.ListAssetsResult;
import com.google.cloud.securitycenter.v1beta1.OrganizationName;
import com.google.cloud.securitycenter.v1beta1.SecurityCenterClient;
import com.google.cloud.securitycenter.v1beta1.SecurityCenterClient.ListAssetsPagedResponse;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import org.threeten.bp.Duration;
import org.threeten.bp.Instant;
import org.threeten.bp.LocalDateTime;
import org.threeten.bp.ZoneId;
import org.threeten.bp.temporal.ChronoUnit;

/**
* Snippets for how to work with Assets in Cloud Security Command Center.
*/
public class AssetSnippets {

private final SecurityCenterClient securityCenterClient;
private final OrganizationName organizationName;

/**
* Filter that returns all projects in the organization
*/
// [START asset_resource_project_filter]
emkornfield marked this conversation as resolved.
Show resolved Hide resolved
public static final String PROJECT_ASSET_FILTERS =
"security_center_properties.resource_type=\"google.cloud.resourcemanager.Project\"";
// [END asset_resource_project_filter]


/**
* Create a new AssetSnippets object.
*
* @param client The client to use for contacting the service.
* @param organizationId The organization ID (this should be a numeric value, not the display name
* of the organization).
*/
public AssetSnippets(SecurityCenterClient client, String organizationId) {
this.securityCenterClient = client;
// [START name_from_id]
this.organizationName = OrganizationName.of(organizationId);
// [END name_from_id]
}

/**
* Lists assets for an organization given meeting <code>filter</code> as of a specific instant in
* time.
*
* @param filter The filter that assets must meet (e.g. {@link #PROJECT_ASSET_FILTERS}). If null,
* all assets in the organization are returned.
* @param asOf The instant in time to query for. If null, current time is assumed
*/

// [TARGET list_assets
emkornfield marked this conversation as resolved.
Show resolved Hide resolved
// [VARIABLE "filter"]
// [VARIABLE "as_of"]
// [START list_assets ]
emkornfield marked this conversation as resolved.
Show resolved Hide resolved
public ImmutableList<ListAssetsResult> listAssets(String filter,
Instant asOf) {
ListAssetsRequest.Builder request =
ListAssetsRequest.newBuilder().setParent(organizationName.toString());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I documented what you asked for

//
emkornfield marked this conversation as resolved.
Show resolved Hide resolved
if (filter != null) {
request.setFilter(filter);
}
// Limits assets returned to a particular point in time.
if (asOf != null) {
request.getReadTimeBuilder().setSeconds(asOf.getEpochSecond()).setNanos(asOf.getNano());
}
ListAssetsPagedResponse response = securityCenterClient.listAssets(request.build());

// This creates one list for all assets. If your organization has a large number of assets
// this can cause out of memory issues. You can process them batches by returning
// the Iterable returned response.iterateAll() directly.
return ImmutableList.copyOf(response.iterateAll());
}
// [END list_assets ]

/**
* Run and print results from common queries.
*/
void demoListAssets() {
// [ START demo_list_assets ] ]
emkornfield marked this conversation as resolved.
Show resolved Hide resolved
// This takes care of formatting the resource name appropriately from the id..

// Query for all currently existing assets
System.out.println("All Assets: " + listAssets(null, null));
// Query for all firewall rules with open HTTP ports as of now.
System.out.println("Project Assets (now): " + listAssets(
PROJECT_ASSET_FILTERS, null));
// Query for all firewall rules with open HTTP open HTTP ports as of a day ago.
System.out.println("Open HTTP Firewall Rules (1 day ago): " + listAssets(
PROJECT_ASSET_FILTERS,
Instant.now().minus(Duration.ofDays(1))));
// [ END demo_list_assets ] ]
}

/**
* Returns Assets and metadata about assets activity (e.g. added, removed, no change) between
* between
* <code>asOf.minus(timespan)</code> and <code>asOf</code>.
*
* @param timeSpan The time-range to compare assets over.
* @param filter The filter that assets must meet (e.g. {@link #PROJECT_ASSET_FILTERS}). If null,
* all assets in the organization are returned.
* @param asOf The instant in time to query for. If null, current time is assumed.
*/
public ImmutableList<ListAssetsResult> listAssetAndStatusChanges(Duration timeSpan, String filter,
Instant asOf) {
// [ START list_asset_changes ] ]
ListAssetsRequest.Builder request =
ListAssetsRequest.newBuilder().setParent(organizationName.toString());
request.getCompareDurationBuilder().setSeconds(timeSpan.getSeconds())
.setNanos(timeSpan.getNano());
//
if (filter != null) {
request.setFilter(filter);
}
// Limits assets returned to a particular point in time.
if (asOf != null) {
request.getReadTimeBuilder().setSeconds(asOf.getEpochSecond()).setNanos(asOf.getNano());
}

ListAssetsPagedResponse response = securityCenterClient.listAssets(request.build());

// This creates one list for all assets. If your organization has a large number of assets
// this can cause out of memory issues. You can process them batches by returning
// the Iterable returned response.iterateAll() directly.
return ImmutableList.copyOf(response.iterateAll());
// [ END list_asset_changes ] ]
}

/**
* Run and print demo outputs of different parameters for {@link #listAssetAndStatusChanges(Duration,
* String, Instant)}.
*/
void demoListAssetAndStatusChanges() {
// [ START demo_list_asset_changes ] ]
// List assets that are GCP Projects and their changes over the last day.
System.out.println(listAssetAndStatusChanges(Duration.ofDays(1), PROJECT_ASSET_FILTERS, null));

final LocalDateTime jan1 = LocalDateTime.of(2019, 1, 1, 0, 0);
final LocalDateTime dec1 = LocalDateTime.of(2018, 12, 1, 0, 0);
final Duration lastMonth = Duration.ofDays(ChronoUnit.DAYS.between(dec1, jan1));
// Query for GCE instances with the name including "Debia" and there changes over between Dec 1, 2019 and Jan 1, 2019 .
System.out.println(
"Project Changes between (between Dec 2019 and Jan 2019): " + listAssetAndStatusChanges(
lastMonth, /* filter (no filter applied) = */null,
jan1.atZone(ZoneId.of("Europe/Paris")).toInstant()));
// [ END demo_list_asset_changes ] ]
}

public static void main(String... args) throws IOException {
try (SecurityCenterClient client = SecurityCenterClient.create()) {
String org_id = System.getenv("ORGANIZATION_ID");
if (args.length > 0) {
org_id = args[0];
}
if (org_id == null) {
Preconditions.checkNotNull(org_id,
"Organization ID must either be set in the environment variable \"ORGANIZATION_ID\" or passed"
+ " as the first parameter to the program.");
}
AssetSnippets snippets = new AssetSnippets(client, org_id);
System.out.println("Project Assets:" + snippets.listAssets(PROJECT_ASSET_FILTERS, null));
System.out.println("Project Assets (changes as of a day ago): " + snippets
.listAssetAndStatusChanges(Duration.ofDays(1),
PROJECT_ASSET_FILTERS, null));
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.google.cloud.examples.securitycenter.snippets;
emkornfield marked this conversation as resolved.
Show resolved Hide resolved

import static com.google.cloud.ServiceOptions.getDefaultProjectId;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.MatcherAssert.assertThat;


import com.google.cloud.securitycenter.v1beta1.ListAssetsResponse.ListAssetsResult;
import com.google.cloud.securitycenter.v1beta1.SecurityCenterClient;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.threeten.bp.Duration;
import org.threeten.bp.Instant;
import org.threeten.bp.LocalDateTime;
import org.threeten.bp.ZoneOffset;

/** Smoke tests for {@link com.google.cloud.examples.securitycenter.snippets.AssetSnippets} */
public class ITAssetSnippets {

static SecurityCenterClient client;
static AssetSnippets snippets;

public static final Instant NOTHING_INSTANCE = LocalDateTime.of(2019, 1, 1, 0, 0).toInstant(ZoneOffset.UTC);
public static final Instant SOMETHING_INSTANCE = LocalDateTime.of(2019, 3, 14, 8, 0).toInstant(ZoneOffset.ofHours((-8)));

@BeforeClass
public static void beforeClass() throws IOException {
client = SecurityCenterClient.create();
snippets = new AssetSnippets(client, getOrganizationId());
}

@Test
public void mainRuns() throws IOException {
AssetSnippets.main(getOrganizationId());
}

@Test
public void demosRun() throws IOException {
snippets.demoListAssets();
snippets.demoListAssetAndStatusChanges();
}

@Test
public void testAllAssetsReturned() {
assertTrue(0 < snippets.listAssets(null, null).size() );
}

@Test
public void testBeforeDateNoAssetsReturned() {
assertTrue(
snippets.listAssets(null, NOTHING_INSTANCE)
.isEmpty());
}

@Test
public void testListAssetsNoFilterOrDate() {
assertTrue(59 >= snippets.listAssets(null, null).size());
}

@Test
public void testListAssetsWithFilterAndInstance() {
assertTrue(3 >= snippets.listAssets(AssetSnippets.PROJECT_ASSET_FILTERS, SOMETHING_INSTANCE).size());
}

@Test
public void testChangesReturnsValues() {
ImmutableList<ListAssetsResult> result = snippets.listAssetAndStatusChanges(Duration.ofDays(3), AssetSnippets.PROJECT_ASSET_FILTERS,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line seems a bit long. Also, it has extra white space.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Old code?

SOMETHING_INSTANCE);
assertTrue("Result: " + result.toString(), result.toString().contains("ADDED"));
assertTrue(3 >= result.size());
}

@AfterClass
public static void tearDown() {
client.close();
}

private static String getOrganizationId() {
return System.getenv("GCLOUD_ORGANIZATION");
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the extra white space.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Old code?


}