You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by im...@apache.org on 2015/08/20 11:36:34 UTC
[48/51] [abbrv] [partial] stratos git commit: Revert "Upgrading to
jclouds 1.9.1"
http://git-wip-us.apache.org/repos/asf/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java
new file mode 100644
index 0000000..8d5a10c
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/extensions/GoogleComputeEngineSecurityGroupExtension.java
@@ -0,0 +1,342 @@
+/*
+ * 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;
+import com.google.common.util.concurrent.Atomics;
+
+/**
+ * An extension to compute service to allow for the manipulation of {@link org.jclouds.compute.domain.SecurityGroup}s. Implementation
+ * is optional by providers.
+ */
+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 = checkNotNull(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 = Atomics.newReference(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 = Atomics.newReference(
+ 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) {
+ checkNotNull(group, "group");
+ checkNotNull(ipPermission, "ipPermission");
+
+ checkNotNull(api.getNetworkApiForProject(userProject.get()).get(group.getId()) == null, "network for group is 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().isEmpty()) {
+ fwOptions.sourceTags(ipPermission.getGroupIds());
+ }
+ if (!ipPermission.getCidrBlocks().isEmpty()) {
+ fwOptions.sourceRanges(ipPermission.getCidrBlocks());
+ }
+ Firewall.Rule.Builder ruleBuilder = Firewall.Rule.builder();
+ ruleBuilder.IpProtocol(ipPermission.getIpProtocol());
+ if (ipPermission.getFromPort() > 0) {
+ if (ipPermission.getFromPort() == ipPermission.getToPort()) {
+ ruleBuilder.addPort(ipPermission.getToPort());
+ } else {
+ ruleBuilder.addPortRange(ipPermission.getFromPort(), ipPermission.getToPort());
+ }
+ }
+ fwOptions.addAllowedRule(ruleBuilder.build());
+
+ AtomicReference<Operation> operation = Atomics.newReference(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 fromPort, int toPort,
+ Multimap<String, String> tenantIdGroupNamePairs, Iterable<String> cidrBlocks,
+ Iterable<String> groupIds, SecurityGroup group) {
+
+ IpPermission.Builder permBuilder = IpPermission.builder();
+ permBuilder.ipProtocol(protocol);
+ permBuilder.fromPort(fromPort);
+ permBuilder.toPort(toPort);
+ permBuilder.groupIds(groupIds);
+ permBuilder.cidrBlocks(cidrBlocks);
+
+ return addIpPermission(permBuilder.build(), group);
+
+ }
+
+ @Override
+ public SecurityGroup removeIpPermission(IpPermission ipPermission, SecurityGroup group) {
+ checkNotNull(group, "group");
+ checkNotNull(ipPermission, "ipPermission");
+
+ checkNotNull(api.getNetworkApiForProject(userProject.get()).get(group.getId()) == null, "network for group is 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 = Atomics.newReference(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 fromPort, int toPort,
+ Multimap<String, String> tenantIdGroupNamePairs, Iterable<String> cidrBlocks,
+ Iterable<String> groupIds, SecurityGroup group) {
+
+ IpPermission.Builder permBuilder = IpPermission.builder();
+ permBuilder.ipProtocol(protocol);
+ permBuilder.fromPort(fromPort);
+ permBuilder.toPort(toPort);
+ permBuilder.groupIds(groupIds);
+ permBuilder.cidrBlocks(cidrBlocks);
+
+ 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.isEmpty()) {
+ return null;
+ }
+
+ return groupConverter.apply(nw);
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/BuildInstanceMetadata.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/BuildInstanceMetadata.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/BuildInstanceMetadata.java
new file mode 100644
index 0000000..80b18b1
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/BuildInstanceMetadata.java
@@ -0,0 +1,46 @@
+/*
+ * 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 com.google.common.base.Preconditions.checkNotNull;
+import static java.lang.String.format;
+
+import javax.inject.Singleton;
+
+import org.jclouds.compute.options.TemplateOptions;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Prepares metadata from the provided TemplateOptions
+ */
+@Singleton
+public class BuildInstanceMetadata implements Function<TemplateOptions, ImmutableMap.Builder<String, String>> {
+
+ @Override
+ public ImmutableMap.Builder apply(TemplateOptions input) {
+ ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
+ if (input.getPublicKey() != null) {
+ builder.put("sshKeys", format("%s:%s %s@localhost", checkNotNull(input.getLoginUser(),
+ "loginUser cannot be null"), input.getPublicKey(), input.getLoginUser()));
+ }
+ builder.putAll(input.getUserMetadata());
+ return builder;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallTagNamingConvention.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallTagNamingConvention.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallTagNamingConvention.java
new file mode 100644
index 0000000..1d2508b
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallTagNamingConvention.java
@@ -0,0 +1,62 @@
+/*
+ * 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 com.google.common.base.Predicate;
+import org.jclouds.compute.functions.GroupNamingConvention;
+
+import javax.inject.Inject;
+
+/**
+ * The convention for naming instance tags that firewall rules recognise.
+ */
+public class FirewallTagNamingConvention {
+
+ public static class Factory {
+
+ private final GroupNamingConvention.Factory namingConvention;
+
+ @Inject
+ public Factory(GroupNamingConvention.Factory namingConvention) {
+ this.namingConvention = namingConvention;
+ }
+
+ public FirewallTagNamingConvention get(String groupName) {
+ return new FirewallTagNamingConvention(namingConvention.create().sharedNameForGroup(groupName));
+ }
+ }
+
+ private final String sharedResourceName;
+
+ public FirewallTagNamingConvention(String sharedResourceName) {
+ this.sharedResourceName = sharedResourceName;
+ }
+
+ public String name(int port) {
+ return String.format("%s-port-%s", sharedResourceName, port);
+ }
+
+ public Predicate<? super String> isFirewallTag() {
+ return new Predicate<String>() {
+ @Override
+ public boolean apply(String input) {
+ return input != null && input.startsWith(sharedResourceName + "-port-");
+ }
+ };
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java
new file mode 100644
index 0000000..ea069e0
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/FirewallToIpPermission.java
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+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/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java
new file mode 100644
index 0000000..b783fc9
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/GoogleComputeEngineImageToImage.java
@@ -0,0 +1,80 @@
+/*
+ * 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 com.google.common.base.Joiner.on;
+import static com.google.common.collect.Iterables.getLast;
+import static com.google.common.collect.Iterables.limit;
+import static com.google.common.collect.Iterables.skip;
+import static org.jclouds.compute.domain.Image.Status;
+
+import java.util.List;
+
+import org.jclouds.compute.domain.ImageBuilder;
+import org.jclouds.compute.domain.OperatingSystem;
+import org.jclouds.compute.domain.OsFamily;
+import org.jclouds.googlecomputeengine.domain.Image;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+
+/**
+ * Transforms a google compute domain specific image to a generic Image object.
+ */
+public class GoogleComputeEngineImageToImage implements Function<Image, org.jclouds.compute.domain.Image> {
+
+
+ @Override
+ public org.jclouds.compute.domain.Image apply(Image image) {
+ ImageBuilder builder = new ImageBuilder()
+ .id(image.getName())
+ .name(image.getName())
+ .providerId(image.getId())
+ .description(image.getDescription().orNull())
+ .status(Status.AVAILABLE)
+ .uri(image.getSelfLink());
+
+ List<String> splits = Lists.newArrayList(image.getName().split("-"));
+ OperatingSystem.Builder osBuilder = defaultOperatingSystem(image);
+ if (splits == null || splits.size() == 0 || splits.size() < 3) {
+ return builder.operatingSystem(osBuilder.build()).build();
+ }
+
+ OsFamily family = OsFamily.fromValue(splits.get(0));
+ if (family != OsFamily.UNRECOGNIZED) {
+ osBuilder.family(family);
+ }
+
+ String version = on(".").join(limit(skip(splits, 1), splits.size() - 2));
+ osBuilder.version(version);
+
+ if (image.getDeprecated().isPresent()) {
+ builder.userMetadata(ImmutableMap.of("deprecatedState", image.getDeprecated().get().getState().orNull()));
+ }
+ builder.version(getLast(splits));
+ return builder.operatingSystem(osBuilder.build()).build();
+ }
+
+ private OperatingSystem.Builder defaultOperatingSystem(Image image) {
+ return OperatingSystem.builder()
+ .family(OsFamily.LINUX)
+ .is64Bit(true)
+ .description(image.getName());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadata.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadata.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadata.java
new file mode 100644
index 0000000..c1ddea1
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/InstanceInZoneToNodeMetadata.java
@@ -0,0 +1,150 @@
+/*
+ * 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 com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.compute.util.ComputeServiceUtils.groupFromMapOrName;
+import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_IMAGE_METADATA_KEY;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.NodeMetadataBuilder;
+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.Instance;
+import org.jclouds.googlecomputeengine.domain.InstanceInZone;
+import org.jclouds.googlecomputeengine.domain.SlashEncodedIds;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicates;
+import com.google.common.base.Supplier;
+import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableSet;
+
+/**
+ * Transforms a google compute domain Instance into a generic NodeMetatada object.
+ */
+public class InstanceInZoneToNodeMetadata implements Function<InstanceInZone, NodeMetadata> {
+
+ private final Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus;
+ private final GroupNamingConvention nodeNamingConvention;
+ private final Supplier<Map<URI, ? extends Image>> images;
+ private final Supplier<Map<URI, ? extends Hardware>> hardwares;
+ private final Supplier<Map<URI, ? extends Location>> locations;
+ private final FirewallTagNamingConvention.Factory firewallTagNamingConvention;
+ private final GoogleComputeEngineApi api;
+ private final Supplier<String> userProject;
+
+ @Inject
+ public InstanceInZoneToNodeMetadata(Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus,
+ GroupNamingConvention.Factory namingConvention,
+ @Memoized Supplier<Map<URI, ? extends Image>> images,
+ @Memoized Supplier<Map<URI, ? extends Hardware>> hardwares,
+ @Memoized Supplier<Map<URI, ? extends Location>> locations,
+ FirewallTagNamingConvention.Factory firewallTagNamingConvention,
+ GoogleComputeEngineApi api,
+ @UserProject Supplier<String> userProject) {
+ this.toPortableNodeStatus = toPortableNodeStatus;
+ this.nodeNamingConvention = namingConvention.createWithoutPrefix();
+ this.images = images;
+ this.hardwares = hardwares;
+ this.locations = locations;
+ this.firewallTagNamingConvention = checkNotNull(firewallTagNamingConvention, "firewallTagNamingConvention");
+ this.api = checkNotNull(api, "api");
+ this.userProject = checkNotNull(userProject, "userProject");
+ }
+
+ @Override
+ public NodeMetadata apply(InstanceInZone instanceInZone) {
+ Instance input = instanceInZone.getInstance();
+
+ String group = groupFromMapOrName(input.getMetadata().getItems(),
+ input.getName(), nodeNamingConvention);
+ FluentIterable<String> tags = FluentIterable.from(input.getTags().getItems());
+ if (group != null) {
+ tags = tags.filter(Predicates.not(firewallTagNamingConvention.get(group).isFirewallTag()));
+ }
+
+ NodeMetadataBuilder builder = new NodeMetadataBuilder();
+
+ builder.id(SlashEncodedIds.fromTwoIds(checkNotNull(locations.get().get(input.getZone()),
+ "location for %s", input.getZone())
+ .getId(), input.getName()).slashEncode())
+ .name(input.getName())
+ .providerId(input.getId())
+ .hostname(input.getName())
+ .location(checkNotNull(locations.get().get(input.getZone()), "location for %s", input.getZone()))
+ .hardware(hardwares.get().get(input.getMachineType()))
+ .status(toPortableNodeStatus.get(input.getStatus()))
+ .tags(tags)
+ .uri(input.getSelfLink())
+ .userMetadata(input.getMetadata().getItems())
+ .group(group)
+ .privateAddresses(collectPrivateAddresses(input))
+ .publicAddresses(collectPublicAddresses(input));
+
+ if (input.getMetadata().getItems().containsKey(GCE_IMAGE_METADATA_KEY)) {
+ try {
+ URI imageUri = URI.create(input.getMetadata().getItems()
+ .get(GCE_IMAGE_METADATA_KEY));
+
+ Map<URI, ? extends Image> imagesMap = images.get();
+
+ Image image = checkNotNull(imagesMap.get(imageUri),
+ "no image for %s. images: %s", imageUri,
+ imagesMap.values());
+ builder.imageId(image.getId());
+ } catch (IllegalArgumentException e) {
+ // Swallow any exception here - it just means we don't actually have a valid image URI, so we skip it.
+ }
+ }
+
+ return builder.build();
+ }
+
+ private Set<String> collectPrivateAddresses(Instance input) {
+ ImmutableSet.Builder<String> privateAddressesBuilder = ImmutableSet.builder();
+ for (Instance.NetworkInterface networkInterface : input.getNetworkInterfaces()) {
+ if (networkInterface.getNetworkIP().isPresent()) {
+ privateAddressesBuilder.add(networkInterface.getNetworkIP().get());
+ }
+ }
+ return privateAddressesBuilder.build();
+ }
+
+ private Set<String> collectPublicAddresses(Instance input) {
+ ImmutableSet.Builder<String> publicAddressesBuilder = ImmutableSet.builder();
+ for (Instance.NetworkInterface networkInterface : input.getNetworkInterfaces()) {
+ for (Instance.NetworkInterface.AccessConfig accessConfig : networkInterface.getAccessConfigs()) {
+ if (accessConfig.getNatIP().isPresent()) {
+ publicAddressesBuilder.add(accessConfig.getNatIP().get());
+ }
+ }
+ }
+ return publicAddressesBuilder.build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/MachineTypeInZoneToHardware.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/MachineTypeInZoneToHardware.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/MachineTypeInZoneToHardware.java
new file mode 100644
index 0000000..e12a4a3
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/MachineTypeInZoneToHardware.java
@@ -0,0 +1,95 @@
+/*
+ * 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 com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterables.filter;
+import static com.google.common.collect.Iterables.getOnlyElement;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.jclouds.collect.Memoized;
+import org.jclouds.compute.domain.Hardware;
+import org.jclouds.compute.domain.HardwareBuilder;
+import org.jclouds.compute.domain.Image;
+import org.jclouds.compute.domain.Processor;
+import org.jclouds.compute.domain.Volume;
+import org.jclouds.compute.domain.VolumeBuilder;
+import org.jclouds.domain.Location;
+import org.jclouds.googlecomputeengine.domain.MachineType;
+import org.jclouds.googlecomputeengine.domain.MachineTypeInZone;
+import org.jclouds.googlecomputeengine.domain.SlashEncodedIds;
+
+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.collect.ImmutableSet;
+import com.google.inject.Inject;
+
+/**
+ * Transforms a google compute domain specific machine type to a generic Hardware object.
+ */
+public class MachineTypeInZoneToHardware implements Function<MachineTypeInZone, Hardware> {
+
+ private final Supplier<Map<URI, ? extends Location>> locations;
+
+ @Inject
+ public MachineTypeInZoneToHardware(@Memoized Supplier<Map<URI, ? extends Location>> locations) {
+ this.locations = locations;
+ }
+
+ @Override
+ public Hardware apply(final MachineTypeInZone input) {
+ Iterable<? extends Location> zonesForMachineType = filter(locations.get().values(), new Predicate<Location>() {
+ @Override
+ public boolean apply(Location l) {
+ return l.getId().equals(input.getMachineType().getZone());
+ }
+ });
+
+ Location location = checkNotNull(getOnlyElement(zonesForMachineType),
+ "location for %s",
+ input.getMachineType().getZone());
+
+ return new HardwareBuilder()
+ .id(SlashEncodedIds.fromTwoIds(input.getMachineType().getZone(), input.getMachineType().getName()).slashEncode())
+ .location(location)
+ .name(input.getMachineType().getName())
+ .hypervisor("kvm")
+ .processor(new Processor(input.getMachineType().getGuestCpus(), 1.0))
+ .providerId(input.getMachineType().getId())
+ .ram(input.getMachineType().getMemoryMb())
+ .uri(input.getMachineType().getSelfLink())
+ .volumes(collectVolumes(input.getMachineType()))
+ .supportsImage(Predicates.<Image>alwaysTrue())
+ .build();
+ }
+
+ private Iterable<Volume> collectVolumes(MachineType input) {
+ ImmutableSet.Builder<Volume> volumes = ImmutableSet.builder();
+ for (MachineType.ScratchDisk disk : input.getScratchDisks()) {
+ volumes.add(new VolumeBuilder()
+ .type(Volume.Type.LOCAL)
+ .size(new Integer(disk.getDiskGb()).floatValue())
+ .bootDevice(true)
+ .durable(false).build());
+ }
+ return volumes.build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
new file mode 100644
index 0000000..1a9be54
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/NetworkToSecurityGroup.java
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+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/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/OrphanedGroupsFromDeadNodes.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/OrphanedGroupsFromDeadNodes.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/OrphanedGroupsFromDeadNodes.java
new file mode 100644
index 0000000..3301c8f
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/OrphanedGroupsFromDeadNodes.java
@@ -0,0 +1,57 @@
+/*
+ * 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 java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.domain.NodeMetadata;
+
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Sets;
+
+@Singleton
+public class OrphanedGroupsFromDeadNodes implements Function<Set<? extends NodeMetadata>, Set<String>> {
+
+ private final Predicate<String> isOrphanedGroupPredicate;
+
+ @Inject
+ public OrphanedGroupsFromDeadNodes(Predicate<String> isOrphanedGroupPredicate) {
+ this.isOrphanedGroupPredicate = isOrphanedGroupPredicate;
+ }
+
+
+ @Override
+ public Set<String> apply(Set<? extends NodeMetadata> deadNodes) {
+ Set<String> groups = Sets.newLinkedHashSet();
+ for (NodeMetadata deadNode : deadNodes) {
+ groups.add(deadNode.getGroup());
+ }
+ Set<String> orphanedGroups = Sets.newLinkedHashSet();
+ for (String group : groups) {
+ if (isOrphanedGroupPredicate.apply(group)) {
+ orphanedGroups.add(group);
+ }
+ }
+ return orphanedGroups;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/RegionToLocation.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/RegionToLocation.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/RegionToLocation.java
new file mode 100644
index 0000000..2f880de
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/RegionToLocation.java
@@ -0,0 +1,45 @@
+/*
+ * 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 com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GOOGLE_PROVIDER_LOCATION;
+
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LocationBuilder;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.googlecomputeengine.domain.Region;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Transforms a google compute domain specific region to a generic Region object.
+ */
+public class RegionToLocation implements Function<Region, Location> {
+
+ @Override
+ public Location apply(Region input) {
+ return new LocationBuilder()
+ .description(input.getDescription().orNull())
+ .metadata(ImmutableMap.of("selfLink", (Object) checkNotNull(input.getSelfLink(), "region URI")))
+ .id(input.getName())
+ .scope(LocationScope.REGION)
+ .parent(GOOGLE_PROVIDER_LOCATION)
+ .build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/ZoneToLocation.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/ZoneToLocation.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/ZoneToLocation.java
new file mode 100644
index 0000000..0dc1c78
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/functions/ZoneToLocation.java
@@ -0,0 +1,45 @@
+/*
+ * 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 com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GOOGLE_PROVIDER_LOCATION;
+
+import org.jclouds.domain.Location;
+import org.jclouds.domain.LocationBuilder;
+import org.jclouds.domain.LocationScope;
+import org.jclouds.googlecomputeengine.domain.Zone;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Transforms a google compute domain specific zone to a generic Zone object.
+ */
+public class ZoneToLocation implements Function<Zone, Location> {
+
+ @Override
+ public Location apply(Zone input) {
+ return new LocationBuilder()
+ .description(input.getDescription().orNull())
+ .metadata(ImmutableMap.of("selfLink", (Object) checkNotNull(input.getSelfLink(), "zone URI")))
+ .id(input.getName())
+ .scope(LocationScope.ZONE)
+ .parent(GOOGLE_PROVIDER_LOCATION)
+ .build();
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreate.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreate.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreate.java
new file mode 100644
index 0000000..2c84787
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/loaders/FindNetworkOrCreate.java
@@ -0,0 +1,62 @@
+/*
+ * 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;
+
+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/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/options/GoogleComputeEngineTemplateOptions.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/options/GoogleComputeEngineTemplateOptions.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/options/GoogleComputeEngineTemplateOptions.java
new file mode 100644
index 0000000..c6aad00
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/options/GoogleComputeEngineTemplateOptions.java
@@ -0,0 +1,382 @@
+/*
+ * 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.options;
+
+import static com.google.common.base.Optional.fromNullable;
+import static org.jclouds.googlecomputeengine.domain.Instance.ServiceAccount;
+
+import java.net.URI;
+import java.util.Map;
+import java.util.Set;
+
+import org.jclouds.compute.options.TemplateOptions;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.googlecomputeengine.domain.Instance;
+import org.jclouds.googlecomputeengine.domain.InstanceTemplate.PersistentDisk;
+import org.jclouds.scriptbuilder.domain.Statement;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
+
+/**
+ * Instance options specific to Google Compute Engine.
+ */
+public class GoogleComputeEngineTemplateOptions extends TemplateOptions {
+
+ private Optional<URI> network = Optional.absent();
+ private Optional<String> networkName = Optional.absent();
+ private Set<Instance.ServiceAccount> serviceAccounts = Sets.newLinkedHashSet();
+ private boolean enableNat = true;
+ private Set<PersistentDisk> disks = Sets.newLinkedHashSet();
+ private Optional<Long> bootDiskSize = Optional.absent();
+ private boolean keepBootDisk = false;
+
+ @Override
+ public GoogleComputeEngineTemplateOptions clone() {
+ GoogleComputeEngineTemplateOptions options = new GoogleComputeEngineTemplateOptions();
+ copyTo(options);
+ return options;
+ }
+
+ @Override
+ public void copyTo(TemplateOptions to) {
+ super.copyTo(to);
+ if (to instanceof GoogleComputeEngineTemplateOptions) {
+ GoogleComputeEngineTemplateOptions eTo = GoogleComputeEngineTemplateOptions.class.cast(to);
+ eTo.network(getNetwork().orNull());
+ eTo.serviceAccounts(getServiceAccounts());
+ eTo.enableNat(isEnableNat());
+ eTo.disks(getDisks());
+ eTo.keepBootDisk(shouldKeepBootDisk());
+ }
+ }
+
+ /**
+ * @deprecated See TemplateOptions#networks
+ * @see #getNetworkName()
+ */
+ @Deprecated
+ public GoogleComputeEngineTemplateOptions network(String networkName) {
+ return this.networks(networkName);
+ }
+
+ /**
+ * @see #getNetwork()
+ */
+ public GoogleComputeEngineTemplateOptions network(URI network) {
+ this.network = fromNullable(network);
+ return this;
+ }
+
+ /**
+ * @see #getServiceAccounts()
+ * @see ServiceAccount
+ */
+ public GoogleComputeEngineTemplateOptions addServiceAccount(ServiceAccount serviceAccout) {
+ this.serviceAccounts.add(serviceAccout);
+ return this;
+ }
+
+ /**
+ * @see #getServiceAccounts()
+ * @see ServiceAccount
+ */
+ public GoogleComputeEngineTemplateOptions serviceAccounts(Set<ServiceAccount> serviceAccounts) {
+ this.serviceAccounts = Sets.newLinkedHashSet(serviceAccounts);
+ return this;
+ }
+
+ /**
+ * @see #getDisks()
+ * @see org.jclouds.googlecomputeengine.domain.InstanceTemplate.PersistentDisk
+ */
+ public GoogleComputeEngineTemplateOptions addDisk(PersistentDisk disk) {
+ this.disks.add(disk);
+ return this;
+ }
+
+ /**
+ * @see #getDisks()
+ * @see org.jclouds.googlecomputeengine.domain.InstanceTemplate.PersistentDisk
+ */
+ public GoogleComputeEngineTemplateOptions disks(Set<PersistentDisk> disks) {
+ this.disks = Sets.newLinkedHashSet(disks);
+ return this;
+ }
+
+ /**
+ * @see #isEnableNat()
+ */
+ public GoogleComputeEngineTemplateOptions enableNat(boolean enableNat) {
+ this.enableNat = enableNat;
+ return this;
+ }
+
+ /**
+ * @see #getBootDiskSize()
+ */
+ public GoogleComputeEngineTemplateOptions bootDiskSize(Long bootDiskSize) {
+ this.bootDiskSize = fromNullable(bootDiskSize);
+ return this;
+ }
+
+ /**
+ * @see #shouldKeepBootDisk()
+ */
+ public GoogleComputeEngineTemplateOptions keepBootDisk(boolean keepBootDisk) {
+ this.keepBootDisk = keepBootDisk;
+ return this;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions blockOnPort(int port, int seconds) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.blockOnPort(port, seconds));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions inboundPorts(int... ports) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.inboundPorts(ports));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions authorizePublicKey(String publicKey) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.authorizePublicKey(publicKey));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions installPrivateKey(String privateKey) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.installPrivateKey(privateKey));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions blockUntilRunning(boolean blockUntilRunning) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.blockUntilRunning(blockUntilRunning));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions dontAuthorizePublicKey() {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.dontAuthorizePublicKey());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions nameTask(String name) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.nameTask(name));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions runAsRoot(boolean runAsRoot) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.runAsRoot(runAsRoot));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions runScript(Statement script) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.runScript(script));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions overrideLoginCredentials(LoginCredentials overridingCredentials) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.overrideLoginCredentials(overridingCredentials));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions overrideLoginPassword(String password) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.overrideLoginPassword(password));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions overrideLoginPrivateKey(String privateKey) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.overrideLoginPrivateKey(privateKey));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions overrideLoginUser(String loginUser) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.overrideLoginUser(loginUser));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions overrideAuthenticateSudo(boolean authenticateSudo) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.overrideAuthenticateSudo(authenticateSudo));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions userMetadata(Map<String, String> userMetadata) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.userMetadata(userMetadata));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions userMetadata(String key, String value) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.userMetadata(key, value));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions nodeNames(Iterable<String> nodeNames) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.nodeNames(nodeNames));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions networks(Iterable<String> networks) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.networks(networks));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions networks(String... networks) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.networks(networks));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions tags(Iterable<String> tags) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.tags(tags));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions wrapInInitScript(boolean wrapInInitScript) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.wrapInInitScript(wrapInInitScript));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions runScript(String script) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.runScript(script));
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GoogleComputeEngineTemplateOptions blockOnComplete(boolean blockOnComplete) {
+ return GoogleComputeEngineTemplateOptions.class.cast(super.blockOnComplete(blockOnComplete));
+ }
+
+ /**
+ * @return the ServiceAccounts to enable in the instances.
+ */
+ public Set<Instance.ServiceAccount> getServiceAccounts() {
+ return serviceAccounts;
+ }
+
+ /**
+ * @return the PersistentDisks for this instance.
+ */
+ public Set<PersistentDisk> getDisks() {
+ return disks;
+ }
+
+ /**
+ * @return the URI of an existing network the instances will be attached to. If no network URI or network name are
+ * provided a new network will be created for the project.
+ */
+ public Optional<URI> getNetwork() {
+ return network;
+ }
+
+ /**
+ * @return the name of an existing network the instances will be attached to, the network is assumed to belong to
+ * user's project. If no network URI network name are provided a new network will be created for the project.
+ * <b>Note that this is now pulling from the first element in the networks field from TemplateOptions.</b>
+ */
+ public Optional<String> getNetworkName() {
+ return fromNullable(Iterables.getFirst(getNetworks(), null));
+ }
+
+ /**
+ * @return whether an AccessConfig with Type ONE_TO_ONE_NAT should be enabled in the instances. When true
+ * instances will have a NAT address that will be publicly accessible.
+ */
+ public boolean isEnableNat() {
+ return enableNat;
+ }
+
+ /**
+ * @return the boot disk size, if specified. Defaults to 10gb.
+ */
+ public Optional<Long> getBootDiskSize() {
+ return bootDiskSize;
+ }
+
+ /**
+ * @return whether we should keep the boot disk around when deleting the instance. Defaults to false.
+ */
+ public boolean shouldKeepBootDisk() {
+ return keepBootDisk;
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/predicates/AllNodesInGroupTerminated.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/predicates/AllNodesInGroupTerminated.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/predicates/AllNodesInGroupTerminated.java
new file mode 100644
index 0000000..38066ba
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/predicates/AllNodesInGroupTerminated.java
@@ -0,0 +1,48 @@
+/*
+ * 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.predicates;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.collect.Iterables.all;
+import static com.google.common.collect.Sets.filter;
+import static org.jclouds.compute.predicates.NodePredicates.TERMINATED;
+import static org.jclouds.compute.predicates.NodePredicates.all;
+import static org.jclouds.compute.predicates.NodePredicates.inGroup;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.ComputeService;
+
+import com.google.common.base.Predicate;
+
+@Singleton
+public class AllNodesInGroupTerminated implements Predicate<String> {
+
+ private final ComputeService computeService;
+
+ @Inject
+ public AllNodesInGroupTerminated(ComputeService computeService) {
+ this.computeService = checkNotNull(computeService, "compute service");
+ }
+
+
+ @Override
+ public boolean apply(String groupName) {
+ return all(filter(computeService.listNodesDetailsMatching(all()), inGroup(groupName)), TERMINATED);
+ }
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
new file mode 100644
index 0000000..14af9cd
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/CreateNodesWithGroupEncodedIntoNameThenAddToSet.java
@@ -0,0 +1,183 @@
+/*
+ * 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.strategy;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.ImmutableSet.of;
+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.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.inject.Inject;
+import javax.inject.Named;
+
+import org.jclouds.Constants;
+import org.jclouds.compute.config.CustomizationResponse;
+import org.jclouds.compute.domain.NodeMetadata;
+import org.jclouds.compute.domain.Template;
+import org.jclouds.compute.functions.GroupNamingConvention;
+import org.jclouds.compute.reference.ComputeServiceConstants;
+import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
+import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
+import org.jclouds.compute.strategy.ListNodesStrategy;
+import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
+import org.jclouds.googlecomputeengine.compute.functions.FirewallTagNamingConvention;
+import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
+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.features.FirewallApi;
+import org.jclouds.googlecomputeengine.options.FirewallOptions;
+
+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.collect.Sets;
+import com.google.common.util.concurrent.Atomics;
+import com.google.common.util.concurrent.ListenableFuture;
+import com.google.common.util.concurrent.ListeningExecutorService;
+
+public class CreateNodesWithGroupEncodedIntoNameThenAddToSet extends
+ org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet {
+
+ public static final String EXTERIOR_RANGE = "0.0.0.0/0";
+ public static final String DEFAULT_INTERNAL_NETWORK_RANGE = "10.0.0.0/8";
+
+ 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;
+ private final FirewallTagNamingConvention.Factory firewallTagNamingConvention;
+
+ @Inject
+ protected CreateNodesWithGroupEncodedIntoNameThenAddToSet(
+ CreateNodeWithGroupEncodedIntoName addNodeWithGroupStrategy,
+ ListNodesStrategy listNodesStrategy,
+ GroupNamingConvention.Factory namingConvention,
+ @Named(Constants.PROPERTY_USER_THREADS)
+ ListeningExecutorService userExecutor,
+ CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory
+ customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
+ GoogleComputeEngineApi api,
+ @UserProject Supplier<String> userProject,
+ @Named("global") Predicate<AtomicReference<Operation>> operationDonePredicate,
+ @Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
+ @Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout,
+ LoadingCache<NetworkAndAddressRange, Network> networkMap,
+ FirewallTagNamingConvention.Factory firewallTagNamingConvention) {
+ super(addNodeWithGroupStrategy, listNodesStrategy, namingConvention, userExecutor,
+ customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
+
+ this.api = checkNotNull(api, "google compute api");
+ this.userProject = checkNotNull(userProject, "user project name");
+ this.operationCompleteCheckInterval = checkNotNull(operationCompleteCheckInterval,
+ "operation completed check interval");
+ this.operationCompleteCheckTimeout = checkNotNull(operationCompleteCheckTimeout,
+ "operation completed check timeout");
+ this.operationDonePredicate = checkNotNull(operationDonePredicate, "operationDonePredicate");
+ this.networkMap = checkNotNull(networkMap, "networkMap");
+ this.firewallTagNamingConvention = checkNotNull(firewallTagNamingConvention, "firewallTagNamingConvention");
+ }
+
+ @Override
+ public synchronized Map<?, ListenableFuture<Void>> execute(String group, int count,
+ Template template,
+ Set<NodeMetadata> goodNodes,
+ Map<NodeMetadata, Exception> badNodes,
+ Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
+
+ String sharedResourceName = namingConvention.create().sharedNameForGroup(group);
+ Template mutableTemplate = template.clone();
+ GoogleComputeEngineTemplateOptions templateOptions = GoogleComputeEngineTemplateOptions.class.cast(mutableTemplate
+ .getOptions());
+ assert template.getOptions().equals(templateOptions) : "options didn't clone properly";
+
+ // get or create the network and create a firewall with the users configuration
+ Network network = getOrCreateNetwork(templateOptions, sharedResourceName);
+ getOrCreateFirewalls(templateOptions, network, firewallTagNamingConvention.get(group));
+ templateOptions.network(network.getSelfLink());
+ templateOptions.userMetadata(ComputeServiceConstants.NODE_GROUP_KEY, group);
+
+ return super.execute(group, count, mutableTemplate, goodNodes, badNodes, customizationResponses);
+ }
+
+ /**
+ * Try and find a network either previously created by jclouds or user defined.
+ */
+ private Network getOrCreateNetwork(GoogleComputeEngineTemplateOptions templateOptions, String sharedResourceName) {
+
+ String networkName = templateOptions.getNetworkName().or(sharedResourceName);
+
+ return networkMap.apply(new NetworkAndAddressRange(networkName, DEFAULT_INTERNAL_NETWORK_RANGE, null));
+ }
+
+ /**
+ * Ensures that a firewall exists for every inbound port that the instance requests.
+ * <p>
+ * For each port, there must be a firewall with a name following the {@link FirewallTagNamingConvention},
+ * with a target tag also following the {@link FirewallTagNamingConvention}, which opens the requested port
+ * for all sources on both TCP and UDP protocols.
+ * @see org.jclouds.googlecomputeengine.features.FirewallApi#patch(String, org.jclouds.googlecomputeengine.options.FirewallOptions)
+ */
+ private void getOrCreateFirewalls(GoogleComputeEngineTemplateOptions templateOptions, Network network,
+ FirewallTagNamingConvention naming) {
+
+ String projectName = userProject.get();
+ FirewallApi firewallApi = api.getFirewallApiForProject(projectName);
+ Set<AtomicReference<Operation>> operations = Sets.newHashSet();
+
+ for (Integer port : templateOptions.getInboundPorts()) {
+ String name = naming.name(port);
+ Firewall firewall = firewallApi.get(name);
+ if (firewall == null) {
+ ImmutableSet<Firewall.Rule> rules = ImmutableSet.of(Firewall.Rule.permitTcpRule(port), Firewall.Rule.permitUdpRule(port));
+ FirewallOptions firewallOptions = new FirewallOptions()
+ .name(name)
+ .network(network.getSelfLink())
+ .allowedRules(rules)
+ .sourceTags(templateOptions.getTags())
+ .sourceRanges(of(DEFAULT_INTERNAL_NETWORK_RANGE, EXTERIOR_RANGE))
+ .targetTags(ImmutableSet.of(name));
+ AtomicReference<Operation> operation = Atomics.newReference(firewallApi.createInNetwork(
+ firewallOptions.getName(),
+ network.getSelfLink(),
+ firewallOptions));
+ operations.add(operation);
+ }
+ }
+
+ for (AtomicReference<Operation> operation : operations) {
+ retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
+ MILLISECONDS).apply(operation);
+ checkState(!operation.get().getHttpError().isPresent(),
+ "Could not create firewall, operation failed" + operation);
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/stratos/blob/b45ae00e/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/PopulateDefaultLoginCredentialsForImageStrategy.java
----------------------------------------------------------------------
diff --git a/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/PopulateDefaultLoginCredentialsForImageStrategy.java b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/PopulateDefaultLoginCredentialsForImageStrategy.java
new file mode 100644
index 0000000..082d9ed
--- /dev/null
+++ b/dependencies/jclouds/apis/gce/1.8.1-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/strategy/PopulateDefaultLoginCredentialsForImageStrategy.java
@@ -0,0 +1,69 @@
+/*
+ * 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.strategy;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
+
+import java.security.NoSuchAlgorithmException;
+import java.util.Map;
+
+import javax.annotation.PostConstruct;
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.jclouds.compute.domain.TemplateBuilderSpec;
+import org.jclouds.domain.LoginCredentials;
+import org.jclouds.ssh.internal.RsaSshKeyPairGenerator;
+
+import com.google.inject.Inject;
+
+@Singleton
+public class PopulateDefaultLoginCredentialsForImageStrategy implements
+ org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy {
+
+ private final TemplateBuilderSpec templateBuilder;
+ private final RsaSshKeyPairGenerator keyPairGenerator;
+ private String compoundKey;
+
+ @Inject
+ PopulateDefaultLoginCredentialsForImageStrategy(@Named(TEMPLATE) String templateSpec,
+ RsaSshKeyPairGenerator keyPairGenerator)
+ throws NoSuchAlgorithmException {
+ this.templateBuilder = TemplateBuilderSpec.parse(checkNotNull(templateSpec, "template builder spec"));
+ checkNotNull(templateBuilder.getLoginUser(), "template builder spec must provide a loginUser");
+ this.keyPairGenerator = checkNotNull(keyPairGenerator, "keypair generator");
+ }
+
+ @PostConstruct
+ private void generateKeys() {
+ Map<String, String> keys = keyPairGenerator.get();
+ // as we need to store both the pubk and the pk, store them separated by : (base64 does not contain that char)
+ compoundKey = String.format("%s:%s", checkNotNull(keys.get("public"), "public key cannot be null"),
+ checkNotNull(keys.get("private"), "private key cannot be null"));
+ }
+
+ @Override
+ public LoginCredentials apply(Object image) {
+ return LoginCredentials.builder()
+ .authenticateSudo(templateBuilder.getAuthenticateSudo() != null ?
+ templateBuilder.getAuthenticateSudo() : false)
+ .privateKey(compoundKey)
+ .user(templateBuilder.getLoginUser()).build();
+ }
+
+}