You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ab...@apache.org on 2013/10/03 23:16:07 UTC
[1/2] JCLOUDS-312. Add SecurityGroupExtension for GCE.
Updated Branches:
refs/heads/master 7295f34e5 -> 97c911ca3
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/FirewallApiLiveTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/FirewallApiLiveTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/FirewallApiLiveTest.java
index 8c550b7..ca18883 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/FirewallApiLiveTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/FirewallApiLiveTest.java
@@ -17,7 +17,6 @@
package org.jclouds.googlecomputeengine.features;
import static com.google.common.collect.Iterables.getOnlyElement;
-import static org.jclouds.googlecomputeengine.domain.Firewall.Rule.IPProtocol;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
@@ -28,6 +27,7 @@ import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
import org.jclouds.googlecomputeengine.options.FirewallOptions;
import org.jclouds.googlecomputeengine.options.ListOptions;
+import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
@@ -57,7 +57,7 @@ public class FirewallApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
FirewallOptions firewall = new FirewallOptions()
.addAllowedRule(
Firewall.Rule.builder()
- .IPProtocol(IPProtocol.TCP)
+ .IpProtocol(IpProtocol.TCP)
.addPort(22).build())
.addSourceRange("10.0.0.0/8")
.addSourceTag("tag1")
@@ -79,7 +79,7 @@ public class FirewallApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
.addTargetTag("tag2")
.allowedRules(ImmutableSet.of(
Firewall.Rule.builder()
- .IPProtocol(IPProtocol.TCP)
+ .IpProtocol(IpProtocol.TCP)
.addPort(23)
.build()));
@@ -96,11 +96,11 @@ public class FirewallApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
.network(getNetworkUrl(userProject.get(), FIREWALL_NETWORK_NAME))
.allowedRules(ImmutableSet.of(
Firewall.Rule.builder()
- .IPProtocol(IPProtocol.TCP)
+ .IpProtocol(IpProtocol.TCP)
.addPort(22)
.build(),
Firewall.Rule.builder()
- .IPProtocol(IPProtocol.TCP)
+ .IpProtocol(IpProtocol.TCP)
.addPort(23)
.build()))
.addSourceRange("10.0.0.0/8")
@@ -119,11 +119,11 @@ public class FirewallApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
.network(getNetworkUrl(userProject.get(), FIREWALL_NETWORK_NAME))
.allowedRules(ImmutableSet.of(
Firewall.Rule.builder()
- .IPProtocol(IPProtocol.TCP)
+ .IpProtocol(IpProtocol.TCP)
.addPort(22)
.build(),
Firewall.Rule.builder()
- .IPProtocol(IPProtocol.TCP)
+ .IpProtocol(IpProtocol.TCP)
.addPort(23)
.build()))
.addSourceRange("10.0.0.0/8")
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/functions/CreateNetworkIfNeededTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/functions/CreateNetworkIfNeededTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/functions/CreateNetworkIfNeededTest.java
new file mode 100644
index 0000000..4bbff5e
--- /dev/null
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/functions/CreateNetworkIfNeededTest.java
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.functions;
+
+import static com.google.common.base.Optional.fromNullable;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.testng.Assert.assertEquals;
+
+import java.net.URI;
+
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.domain.Network;
+import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
+import org.jclouds.googlecomputeengine.features.GlobalOperationApi;
+import org.jclouds.googlecomputeengine.features.NetworkApi;
+import org.jclouds.googlecomputeengine.predicates.GlobalOperationDonePredicate;
+import org.jclouds.http.HttpResponse;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Supplier;
+
+/**
+ * @author Andrew Bayer
+ */
+public class CreateNetworkIfNeededTest {
+
+ @Test
+ public void testApply() {
+ final GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
+ final NetworkApi nwApi = createMock(NetworkApi.class);
+ final GlobalOperationApi globalApi = createMock(GlobalOperationApi.class);
+
+ Network network = Network.builder().IPv4Range("0.0.0.0/0")
+ .id("abcd").name("this-network")
+ .selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/this-network"))
+ .build();
+
+ Operation createOp = createMock(Operation.class);
+
+ final Supplier<String> userProject = new Supplier<String>() {
+ @Override
+ public String get() {
+ return "myproject";
+ }
+ };
+
+ expect(api.getNetworkApiForProject(userProject.get())).andReturn(nwApi).atLeastOnce();
+ expect(api.getGlobalOperationApiForProject(userProject.get())).andReturn(globalApi).atLeastOnce();
+
+ expect(nwApi.createInIPv4Range("this-network", "0.0.0.0/0"))
+ .andReturn(createOp);
+ expect(globalApi.get("create-op")).andReturn(createOp);
+ expect(nwApi.get("this-network")).andReturn(network);
+
+ expect(createOp.getName()).andReturn("create-op");
+ expect(createOp.getStatus()).andReturn(Operation.Status.DONE);
+ expect(createOp.getHttpError()).andReturn(fromNullable((HttpResponse)null));
+ replay(api, nwApi, createOp, globalApi);
+
+ NetworkAndAddressRange input = new NetworkAndAddressRange("this-network", "0.0.0.0/0", null);
+
+ GlobalOperationDonePredicate pred = new GlobalOperationDonePredicate(api, userProject);
+
+ CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, userProject, pred, 100l, 100l);
+
+ assertEquals(creator.apply(input), network);
+
+ verify(api, nwApi, globalApi, createOp);
+ }
+
+ @Test
+ public void testApplyWithGateway() {
+ final GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
+ final NetworkApi nwApi = createMock(NetworkApi.class);
+ final GlobalOperationApi globalApi = createMock(GlobalOperationApi.class);
+
+ Network network = Network.builder().IPv4Range("0.0.0.0/0")
+ .id("abcd").name("this-network").gatewayIPv4("1.2.3.4")
+ .selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/this-network"))
+ .build();
+
+ Operation createOp = createMock(Operation.class);
+
+ final Supplier<String> userProject = new Supplier<String>() {
+ @Override
+ public String get() {
+ return "myproject";
+ }
+ };
+
+ expect(api.getNetworkApiForProject(userProject.get())).andReturn(nwApi).atLeastOnce();
+ expect(api.getGlobalOperationApiForProject(userProject.get())).andReturn(globalApi).atLeastOnce();
+
+ expect(nwApi.createInIPv4RangeWithGateway("this-network", "0.0.0.0/0", "1.2.3.4"))
+ .andReturn(createOp);
+ expect(globalApi.get("create-op")).andReturn(createOp);
+ expect(nwApi.get("this-network")).andReturn(network);
+
+ expect(createOp.getName()).andReturn("create-op");
+ expect(createOp.getStatus()).andReturn(Operation.Status.DONE);
+ expect(createOp.getHttpError()).andReturn(fromNullable((HttpResponse)null));
+ replay(api, nwApi, createOp, globalApi);
+
+ NetworkAndAddressRange input = new NetworkAndAddressRange("this-network", "0.0.0.0/0", "1.2.3.4");
+
+ GlobalOperationDonePredicate pred = new GlobalOperationDonePredicate(api, userProject);
+
+ CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, userProject, pred, 100l, 100l);
+
+ assertEquals(creator.apply(input), network);
+
+ verify(api, nwApi, globalApi, createOp);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseFirewallListTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseFirewallListTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseFirewallListTest.java
index a90f17b..1bbf753 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseFirewallListTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseFirewallListTest.java
@@ -26,6 +26,7 @@ import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.domain.ListPage;
import org.jclouds.googlecomputeengine.domain.Resource;
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineParseTest;
+import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
import com.google.common.collect.ImmutableSet;
@@ -61,7 +62,7 @@ public class ParseFirewallListTest extends BaseGoogleComputeEngineParseTest<List
".com/compute/v1beta15/projects/google/global/networks/default"))
.addSourceRange("0.0.0.0/0")
.addAllowed(Firewall.Rule.builder()
- .IPProtocol(Firewall.Rule.IPProtocol.TCP)
+ .IpProtocol(IpProtocol.TCP)
.addPort(22).build())
.build()
))
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseFirewallTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseFirewallTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseFirewallTest.java
index 187380f..49012fb 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseFirewallTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/parse/ParseFirewallTest.java
@@ -16,8 +16,6 @@
*/
package org.jclouds.googlecomputeengine.parse;
-import static org.jclouds.googlecomputeengine.domain.Firewall.Rule.IPProtocol;
-
import java.net.URI;
import javax.ws.rs.Consumes;
@@ -26,6 +24,7 @@ import javax.ws.rs.core.MediaType;
import org.jclouds.date.internal.SimpleDateFormatDateService;
import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineParseTest;
+import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
/**
@@ -51,13 +50,13 @@ public class ParseFirewallTest extends BaseGoogleComputeEngineParseTest<Firewall
.network(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/jclouds-test"))
.addSourceRange("10.0.0.0/8")
.addAllowed(Firewall.Rule.builder()
- .IPProtocol(IPProtocol.TCP)
+ .IpProtocol(IpProtocol.TCP)
.addPortRange(1, 65535).build())
.addAllowed(Firewall.Rule.builder()
- .IPProtocol(IPProtocol.UDP)
+ .IpProtocol(IpProtocol.UDP)
.addPortRange(1, 65535).build())
.addAllowed(Firewall.Rule.builder()
- .IPProtocol(IPProtocol.ICMP).build())
+ .IpProtocol(IpProtocol.ICMP).build())
.build();
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/predicates/NetworkFirewallPredicatesTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/predicates/NetworkFirewallPredicatesTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/predicates/NetworkFirewallPredicatesTest.java
new file mode 100644
index 0000000..a7c43f2
--- /dev/null
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/predicates/NetworkFirewallPredicatesTest.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.predicates;
+
+import static org.jclouds.googlecomputeengine.compute.functions.FirewallToIpPermissionTest.fwForTest;
+import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.equalsIpPermission;
+import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.hasPortRange;
+import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.hasProtocol;
+import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.hasSourceRange;
+import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.hasSourceTag;
+import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.providesIpPermission;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.Date;
+
+import org.jclouds.googlecomputeengine.domain.Firewall;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.Range;
+
+@Test(groups = "unit")
+public class NetworkFirewallPredicatesTest {
+
+ public static Firewall getFwForTestSourceTags() {
+ Firewall.Builder builder = Firewall.builder();
+
+ builder.network(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/jclouds-test"));
+ builder.selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/firewalls/jclouds-test"));
+ builder.addSourceTag("tag-1");
+ builder.addAllowed(Firewall.Rule.builder().IpProtocol(IpProtocol.TCP)
+ .addPortRange(1, 10).build());
+ builder.addAllowed(Firewall.Rule.builder().IpProtocol(IpProtocol.TCP)
+ .addPort(33).build());
+ builder.addAllowed(Firewall.Rule.builder().IpProtocol(IpProtocol.ICMP).build());
+ builder.id("abcd");
+ builder.creationTimestamp(new Date());
+ builder.name("jclouds-test");
+
+ return builder.build();
+ }
+
+ public static Firewall getFwForTestSourceTagsExact() {
+ Firewall.Builder builder = Firewall.builder();
+
+ builder.network(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/jclouds-test"));
+ builder.selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/firewalls/jclouds-test"));
+ builder.addSourceTag("tag-1");
+ builder.addAllowed(Firewall.Rule.builder().IpProtocol(IpProtocol.TCP)
+ .addPortRange(1, 10).build());
+ builder.id("abcd");
+ builder.creationTimestamp(new Date());
+ builder.name("jclouds-test");
+
+ return builder.build();
+ }
+
+ @Test
+ public void testHasProtocol() {
+ assertTrue(hasProtocol(IpProtocol.TCP).apply(fwForTest()),
+ "Firewall " + fwForTest() + " should contain a TCP rule.");
+ }
+
+ @Test
+ public void testHasProtocolFails() {
+ assertFalse(hasProtocol(IpProtocol.UDP).apply(fwForTest()),
+ "Firewall " + fwForTest() + " should NOT contain a UDP rule.");
+ }
+
+ @Test
+ public void testHasPortRange() {
+ assertTrue(hasPortRange(Range.closed(2, 9)).apply(fwForTest()),
+ "Firewall " + fwForTest() + " should contain the port range 2-9.");
+ }
+
+ @Test
+ public void testHasPortRangeFails() {
+ assertFalse(hasPortRange(Range.closed(11, 15)).apply(fwForTest()),
+ "Firewall " + fwForTest() + " should NOT contain the port range 11-15.");
+ }
+
+ @Test
+ public void testHasSourceTag() {
+ assertTrue(hasSourceTag("tag-1").apply(getFwForTestSourceTags()),
+ "Firewall " + getFwForTestSourceTags() + " should contain the source tag 'tag-1'.");
+ }
+
+ @Test
+ public void testHasSourceTagFails() {
+ assertFalse(hasSourceTag("tag-1").apply(fwForTest()),
+ "Firewall " + fwForTest() + " should NOT contain the source tag 'tag-1'.");
+ }
+
+ @Test
+ public void testHasSourceRange() {
+ assertTrue(hasSourceRange("0.0.0.0/0").apply(fwForTest()),
+ "Firewall " + fwForTest() + " should contain the source range '0.0.0.0/0'.");
+ }
+
+ @Test
+ public void testHasSourceRangeFails() {
+ assertFalse(hasSourceRange("0.0.0.0/0").apply(getFwForTestSourceTags()),
+ "Firewall " + getFwForTestSourceTags() + " should NOT contain the source range '0.0.0.0/0'.");
+ }
+
+ @Test
+ public void testEqualsIpPermission() {
+ IpPermission perm = IpPermission.builder().groupId("tag-1")
+ .fromPort(1).toPort(10).ipProtocol(IpProtocol.TCP).build();
+
+ assertTrue(equalsIpPermission(perm).apply(getFwForTestSourceTagsExact()),
+ "Firewall " + getFwForTestSourceTagsExact() + " should match IpPermission " + perm + " but does not.");
+ }
+
+ @Test
+ public void testEqualsIpPermissionFails() {
+ IpPermission perm = IpPermission.builder().groupId("tag-1")
+ .fromPort(1).toPort(10).ipProtocol(IpProtocol.TCP).build();
+
+ assertFalse(equalsIpPermission(perm).apply(getFwForTestSourceTags()),
+ "Firewall " + getFwForTestSourceTags() + " should not match IpPermission " + perm + " but does.");
+ }
+
+ @Test
+ public void testProvidesIpPermission() {
+ IpPermission perm = IpPermission.builder().groupId("tag-1")
+ .fromPort(1).toPort(10).ipProtocol(IpProtocol.TCP).build();
+
+ assertTrue(providesIpPermission(perm).apply(getFwForTestSourceTagsExact()),
+ "Firewall " + getFwForTestSourceTagsExact() + " should provide IpPermission " + perm + " but does not.");
+
+ assertTrue(providesIpPermission(perm).apply(getFwForTestSourceTags()),
+ "Firewall " + getFwForTestSourceTags() + " should inexactly provide IpPermission " + perm + " but does not.");
+ }
+
+ @Test
+ public void testProvidesIpPermissionFails() {
+ IpPermission perm = IpPermission.builder().groupId("tag-1")
+ .fromPort(1).toPort(10).ipProtocol(IpProtocol.TCP).build();
+
+ assertFalse(providesIpPermission(perm).apply(fwForTest()),
+ "Firewall " + fwForTest() + " should not provide IpPermission " + perm + " but does.");
+ }
+}
+
[2/2] git commit: JCLOUDS-312. Add SecurityGroupExtension for GCE.
Posted by ab...@apache.org.
JCLOUDS-312. Add SecurityGroupExtension for GCE.
Note - there is no GoogleComputEngineSecurityGroupExtensionExpectTest,
due to it being more or less redundant given that we're not making any
new API calls.
Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/commit/97c911ca
Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/tree/97c911ca
Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/diff/97c911ca
Branch: refs/heads/master
Commit: 97c911ca3807bb3c1772a5871f71ee626291df9d
Parents: 7295f34
Author: Andrew Bayer <an...@gmail.com>
Authored: Mon Sep 30 11:54:47 2013 -0700
Committer: Andrew Bayer <an...@gmail.com>
Committed: Tue Oct 1 14:50:55 2013 -0700
----------------------------------------------------------------------
google-compute-engine/pom.xml | 3 +
...GoogleComputeEngineServiceContextModule.java | 43 ++-
...ogleComputeEngineSecurityGroupExtension.java | 340 +++++++++++++++++++
.../functions/FirewallToIpPermission.java | 89 +++++
.../functions/NetworkToSecurityGroup.java | 84 +++++
.../compute/loaders/FindNetworkOrCreate.java | 65 ++++
...desWithGroupEncodedIntoNameThenAddToSet.java | 34 +-
.../config/GoogleComputeEngineParserModule.java | 5 +-
.../googlecomputeengine/domain/Firewall.java | 42 +--
.../googlecomputeengine/domain/Project.java | 2 +-
.../domain/internal/NetworkAndAddressRange.java | 91 +++++
.../functions/CreateNetworkIfNeeded.java | 101 ++++++
.../GlobalOperationDonePredicate.java | 2 +-
.../predicates/NetworkFirewallPredicates.java | 123 +++++++
...uteEngineSecurityGroupExtensionLiveTest.java | 31 ++
.../functions/FirewallToIpPermissionTest.java | 93 +++++
.../functions/NetworkToSecurityGroupTest.java | 94 +++++
.../loaders/FindNetworkOrCreateTest.java | 144 ++++++++
.../features/FirewallApiExpectTest.java | 8 +-
.../features/FirewallApiLiveTest.java | 14 +-
.../functions/CreateNetworkIfNeededTest.java | 133 ++++++++
.../parse/ParseFirewallListTest.java | 3 +-
.../parse/ParseFirewallTest.java | 9 +-
.../NetworkFirewallPredicatesTest.java | 162 +++++++++
24 files changed, 1641 insertions(+), 74 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/pom.xml
----------------------------------------------------------------------
diff --git a/google-compute-engine/pom.xml b/google-compute-engine/pom.xml
index 375192c..de8d759 100644
--- a/google-compute-engine/pom.xml
+++ b/google-compute-engine/pom.xml
@@ -114,6 +114,9 @@
<goal>test</goal>
</goals>
<configuration>
+ <includes>
+ <include>**/GoogleComputeEngineSecurityGroupExtensionLiveTest.java</include>
+ </includes>
<systemPropertyVariables>
<test.google-compute-engine.identity>${test.google-compute-engine.identity}
</test.google-compute-engine.identity>
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
index 1e3580b..b726f11 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/config/GoogleComputeEngineServiceContextModule.java
@@ -35,32 +35,43 @@ import org.jclouds.compute.ComputeServiceAdapter;
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
import org.jclouds.compute.domain.Hardware;
import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.SecurityGroup;
import org.jclouds.compute.extensions.ImageExtension;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
import org.jclouds.compute.options.TemplateOptions;
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
import org.jclouds.domain.Location;
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
import org.jclouds.googlecomputeengine.compute.GoogleComputeEngineService;
import org.jclouds.googlecomputeengine.compute.GoogleComputeEngineServiceAdapter;
+import org.jclouds.googlecomputeengine.compute.extensions.GoogleComputeEngineSecurityGroupExtension;
import org.jclouds.googlecomputeengine.compute.functions.BuildInstanceMetadata;
+import org.jclouds.googlecomputeengine.compute.functions.FirewallToIpPermission;
import org.jclouds.googlecomputeengine.compute.functions.GoogleComputeEngineImageToImage;
import org.jclouds.googlecomputeengine.compute.functions.InstanceInZoneToNodeMetadata;
import org.jclouds.googlecomputeengine.compute.functions.MachineTypeInZoneToHardware;
+import org.jclouds.googlecomputeengine.compute.functions.NetworkToSecurityGroup;
import org.jclouds.googlecomputeengine.compute.functions.OrphanedGroupsFromDeadNodes;
import org.jclouds.googlecomputeengine.compute.functions.RegionToLocation;
import org.jclouds.googlecomputeengine.compute.functions.ZoneToLocation;
+import org.jclouds.googlecomputeengine.compute.loaders.FindNetworkOrCreate;
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
import org.jclouds.googlecomputeengine.compute.predicates.AllNodesInGroupTerminated;
import org.jclouds.googlecomputeengine.compute.strategy.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
import org.jclouds.googlecomputeengine.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
import org.jclouds.googlecomputeengine.compute.strategy.UseNodeCredentialsButOverrideFromTemplate;
import org.jclouds.googlecomputeengine.config.UserProject;
+import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.domain.Image;
import org.jclouds.googlecomputeengine.domain.Instance;
import org.jclouds.googlecomputeengine.domain.InstanceInZone;
import org.jclouds.googlecomputeengine.domain.MachineTypeInZone;
+import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.domain.Region;
import org.jclouds.googlecomputeengine.domain.Zone;
+import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
+import org.jclouds.googlecomputeengine.functions.CreateNetworkIfNeeded;
+import org.jclouds.net.domain.IpPermission;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.rest.suppliers.MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier;
@@ -69,6 +80,9 @@ import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Injector;
import com.google.inject.Provides;
@@ -105,6 +119,12 @@ public class GoogleComputeEngineServiceContextModule
bind(new TypeLiteral<Function<Zone, Location>>() {})
.to(ZoneToLocation.class);
+ bind(new TypeLiteral<Function<Firewall, Iterable<IpPermission>>>() {})
+ .to(FirewallToIpPermission.class);
+
+ bind(new TypeLiteral<Function<Network, SecurityGroup>>() {})
+ .to(NetworkToSecurityGroup.class);
+
bind(new TypeLiteral<Function<TemplateOptions, ImmutableMap.Builder<String, String>>>() {})
.to(BuildInstanceMetadata.class);
@@ -121,6 +141,15 @@ public class GoogleComputeEngineServiceContextModule
bind(new TypeLiteral<Predicate<String>>() {}).to(AllNodesInGroupTerminated.class);
+ bind(new TypeLiteral<Function<NetworkAndAddressRange, Network>>() {})
+ .to(CreateNetworkIfNeeded.class);
+
+ bind(new TypeLiteral<CacheLoader<NetworkAndAddressRange, Network>>() {})
+ .to(FindNetworkOrCreate.class);
+
+ bind(new TypeLiteral<SecurityGroupExtension>() {})
+ .to(GoogleComputeEngineSecurityGroupExtension.class);
+
bind(PrioritizeCredentialsFromTemplate.class).to(UseNodeCredentialsButOverrideFromTemplate.class);
install(new LocationsFromComputeServiceAdapterModule<InstanceInZone, MachineTypeInZone, Image, Zone>() {});
@@ -131,7 +160,7 @@ public class GoogleComputeEngineServiceContextModule
@Singleton
@Memoized
public Supplier<Map<URI, ? extends org.jclouds.compute.domain.Image>> provideImagesMap(
- AtomicReference<AuthorizationException> authException,
+ AtomicReference <AuthorizationException> authException,
final Supplier<Set<? extends org.jclouds.compute.domain.Image>> images,
@Named(PROPERTY_SESSION_INTERVAL) long seconds) {
return MemoizedRetryOnTimeOutButNotOnAuthorizationExceptionSupplier.create(authException,
@@ -219,11 +248,23 @@ public class GoogleComputeEngineServiceContextModule
seconds, TimeUnit.SECONDS);
}
+ @Provides
+ @Singleton
+ protected LoadingCache<NetworkAndAddressRange, Network> networkMap(
+ CacheLoader<NetworkAndAddressRange, Network> in) {
+ return CacheBuilder.newBuilder().build(in);
+ }
+
@Override
protected Optional<ImageExtension> provideImageExtension(Injector i) {
return Optional.absent();
}
+ @Override
+ protected Optional<SecurityGroupExtension> provideSecurityGroupExtension(Injector i) {
+ return Optional.of(i.getInstance(SecurityGroupExtension.class));
+ }
+
@VisibleForTesting
public static final Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus =
ImmutableMap.<Instance.Status, NodeMetadata.Status>builder()
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java
new file mode 100644
index 0000000..2ceccef
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java
@@ -0,0 +1,340 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.compute.extensions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
+import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
+import static org.jclouds.googlecomputeengine.compute.strategy.CreateNodesWithGroupEncodedIntoNameThenAddToSet.DEFAULT_INTERNAL_NETWORK_RANGE;
+import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.equalsIpPermission;
+import static org.jclouds.googlecomputeengine.predicates.NetworkFirewallPredicates.providesIpPermission;
+import static org.jclouds.util.Predicates2.retry;
+
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.extensions.SecurityGroupExtension;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.domain.Location;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.config.UserProject;
+import org.jclouds.googlecomputeengine.domain.Firewall;
+import org.jclouds.googlecomputeengine.domain.Instance;
+import org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface;
+import org.jclouds.googlecomputeengine.domain.Network;
+import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.domain.SlashEncodedIds;
+import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
+import org.jclouds.googlecomputeengine.options.FirewallOptions;
+import org.jclouds.googlecomputeengine.options.ListOptions;
+import org.jclouds.googlecomputeengine.options.ListOptions.Builder;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Multimap;
+
+/**
+ * An extension to compute service to allow for the manipulation of {@link org.jclouds.compute.domain.SecurityGroup}s. Implementation
+ * is optional by providers.
+ *
+ * @author Andrew Bayer
+ */
+public class GoogleComputeEngineSecurityGroupExtension implements SecurityGroupExtension {
+
+ protected final Supplier<String> userProject;
+ protected final GroupNamingConvention.Factory namingConvention;
+ protected final LoadingCache<NetworkAndAddressRange, Network> networkCreator;
+ protected final Function<Network, SecurityGroup> groupConverter;
+ protected final GoogleComputeEngineApi api;
+ protected final Predicate<AtomicReference<Operation>> operationDonePredicate;
+ protected final long operationCompleteCheckInterval;
+ protected final long operationCompleteCheckTimeout;
+
+ @Inject
+ public GoogleComputeEngineSecurityGroupExtension(GoogleComputeEngineApi api,
+ @UserProject Supplier<String> userProject,
+ GroupNamingConvention.Factory namingConvention,
+ LoadingCache<NetworkAndAddressRange, Network> networkCreator,
+ Function<Network, SecurityGroup> groupConverter,
+ @Named("global") Predicate<AtomicReference<Operation>> operationDonePredicate,
+ @Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
+ @Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout) {
+ this.api = checkNotNull(api, "api");
+ this.userProject = checkNotNull(userProject, "userProject");
+ this.namingConvention = checkNotNull(namingConvention, "namingConvention");
+ this.networkCreator = checkNotNull(networkCreator, "networkCreator");
+ this.groupConverter = checkNotNull(groupConverter, "groupConverter");
+ this.operationCompleteCheckInterval = checkNotNull(operationCompleteCheckInterval,
+ "operation completed check interval");
+ this.operationCompleteCheckTimeout = checkNotNull(operationCompleteCheckTimeout,
+ "operation completed check timeout");
+ this.operationDonePredicate = operationDonePredicate;
+ }
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroups() {
+ return api.getNetworkApiForProject(userProject.get()).list().concat().transform(groupConverter).toSet();
+ }
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroupsInLocation(final Location location) {
+ return listSecurityGroups();
+ }
+
+ @Override
+ public Set<SecurityGroup> listSecurityGroupsForNode(String id) {
+ SlashEncodedIds slashEncodedIds = SlashEncodedIds.fromSlashEncoded(id);
+
+ Instance instance = api.getInstanceApiForProject(userProject.get()).getInZone(slashEncodedIds.getFirstId(),
+ slashEncodedIds.getSecondId());
+
+ if (instance == null) {
+ return ImmutableSet.of();
+ }
+
+ ImmutableSet.Builder builder = ImmutableSet.builder();
+
+
+ for (NetworkInterface nwInterface : instance.getNetworkInterfaces()) {
+ String networkUrl = nwInterface.getNetwork().getPath();
+ Network nw = api.getNetworkApiForProject(userProject.get()).get(networkUrl.substring(networkUrl.lastIndexOf('/') + 1));
+
+ SecurityGroup grp = groupForTagsInNetwork(nw, instance.getTags().getItems());
+ if (grp != null) {
+ builder.add(grp);
+ }
+ }
+
+ return builder.build();
+ }
+
+ @Override
+ public SecurityGroup getSecurityGroupById(String id) {
+ checkNotNull(id, "id");
+ Network network = api.getNetworkApiForProject(userProject.get()).get(id);
+
+ if (network == null) {
+ return null;
+ }
+
+ return groupConverter.apply(network);
+ }
+
+ @Override
+ public SecurityGroup createSecurityGroup(String name, Location location) {
+ return createSecurityGroup(name);
+ }
+
+ public SecurityGroup createSecurityGroup(String name) {
+ checkNotNull(name, "name");
+
+ NetworkAndAddressRange nAr = new NetworkAndAddressRange(name, DEFAULT_INTERNAL_NETWORK_RANGE, null);
+
+ Network nw = networkCreator.apply(nAr);
+
+ return groupConverter.apply(nw);
+ }
+
+ @Override
+ public boolean removeSecurityGroup(String id) {
+ checkNotNull(id, "id");
+ if (api.getNetworkApiForProject(userProject.get()).get(id) == null) {
+ return false;
+ }
+
+ ListOptions options = new ListOptions.Builder().filter("network eq .*/" + id);
+
+ FluentIterable<Firewall> fws = api.getFirewallApiForProject(userProject.get()).list(options).concat();
+
+ for (Firewall fw : fws) {
+ AtomicReference<Operation> operation = new AtomicReference<Operation>(api.getFirewallApiForProject(userProject.get())
+ .delete(fw.getName()));
+
+ retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
+ MILLISECONDS).apply(operation);
+
+ checkState(!operation.get().getHttpError().isPresent(), "Could not delete firewall, operation failed" + operation);
+ }
+
+ AtomicReference<Operation> operation = new AtomicReference<Operation>(
+ api.getNetworkApiForProject(userProject.get()).delete(id));
+
+ retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
+ MILLISECONDS).apply(operation);
+
+ checkState(!operation.get().getHttpError().isPresent(), "Could not create network, operation failed" + operation);
+
+ return true;
+ }
+
+ @Override
+ public SecurityGroup addIpPermission(IpPermission ipPermission, SecurityGroup group) {
+
+ if (api.getNetworkApiForProject(userProject.get()).get(group.getId()) == null) {
+ // Network corresponding to security group does not exist.
+ return null;
+ }
+
+ ListOptions options = new ListOptions.Builder().filter("network eq .*/" + group.getName());
+
+ if (api.getFirewallApiForProject(userProject.get()).list(options).concat().anyMatch(providesIpPermission(ipPermission))) {
+ // Permission already exists.
+ return group;
+ }
+
+ FirewallOptions fwOptions = new FirewallOptions();
+ String uniqueFwName = namingConvention.createWithoutPrefix().uniqueNameForGroup(group.getName());
+ fwOptions.name(uniqueFwName);
+ fwOptions.network(group.getUri());
+ if (ipPermission.getGroupIds().size() > 0) {
+ fwOptions.sourceTags(ipPermission.getGroupIds());
+ }
+ if (ipPermission.getCidrBlocks().size() > 0) {
+ fwOptions.sourceRanges(ipPermission.getCidrBlocks());
+ }
+ Firewall.Rule.Builder ruleBuilder = Firewall.Rule.builder();
+ ruleBuilder.IpProtocol(ipPermission.getIpProtocol());
+ if (ipPermission.getToPort() > 0) {
+ ruleBuilder.addPortRange(ipPermission.getFromPort(), ipPermission.getToPort());
+ }
+ fwOptions.addAllowedRule(ruleBuilder.build());
+
+ AtomicReference<Operation> operation = new AtomicReference<Operation>(api.getFirewallApiForProject(userProject
+ .get()).createInNetwork(
+ uniqueFwName,
+ group.getUri(),
+ fwOptions));
+
+ retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
+ MILLISECONDS).apply(operation);
+
+ checkState(!operation.get().getHttpError().isPresent(), "Could not create firewall, operation failed" + operation);
+
+ return getSecurityGroupById(group.getId());
+ }
+
+ @Override
+ public SecurityGroup addIpPermission(IpProtocol protocol, int startPort, int endPort,
+ Multimap<String,String> tenantIdGroupNamePairs, Iterable<String> ipRanges,
+ Iterable<String> groupIds, SecurityGroup group) {
+
+ IpPermission.Builder permBuilder = IpPermission.builder();
+ permBuilder.ipProtocol(protocol);
+ permBuilder.fromPort(startPort);
+ permBuilder.toPort(endPort);
+ permBuilder.groupIds(groupIds);
+ permBuilder.cidrBlocks(ipRanges);
+
+ return addIpPermission(permBuilder.build(), group);
+
+ }
+
+ @Override
+ public SecurityGroup removeIpPermission(IpPermission ipPermission, SecurityGroup group) {
+ if (api.getNetworkApiForProject(userProject.get()).get(group.getId()) == null) {
+ // Network corresponding to security group does not exist.
+ return null;
+ }
+
+ ListOptions options = new ListOptions.Builder().filter("network eq .*/" + group.getName());
+
+ FluentIterable<Firewall> fws = api.getFirewallApiForProject(userProject.get()).list(options).concat();
+
+ for (Firewall fw : fws) {
+ if (equalsIpPermission(ipPermission).apply(fw)) {
+ AtomicReference<Operation> operation = new AtomicReference<Operation>(api.getFirewallApiForProject(userProject.get())
+ .delete(fw.getName()));
+
+ retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
+ MILLISECONDS).apply(operation);
+
+ checkState(!operation.get().getHttpError().isPresent(), "Could not delete firewall, operation failed" + operation);
+ }
+ }
+
+ return getSecurityGroupById(group.getId());
+ }
+
+ @Override
+ public SecurityGroup removeIpPermission(IpProtocol protocol, int startPort, int endPort,
+ Multimap<String,String> tenantIdGroupNamePairs, Iterable<String> ipRanges,
+ Iterable<String> groupIds, SecurityGroup group) {
+
+ IpPermission.Builder permBuilder = IpPermission.builder();
+ permBuilder.ipProtocol(protocol);
+ permBuilder.fromPort(startPort);
+ permBuilder.toPort(endPort);
+ permBuilder.groupIds(groupIds);
+ permBuilder.cidrBlocks(ipRanges);
+
+ return removeIpPermission(permBuilder.build(), group);
+
+ }
+
+ @Override
+ public boolean supportsTenantIdGroupNamePairs() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsTenantIdGroupIdPairs() {
+ return false;
+ }
+
+ @Override
+ public boolean supportsGroupIds() {
+ return true;
+ }
+
+ @Override
+ public boolean supportsPortRangesForGroups() {
+ return true;
+ }
+
+ private SecurityGroup groupForTagsInNetwork(Network nw, final Set <String> tags) {
+ ListOptions opts = new Builder().filter("network eq .*/" + nw.getName());
+ Set<Firewall> fws = api.getFirewallApiForProject(userProject.get()).list(opts).concat()
+ .filter(new Predicate<Firewall>() {
+ @Override
+ public boolean apply(final Firewall input) {
+ // If any of the targetTags on the firewall apply or the firewall has no target tags...
+ return Iterables.any(input.getTargetTags(), Predicates.in(tags))
+ || Predicates.equalTo(0).apply(input.getTargetTags().size());
+ }
+ }).toSet();
+
+ if (fws.size() > 0) {
+ return groupConverter.apply(nw);
+ }
+
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java
new file mode 100644
index 0000000..6ee86f9
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.compute.functions;
+
+import javax.annotation.Resource;
+import javax.inject.Named;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.googlecomputeengine.domain.Firewall;
+import org.jclouds.googlecomputeengine.domain.Firewall.Rule;
+import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Range;
+
+/**
+ * A function for transforming a GCE-specific Firewall into a generic
+ * IpPermission object.
+ *
+ * @author Andrew Bayer
+ */
+public class FirewallToIpPermission implements Function<Firewall, Iterable<IpPermission>> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ public FirewallToIpPermission() {
+ }
+
+
+ @Override
+ public Iterable<IpPermission> apply(Firewall fw) {
+ ImmutableSet.Builder setBuilder = ImmutableSet.builder();
+
+ for (Rule rule: fw.getAllowed()) {
+ if (!rule.getPorts().isEmpty()) {
+ for (Range<Integer> r : rule.getPorts().asRanges()) {
+ IpPermission.Builder builder = populateBuilder(fw, rule.getIpProtocol());
+ builder.fromPort(r.lowerEndpoint());
+ builder.toPort(r.upperEndpoint());
+ setBuilder.add(builder.build());
+ }
+ } else {
+ setBuilder.add(populateBuilder(fw, rule.getIpProtocol()).build());
+ }
+ }
+
+ return setBuilder.build();
+ }
+
+ /**
+ * Convenience method for populating common parts of the IpPermission.
+ * @param fw
+ * @param protocol
+ * @return a pre-populated builder.
+ */
+ private IpPermission.Builder populateBuilder(Firewall fw, IpProtocol protocol) {
+ IpPermission.Builder builder = IpPermission.builder();
+
+ builder.ipProtocol(protocol);
+
+ if (!fw.getSourceRanges().isEmpty()) {
+ builder.cidrBlocks(fw.getSourceRanges());
+ }
+ if (!fw.getSourceTags().isEmpty()) {
+ builder.groupIds(fw.getSourceTags());
+ }
+
+ return builder;
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
new file mode 100644
index 0000000..ad8a95c
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
@@ -0,0 +1,84 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.compute.functions;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.compute.domain.SecurityGroupBuilder;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.config.UserProject;
+import org.jclouds.googlecomputeengine.domain.Firewall;
+import org.jclouds.googlecomputeengine.domain.Network;
+import org.jclouds.googlecomputeengine.options.ListOptions;
+import org.jclouds.logging.Logger;
+import org.jclouds.net.domain.IpPermission;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * A function for transforming a GCE-specific Network into a generic
+ * SecurityGroup object.
+ *
+ * @author Andrew Bayer
+ */
+public class NetworkToSecurityGroup implements Function<Network, SecurityGroup> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ private final Function<Firewall, Iterable<IpPermission>> firewallToPerms;
+ private final GoogleComputeEngineApi api;
+ private final Supplier<String> project;
+
+ @Inject
+ public NetworkToSecurityGroup(Function<Firewall, Iterable<IpPermission>> firewallToPerms,
+ GoogleComputeEngineApi api,
+ @UserProject Supplier<String> project) {
+ this.firewallToPerms = firewallToPerms;
+ this.api = api;
+ this.project = project;
+ }
+
+ @Override
+ public SecurityGroup apply(Network network) {
+ SecurityGroupBuilder builder = new SecurityGroupBuilder();
+
+ builder.id(network.getName());
+ builder.providerId(network.getId());
+ builder.name(network.getName());
+ builder.uri(network.getSelfLink());
+
+ ImmutableSet.Builder permBuilder = ImmutableSet.builder();
+
+ ListOptions options = new ListOptions.Builder().filter("network eq .*/" + network.getName());
+
+ for (Firewall fw : api.getFirewallApiForProject(project.get()).list(options).concat()) {
+ permBuilder.addAll(firewallToPerms.apply(fw));
+ }
+
+ builder.ipPermissions(permBuilder.build());
+
+ return builder.build();
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreate.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreate.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreate.java
new file mode 100644
index 0000000..120448f
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreate.java
@@ -0,0 +1,65 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.compute.loaders;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.config.UserProject;
+import org.jclouds.googlecomputeengine.domain.Network;
+import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
+import org.jclouds.logging.Logger;
+
+import com.google.common.base.Function;
+import com.google.common.base.Supplier;
+import com.google.common.cache.CacheLoader;
+
+/**
+ * @author Andrew Bayer
+ */
+public class FindNetworkOrCreate extends CacheLoader<NetworkAndAddressRange, Network> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+ protected final GoogleComputeEngineApi api;
+ protected final Function<NetworkAndAddressRange, Network> networkCreator;
+ protected final Supplier<String> userProject;
+
+ @Inject
+ public FindNetworkOrCreate(GoogleComputeEngineApi api,
+ Function<NetworkAndAddressRange, Network> networkCreator,
+ @UserProject Supplier<String> userProject) {
+ this.api = checkNotNull(api, "api");
+ this.networkCreator = checkNotNull(networkCreator, "networkCreator");
+ this.userProject = checkNotNull(userProject, "userProject");
+ }
+
+ @Override
+ public Network load(NetworkAndAddressRange in) {
+ Network network = api.getNetworkApiForProject(userProject.get()).get(in.getName());
+ if (network != null) {
+ return network;
+ } else {
+ return networkCreator.apply(in);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
index 5380313..74059f9 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
@@ -45,10 +45,13 @@ import org.jclouds.googlecomputeengine.config.UserProject;
import org.jclouds.googlecomputeengine.domain.Firewall;
import org.jclouds.googlecomputeengine.domain.Network;
import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
import org.jclouds.googlecomputeengine.options.FirewallOptions;
+import org.jclouds.net.domain.IpProtocol;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
+import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.common.util.concurrent.ListenableFuture;
@@ -65,6 +68,7 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
private final GoogleComputeEngineApi api;
private final Supplier<String> userProject;
+ private final LoadingCache<NetworkAndAddressRange, Network> networkMap;
private final Predicate<AtomicReference<Operation>> operationDonePredicate;
private final long operationCompleteCheckInterval;
private final long operationCompleteCheckTimeout;
@@ -82,7 +86,8 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
@UserProject Supplier<String> userProject,
@Named("global") Predicate<AtomicReference<Operation>> operationDonePredicate,
@Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
- @Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout) {
+ @Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout,
+ LoadingCache<NetworkAndAddressRange, Network> networkMap) {
super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor,
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
@@ -93,6 +98,7 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
this.operationCompleteCheckTimeout = checkNotNull(operationCompleteCheckTimeout,
"operation completed check timeout");
this.operationDonePredicate = operationDonePredicate;
+ this.networkMap = checkNotNull(networkMap, "networkMap");
}
@Override
@@ -123,31 +129,13 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
String networkName = templateOptions.getNetworkName().or(sharedResourceName);
- // check if the network was previously created (cache???)
- Network network = api.getNetworkApiForProject(userProject.get()).get(networkName);
-
- if (network != null) {
- return network;
- } else if (templateOptions.getNetwork().isPresent()) {
- throw new IllegalArgumentException("requested network " + networkName + " does not exist");
- }
-
- AtomicReference<Operation> operation = new AtomicReference<Operation>(api.getNetworkApiForProject(userProject
- .get()).createInIPv4Range(sharedResourceName, DEFAULT_INTERNAL_NETWORK_RANGE));
- retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
- MILLISECONDS).apply(operation);
-
- checkState(!operation.get().getHttpError().isPresent(), "Could not create network, operation failed" + operation);
-
- return checkNotNull(api.getNetworkApiForProject(userProject.get()).get(sharedResourceName),
- "no network with name %s was found", sharedResourceName);
-
+ return networkMap.apply(new NetworkAndAddressRange(networkName, DEFAULT_INTERNAL_NETWORK_RANGE, null));
}
/**
* Tries to find if a firewall already exists for this group, if not it creates one.
*
- * @see org.jclouds.googlecomputeengine.features.FirewallAsyncApi#patch(String, org.jclouds.googlecomputeengine.options.FirewallOptions)
+ * @see org.jclouds.googlecomputeengine.features.FirewallApi#patch(String, org.jclouds.googlecomputeengine.options.FirewallOptions)
*/
private void getOrCreateFirewall(GoogleComputeEngineTemplateOptions templateOptions, Network network,
String sharedResourceName) {
@@ -161,9 +149,9 @@ public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
ImmutableSet.Builder<Firewall.Rule> rules = ImmutableSet.builder();
Firewall.Rule.Builder tcpRule = Firewall.Rule.builder();
- tcpRule.IPProtocol(Firewall.Rule.IPProtocol.TCP);
+ tcpRule.IpProtocol(IpProtocol.TCP);
Firewall.Rule.Builder udpRule = Firewall.Rule.builder();
- udpRule.IPProtocol(Firewall.Rule.IPProtocol.UDP);
+ udpRule.IpProtocol(IpProtocol.UDP);
for (Integer port : templateOptions.getInboundPorts()) {
tcpRule.addPort(port);
udpRule.addPort(port);
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineParserModule.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineParserModule.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineParserModule.java
index 1b3fbac..ef9d7d6 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineParserModule.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/config/GoogleComputeEngineParserModule.java
@@ -36,6 +36,7 @@ import org.jclouds.googlecomputeengine.domain.Project;
import org.jclouds.googlecomputeengine.options.FirewallOptions;
import org.jclouds.googlecomputeengine.options.RouteOptions;
import org.jclouds.json.config.GsonModule;
+import org.jclouds.net.domain.IpProtocol;
import org.jclouds.oauth.v2.domain.ClaimSet;
import org.jclouds.oauth.v2.domain.Header;
import org.jclouds.oauth.v2.json.ClaimSetTypeAdapter;
@@ -380,7 +381,7 @@ public class GoogleComputeEngineParserModule extends AbstractModule {
JsonParseException {
JsonObject rule = json.getAsJsonObject();
Rule.Builder builder = Rule.builder();
- builder.IPProtocol(Rule.IPProtocol.fromValue(rule.get("IPProtocol").getAsString()));
+ builder.IpProtocol(IpProtocol.fromValue(rule.get("IPProtocol").getAsString()));
if (rule.get("ports") != null) {
JsonArray ports = (JsonArray) rule.get("ports");
for (JsonElement port : ports) {
@@ -399,7 +400,7 @@ public class GoogleComputeEngineParserModule extends AbstractModule {
@Override
public JsonElement serialize(Firewall.Rule src, Type typeOfSrc, JsonSerializationContext context) {
JsonObject ruleObject = new JsonObject();
- ruleObject.addProperty("IPProtocol", src.getIPProtocol().value());
+ ruleObject.addProperty("IPProtocol", src.getIpProtocol().value());
if (src.getPorts() != null && !src.getPorts().isEmpty()) {
JsonArray ports = new JsonArray();
for (Range<Integer> range : src.getPorts().asRanges()) {
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Firewall.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Firewall.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Firewall.java
index 52d51ab..78874bc 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Firewall.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Firewall.java
@@ -28,6 +28,8 @@ import java.net.URI;
import java.util.Date;
import java.util.Set;
+import org.jclouds.net.domain.IpProtocol;
+
import com.google.common.annotations.Beta;
import com.google.common.base.Objects;
import com.google.common.collect.ImmutableSet;
@@ -245,32 +247,14 @@ public final class Firewall extends Resource {
*/
public static final class Rule {
- public enum IPProtocol {
-
- TCP, UDP, ICMP, UNKNOWN;
-
- public String value() {
- return name().toLowerCase();
- }
-
- @Override
- public String toString() {
- return value();
- }
-
- public static IPProtocol fromValue(String protocol) {
- return valueOf(protocol.toUpperCase());
- }
- }
-
- private final IPProtocol ipProtocol;
+ private final IpProtocol ipProtocol;
private final RangeSet<Integer> ports;
@ConstructorProperties({
- "IPProtocol", "ports"
+ "IpProtocol", "ports"
})
- private Rule(IPProtocol IPProtocol, RangeSet<Integer> ports) {
- this.ipProtocol = checkNotNull(IPProtocol);
+ private Rule(IpProtocol IpProtocol, RangeSet<Integer> ports) {
+ this.ipProtocol = checkNotNull(IpProtocol);
this.ports = ports == null ? TreeRangeSet.<Integer>create() : ports;
}
@@ -279,7 +263,7 @@ public final class Firewall extends Resource {
*
* @return this is the IP protocol that is allowed for this rule.
*/
- public IPProtocol getIPProtocol() {
+ public IpProtocol getIpProtocol() {
return ipProtocol;
}
@@ -320,7 +304,7 @@ public final class Firewall extends Resource {
*/
public Objects.ToStringHelper string() {
return toStringHelper(this)
- .add("IPProtocol", ipProtocol).add("ports", ports);
+ .add("IpProtocol", ipProtocol).add("ports", ports);
}
/**
@@ -341,14 +325,14 @@ public final class Firewall extends Resource {
public static final class Builder {
- private IPProtocol ipProtocol;
+ private IpProtocol ipProtocol;
private RangeSet<Integer> ports = TreeRangeSet.create();
/**
- * @see org.jclouds.googlecomputeengine.domain.Firewall.Rule#getIPProtocol()
+ * @see org.jclouds.googlecomputeengine.domain.Firewall.Rule#getIpProtocol()
*/
- public Builder IPProtocol(IPProtocol IPProtocol) {
- this.ipProtocol = IPProtocol;
+ public Builder IpProtocol(IpProtocol IpProtocol) {
+ this.ipProtocol = IpProtocol;
return this;
}
@@ -384,7 +368,7 @@ public final class Firewall extends Resource {
}
public Builder fromFirewallRule(Rule firewallRule) {
- return new Builder().IPProtocol(firewallRule.getIPProtocol()).ports(firewallRule.getPorts());
+ return new Builder().IpProtocol(firewallRule.getIpProtocol()).ports(firewallRule.getPorts());
}
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Project.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Project.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Project.java
index 0292c71..24a139a 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Project.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/Project.java
@@ -178,7 +178,7 @@ public class Project extends Resource {
"metric", "usage", "limit"
})
protected Quota(String metric, Double usage, Double limit) {
- this.metric = checkNotNull(metric, "metric");
+ this.metric = metric != null ? metric : "undefined";
this.usage = checkNotNull(usage, "usage");
this.limit = checkNotNull(limit, "limit");
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/internal/NetworkAndAddressRange.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/internal/NetworkAndAddressRange.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/internal/NetworkAndAddressRange.java
new file mode 100644
index 0000000..66fbd66
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/domain/internal/NetworkAndAddressRange.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.domain.internal;
+
+import static com.google.common.base.Objects.equal;
+import static com.google.common.base.Objects.toStringHelper;
+import static com.google.common.base.Optional.fromNullable;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.beans.ConstructorProperties;
+
+import org.jclouds.javax.annotation.Nullable;
+
+import com.google.common.base.Objects;
+import com.google.common.base.Objects.ToStringHelper;
+import com.google.common.base.Optional;
+
+/**
+ * Container for network, IPv4 range and optional gateway, for creation caching
+ */
+public class NetworkAndAddressRange {
+ protected final String name;
+ protected final String ipV4Range;
+ protected final Optional<String> gateway;
+
+ @ConstructorProperties({
+ "name", "ipV4Range", "gateway"
+ })
+ public NetworkAndAddressRange(String name, String ipV4Range, @Nullable String gateway) {
+ this.name = checkNotNull(name, "name");
+ this.ipV4Range = checkNotNull(ipV4Range, "ipV4Range");
+ this.gateway = fromNullable(gateway);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getIpV4Range() {
+ return ipV4Range;
+ }
+
+ @Nullable
+ public Optional<String> getGateway() {
+ return gateway;
+ }
+
+ @Override
+ public int hashCode() {
+ // We only do hashcode/equals on name.
+ // the ip v4 range and gateway are included for creation rather than caching.
+ return Objects.hashCode(name);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null || getClass() != obj.getClass()) return false;
+ NetworkAndAddressRange that = NetworkAndAddressRange.class.cast(obj);
+ return equal(this.name, that.name);
+ }
+
+ protected ToStringHelper string() {
+ return toStringHelper(this)
+ .omitNullValues()
+ .add("name", name)
+ .add("ipV4Range", ipV4Range)
+ .add("gateway", gateway.orNull());
+ }
+
+ @Override
+ public String toString() {
+ return string().toString();
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/CreateNetworkIfNeeded.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/CreateNetworkIfNeeded.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/CreateNetworkIfNeeded.java
new file mode 100644
index 0000000..09a4eee
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/functions/CreateNetworkIfNeeded.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.functions;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
+import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
+import static org.jclouds.util.Predicates2.retry;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.annotation.Resource;
+import javax.inject.Inject;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.config.UserProject;
+import org.jclouds.googlecomputeengine.domain.Network;
+import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
+import org.jclouds.logging.Logger;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Supplier;
+
+/**
+ * @author Andrew Bayer
+ */
+@Singleton
+public class CreateNetworkIfNeeded implements Function<NetworkAndAddressRange, Network> {
+ @Resource
+ @Named(ComputeServiceConstants.COMPUTE_LOGGER)
+ protected Logger logger = Logger.NULL;
+
+ protected final GoogleComputeEngineApi api;
+ protected final Supplier<String> userProject;
+ private final Predicate<AtomicReference<Operation>> operationDonePredicate;
+ private final long operationCompleteCheckInterval;
+ private final long operationCompleteCheckTimeout;
+
+ @Inject
+ public CreateNetworkIfNeeded(GoogleComputeEngineApi api,
+ @UserProject Supplier<String> userProject,
+ @Named("global") Predicate<AtomicReference<Operation>> operationDonePredicate,
+ @Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
+ @Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout) {
+ this.api = checkNotNull(api, "api");
+ this.userProject = checkNotNull(userProject, "userProject");
+ this.operationCompleteCheckInterval = checkNotNull(operationCompleteCheckInterval,
+ "operation completed check interval");
+ this.operationCompleteCheckTimeout = checkNotNull(operationCompleteCheckTimeout,
+ "operation completed check timeout");
+ this.operationDonePredicate = operationDonePredicate;
+ }
+
+ @Override
+ public Network apply(NetworkAndAddressRange input) {
+ checkNotNull(input, "input");
+
+ try {
+ if (input.getGateway().isPresent()) {
+ AtomicReference<Operation> operation = new AtomicReference<Operation>(api.getNetworkApiForProject(userProject
+ .get()).createInIPv4RangeWithGateway(input.getName(), input.getIpV4Range(), input.getGateway().get()));
+ retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
+ MILLISECONDS).apply(operation);
+
+ checkState(!operation.get().getHttpError().isPresent(), "Could not create network, operation failed" + operation);
+ } else {
+ AtomicReference<Operation> operation = new AtomicReference<Operation>(api.getNetworkApiForProject(userProject
+ .get()).createInIPv4Range(input.getName(), input.getIpV4Range()));
+ retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
+ MILLISECONDS).apply(operation);
+
+ checkState(!operation.get().getHttpError().isPresent(), "Could not create network, operation failed" + operation);
+ }
+ return checkNotNull(api.getNetworkApiForProject(userProject.get()).get(input.getName()),
+ "no network with name %s was found", input.getName());
+ } catch (IllegalStateException e) {
+ return api.getNetworkApiForProject(userProject.get()).get(input.getName());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/GlobalOperationDonePredicate.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/GlobalOperationDonePredicate.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/GlobalOperationDonePredicate.java
index abd2b4c..df96e4e 100644
--- a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/GlobalOperationDonePredicate.java
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/GlobalOperationDonePredicate.java
@@ -39,7 +39,7 @@ public class GlobalOperationDonePredicate implements Predicate<AtomicReference<O
private final Supplier<String> project;
@Inject
- GlobalOperationDonePredicate(GoogleComputeEngineApi api, @UserProject Supplier<String> project) {
+ public GlobalOperationDonePredicate(GoogleComputeEngineApi api, @UserProject Supplier<String> project) {
this.api = api;
this.project = project;
}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/NetworkFirewallPredicates.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/NetworkFirewallPredicates.java b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/NetworkFirewallPredicates.java
new file mode 100644
index 0000000..e41536e
--- /dev/null
+++ b/google-compute-engine/src/main/java/org/jclouds/googlecomputeengine/predicates/NetworkFirewallPredicates.java
@@ -0,0 +1,123 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.predicates;
+
+import static com.google.common.collect.Collections2.transform;
+
+import org.jclouds.googlecomputeengine.domain.Firewall;
+import org.jclouds.googlecomputeengine.domain.Firewall.Rule;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Range;
+import com.google.common.collect.Sets;
+
+public class NetworkFirewallPredicates {
+
+ public static Predicate<Firewall> hasProtocol(final IpProtocol protocol) {
+ return new Predicate<Firewall>() {
+
+ @Override
+ public boolean apply(Firewall fw) {
+ return Predicates.in(transform(fw.getAllowed(), new Function<Rule, IpProtocol>() {
+ @Override
+ public IpProtocol apply(Rule input) {
+ return input.getIpProtocol();
+ }
+ })).apply(protocol);
+
+ }
+ };
+ }
+
+ public static Predicate<Firewall> hasPortRange(final Range<Integer> portRange) {
+ return new Predicate<Firewall>() {
+
+ @Override
+ public boolean apply(Firewall fw) {
+ return Iterables.any(fw.getAllowed(), new Predicate<Rule>() {
+ @Override
+ public boolean apply(Rule input) {
+ return input.getPorts().encloses(portRange);
+ }
+ });
+ }
+ };
+ }
+
+ public static Predicate<Firewall> hasSourceTag(final String sourceTag) {
+ return new Predicate<Firewall>() {
+ @Override
+ public boolean apply(Firewall input) {
+ return input.getSourceTags() != null && input.getSourceTags().contains(sourceTag);
+ }
+ };
+ }
+
+ public static Predicate<Firewall> hasSourceRange(final String sourceRange) {
+ return new Predicate<Firewall>() {
+ @Override
+ public boolean apply(Firewall input) {
+ return input.getSourceRanges() != null && input.getSourceRanges().contains(sourceRange);
+ }
+ };
+ }
+
+ public static Predicate<Firewall> equalsIpPermission(final IpPermission permission) {
+ return new Predicate<Firewall>() {
+ @Override
+ public boolean apply(Firewall input) {
+ return Iterables.elementsEqual(permission.getGroupIds(), input.getSourceTags())
+ && Iterables.elementsEqual(permission.getCidrBlocks(), input.getSourceRanges())
+ && (input.getAllowed().size() == 1
+ && ruleEqualsIpPermission(permission).apply(Iterables.getOnlyElement(input.getAllowed())));
+ }
+ };
+ }
+
+ public static Predicate<Firewall> providesIpPermission(final IpPermission permission) {
+ return new Predicate<Firewall>() {
+ @Override
+ public boolean apply(Firewall input) {
+ return ((permission.getGroupIds().size() == 0 && input.getSourceTags().size() == 0)
+ || Sets.intersection(permission.getGroupIds(), input.getSourceTags()).size() > 0)
+ && ((permission.getCidrBlocks().size() == 0 && input.getSourceRanges().size() == 0)
+ || Sets.intersection(permission.getCidrBlocks(), input.getSourceRanges()).size() > 0)
+ && hasProtocol(permission.getIpProtocol()).apply(input)
+ && ((permission.getFromPort() == 0 && permission.getToPort() == 0)
+ || hasPortRange(Range.closed(permission.getFromPort(), permission.getToPort())).apply(input));
+ }
+ };
+ }
+
+ private static Predicate<Firewall.Rule> ruleEqualsIpPermission(final IpPermission permission) {
+ return new Predicate<Rule>() {
+ @Override
+ public boolean apply(Firewall.Rule input) {
+ return permission.getIpProtocol().equals(input.getIpProtocol())
+ && ((input.getPorts().isEmpty() && permission.getFromPort() == 0 && permission.getToPort() == 0)
+ || (input.getPorts().asRanges().size() == 1
+ && permission.getFromPort() == Iterables.getOnlyElement(input.getPorts().asRanges()).lowerEndpoint()
+ && permission.getToPort() == Iterables.getOnlyElement(input.getPorts().asRanges()).upperEndpoint()));
+ }
+ };
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtensionLiveTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtensionLiveTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtensionLiveTest.java
new file mode 100644
index 0000000..6f0b4c6
--- /dev/null
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtensionLiveTest.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.compute.extensions;
+
+import org.jclouds.compute.extensions.internal.BaseSecurityGroupExtensionLiveTest;
+import org.testng.annotations.Test;
+
+/**
+ * @author Andrew Bayer
+ */
+@Test(groups = "live", singleThreaded = true, testName = "GoogleComputeEngineSecurityGroupExtensionLiveTest")
+public class GoogleComputeEngineSecurityGroupExtensionLiveTest extends BaseSecurityGroupExtensionLiveTest {
+
+ public GoogleComputeEngineSecurityGroupExtensionLiveTest() {
+ provider = "google-compute-engine";
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermissionTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermissionTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermissionTest.java
new file mode 100644
index 0000000..4970357
--- /dev/null
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermissionTest.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.compute.functions;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.Date;
+
+import org.jclouds.googlecomputeengine.domain.Firewall;
+import org.jclouds.net.domain.IpPermission;
+import org.jclouds.net.domain.IpProtocol;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+import com.google.common.collect.Iterables;
+
+public class FirewallToIpPermissionTest {
+
+ @Test
+ public void testApply() {
+
+ Firewall fw = fwForTest();
+
+ FirewallToIpPermission converter = new FirewallToIpPermission();
+
+ Iterable<IpPermission> perms = converter.apply(fw);
+
+ assertEquals(Iterables.size(perms), 3, "There should be three IpPermissions but there is only " + Iterables.size(perms));
+
+ assertTrue(Iterables.any(perms, Predicates.and(hasProtocol(IpProtocol.TCP),
+ hasStartAndEndPort(1, 10))), "No permission found for TCP, ports 1-10");
+ assertTrue(Iterables.any(perms, Predicates.and(hasProtocol(IpProtocol.TCP),
+ hasStartAndEndPort(33, 33))), "No permission found for TCP, port 33");
+ assertTrue(Iterables.any(perms, hasProtocol(IpProtocol.ICMP)),
+ "No permission found for ICMP");
+ }
+
+ public static Firewall fwForTest() {
+ Firewall.Builder builder = Firewall.builder();
+
+ builder.addSourceRange("0.0.0.0/0");
+ builder.addAllowed(Firewall.Rule.builder().IpProtocol(IpProtocol.TCP)
+ .addPortRange(1, 10).build());
+ builder.addAllowed(Firewall.Rule.builder().IpProtocol(IpProtocol.TCP)
+ .addPort(33).build());
+ builder.addAllowed(Firewall.Rule.builder().IpProtocol(IpProtocol.ICMP).build());
+ builder.id("abcd");
+ builder.selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/firewalls/jclouds-test"));
+ builder.network(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/jclouds-test"));
+ builder.creationTimestamp(new Date());
+ builder.name("jclouds-test");
+
+ return builder.build();
+ }
+
+ public static Predicate<IpPermission> hasProtocol(final IpProtocol protocol) {
+ return new Predicate<IpPermission>() {
+
+ @Override
+ public boolean apply(IpPermission perm) {
+ return protocol.equals(perm.getIpProtocol());
+ }
+ };
+ }
+
+ public static Predicate<IpPermission> hasStartAndEndPort(final int startPort, final int endPort) {
+ return new Predicate<IpPermission>() {
+
+ @Override
+ public boolean apply(IpPermission perm) {
+ return startPort == perm.getFromPort() && endPort == perm.getToPort();
+ }
+ };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroupTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroupTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroupTest.java
new file mode 100644
index 0000000..79a9da0
--- /dev/null
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroupTest.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.compute.functions;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.jclouds.googlecomputeengine.compute.functions.FirewallToIpPermissionTest.hasProtocol;
+import static org.jclouds.googlecomputeengine.compute.functions.FirewallToIpPermissionTest.hasStartAndEndPort;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.net.URI;
+import java.util.Date;
+
+import org.jclouds.collect.IterableWithMarkers;
+import org.jclouds.collect.PagedIterables;
+import org.jclouds.compute.domain.SecurityGroup;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.domain.Network;
+import org.jclouds.googlecomputeengine.features.FirewallApi;
+import org.jclouds.googlecomputeengine.options.ListOptions;
+import org.jclouds.googlecomputeengine.options.ListOptions.Builder;
+import org.jclouds.net.domain.IpProtocol;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Iterables;
+
+public class NetworkToSecurityGroupTest {
+
+ @Test
+ public void testApply() {
+ Supplier<String> projectSupplier = new Supplier<String>() {
+ @Override
+ public String get() {
+ return "myproject";
+ }
+ };
+
+ FirewallToIpPermission fwToPerm = new FirewallToIpPermission();
+
+ GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
+ FirewallApi fwApi = createMock(FirewallApi.class);
+
+ ListOptions options = new Builder().filter("network eq .*/jclouds-test");
+ expect(api.getFirewallApiForProject(projectSupplier.get()))
+ .andReturn(fwApi);
+ expect(fwApi.list(options)).andReturn(PagedIterables.of(IterableWithMarkers.from(ImmutableSet.of(FirewallToIpPermissionTest.fwForTest()))));
+
+ replay(api, fwApi);
+ Network.Builder builder = Network.builder();
+
+ builder.id("abcd");
+ builder.selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/jclouds-test"));
+ builder.creationTimestamp(new Date());
+ builder.description("some description");
+ builder.gatewayIPv4("1.2.3.4");
+ builder.IPv4Range("0.0.0.0/0");
+ builder.name("jclouds-test");
+
+ Network network = builder.build();
+
+ NetworkToSecurityGroup netToSg = new NetworkToSecurityGroup(fwToPerm, api, projectSupplier);
+
+ SecurityGroup group = netToSg.apply(network);
+
+ assertEquals(group.getId(), "jclouds-test");
+ assertEquals(group.getUri(), URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/jclouds-test"));
+ assertEquals(group.getIpPermissions().size(), 3);
+ assertTrue(Iterables.any(group.getIpPermissions(), Predicates.and(hasProtocol(IpProtocol.TCP),
+ hasStartAndEndPort(1, 10))), "No permission found for TCP, ports 1-10");
+ assertTrue(Iterables.any(group.getIpPermissions(), Predicates.and(hasProtocol(IpProtocol.TCP),
+ hasStartAndEndPort(33, 33))), "No permission found for TCP, port 33");
+ assertTrue(Iterables.any(group.getIpPermissions(), hasProtocol(IpProtocol.ICMP)),
+ "No permission found for ICMP");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreateTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreateTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreateTest.java
new file mode 100644
index 0000000..af384a5
--- /dev/null
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreateTest.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * 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.
+ */
+package org.jclouds.googlecomputeengine.compute.loaders;
+
+import static com.google.common.base.Optional.fromNullable;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.testng.Assert.assertEquals;
+
+import java.net.URI;
+
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.domain.Network;
+import org.jclouds.googlecomputeengine.domain.Operation;
+import org.jclouds.googlecomputeengine.domain.internal.NetworkAndAddressRange;
+import org.jclouds.googlecomputeengine.features.GlobalOperationApi;
+import org.jclouds.googlecomputeengine.features.NetworkApi;
+import org.jclouds.googlecomputeengine.functions.CreateNetworkIfNeeded;
+import org.jclouds.googlecomputeengine.predicates.GlobalOperationDonePredicate;
+import org.jclouds.http.HttpResponse;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Supplier;
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.LoadingCache;
+
+/**
+ * @author Andrew Bayer
+ */
+public class FindNetworkOrCreateTest {
+
+ @Test
+ public void testLoadExisting() {
+ final GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
+ final NetworkApi nwApi = createMock(NetworkApi.class);
+
+ Network network = Network.builder().IPv4Range("0.0.0.0/0")
+ .id("abcd").name("this-network")
+ .selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/this-network"))
+ .build();
+
+ final Supplier<String> userProject = new Supplier<String>() {
+ @Override
+ public String get() {
+ return "myproject";
+ }
+ };
+
+ expect(api.getNetworkApiForProject(userProject.get())).andReturn(nwApi).atLeastOnce();
+
+ expect(nwApi.get("this-network")).andReturn(network);
+
+ replay(api, nwApi);
+
+ NetworkAndAddressRange input = new NetworkAndAddressRange("this-network", "0.0.0.0/0", null);
+
+ GlobalOperationDonePredicate pred = new GlobalOperationDonePredicate(api, userProject);
+
+ CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, userProject, pred, 100l, 100l);
+
+ FindNetworkOrCreate loader = new FindNetworkOrCreate(api, creator, userProject);
+
+ LoadingCache<NetworkAndAddressRange, Network> cache = CacheBuilder.newBuilder().build(loader);
+
+ assertEquals(cache.getUnchecked(input), network);
+
+ // Second call is to ensure we only need to make the API calls once.
+ assertEquals(cache.getUnchecked(input), network);
+
+ verify(api, nwApi);
+ }
+
+ @Test
+ public void testLoadNew() {
+ final GoogleComputeEngineApi api = createMock(GoogleComputeEngineApi.class);
+ final NetworkApi nwApi = createMock(NetworkApi.class);
+ final GlobalOperationApi globalApi = createMock(GlobalOperationApi.class);
+
+ Network network = Network.builder().IPv4Range("0.0.0.0/0")
+ .id("abcd").name("this-network")
+ .selfLink(URI.create("https://www.googleapis.com/compute/v1beta15/projects/myproject/global/networks/this-network"))
+ .build();
+
+ Operation createOp = createMock(Operation.class);
+
+ final Supplier<String> userProject = new Supplier<String>() {
+ @Override
+ public String get() {
+ return "myproject";
+ }
+ };
+
+ expect(api.getNetworkApiForProject(userProject.get())).andReturn(nwApi).atLeastOnce();
+ expect(api.getGlobalOperationApiForProject(userProject.get())).andReturn(globalApi).atLeastOnce();
+
+ expect(nwApi.createInIPv4Range("this-network", "0.0.0.0/0"))
+ .andReturn(createOp);
+ expect(globalApi.get("create-op")).andReturn(createOp);
+ // pre-creation
+ expect(nwApi.get("this-network")).andReturn(null);
+ // post-creation
+ expect(nwApi.get("this-network")).andReturn(network);
+
+ expect(createOp.getName()).andReturn("create-op");
+ expect(createOp.getStatus()).andReturn(Operation.Status.DONE);
+ expect(createOp.getHttpError()).andReturn(fromNullable((HttpResponse)null));
+ replay(api, nwApi, createOp, globalApi);
+
+ NetworkAndAddressRange input = new NetworkAndAddressRange("this-network", "0.0.0.0/0", null);
+
+ GlobalOperationDonePredicate pred = new GlobalOperationDonePredicate(api, userProject);
+
+ CreateNetworkIfNeeded creator = new CreateNetworkIfNeeded(api, userProject, pred, 100l, 100l);
+
+ FindNetworkOrCreate loader = new FindNetworkOrCreate(api, creator, userProject);
+
+ LoadingCache<NetworkAndAddressRange, Network> cache = CacheBuilder.newBuilder().build(loader);
+
+ assertEquals(cache.getUnchecked(input), network);
+
+ // Second call is to ensure we only need to make the API calls once.
+ assertEquals(cache.getUnchecked(input), network);
+
+ verify(api, nwApi, globalApi, createOp);
+
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/incubator-jclouds-labs-google/blob/97c911ca/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/FirewallApiExpectTest.java
----------------------------------------------------------------------
diff --git a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/FirewallApiExpectTest.java b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/FirewallApiExpectTest.java
index 6345c51..6a20d28 100644
--- a/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/FirewallApiExpectTest.java
+++ b/google-compute-engine/src/test/java/org/jclouds/googlecomputeengine/features/FirewallApiExpectTest.java
@@ -21,7 +21,6 @@ import static com.google.common.collect.Iterables.transform;
import static java.lang.String.format;
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
-import static org.jclouds.googlecomputeengine.domain.Firewall.Rule.IPProtocol;
import static org.jclouds.io.Payloads.newStringPayload;
import static org.jclouds.util.Strings2.toStringAndClose;
import static org.testng.Assert.assertEquals;
@@ -43,6 +42,7 @@ import org.jclouds.googlecomputeengine.parse.ParseOperationTest;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.io.Payload;
+import org.jclouds.net.domain.IpProtocol;
import org.testng.annotations.Test;
import com.google.common.base.Function;
@@ -147,7 +147,7 @@ public class FirewallApiExpectTest extends BaseGoogleComputeEngineApiExpectTest
".com/compute/v1beta15/projects/myproject/global/networks/default"),
new FirewallOptions()
.addAllowedRule(Firewall.Rule.builder()
- .IPProtocol(IPProtocol.TCP)
+ .IpProtocol(IpProtocol.TCP)
.addPort(22)
.addPortRange(23, 24).build())
.addSourceTag("tag1")
@@ -185,7 +185,7 @@ public class FirewallApiExpectTest extends BaseGoogleComputeEngineApiExpectTest
.network(URI.create("https://www.googleapis" +
".com/compute/v1beta15/projects/myproject/global/networks/default"))
.addAllowedRule(Firewall.Rule.builder()
- .IPProtocol(IPProtocol.TCP)
+ .IpProtocol(IpProtocol.TCP)
.addPort(22)
.addPortRange(23, 24).build())
.addSourceTag("tag1")
@@ -222,7 +222,7 @@ public class FirewallApiExpectTest extends BaseGoogleComputeEngineApiExpectTest
.network(URI.create("https://www.googleapis" +
".com/compute/v1beta15/projects/myproject/global/networks/default"))
.addAllowedRule(Firewall.Rule.builder()
- .IPProtocol(IPProtocol.TCP)
+ .IpProtocol(IpProtocol.TCP)
.addPort(22)
.addPortRange(23, 24).build())
.addSourceTag("tag1")