mirror of https://github.com/apache/jclouds.git
Merge pull request #1148 from dralves/gce-firewalls
gce - firewalls api
This commit is contained in:
commit
a9d335c6cc
|
@ -20,6 +20,7 @@ package org.jclouds.googlecompute;
|
|||
|
||||
import com.google.common.annotations.Beta;
|
||||
import org.jclouds.googlecompute.features.DiskApi;
|
||||
import org.jclouds.googlecompute.features.FirewallApi;
|
||||
import org.jclouds.googlecompute.features.KernelApi;
|
||||
import org.jclouds.googlecompute.features.MachineTypeApi;
|
||||
import org.jclouds.googlecompute.features.NetworkApi;
|
||||
|
@ -51,6 +52,15 @@ public interface GoogleComputeApi {
|
|||
@Path("/projects/{project}")
|
||||
DiskApi getDiskApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Firewall features
|
||||
*
|
||||
* @param projectName the name of the project
|
||||
*/
|
||||
@Delegate
|
||||
@Path("/projects/{project}")
|
||||
FirewallApi getFirewallApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Kernel features
|
||||
*
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.jclouds.googlecompute;
|
|||
|
||||
import com.google.common.annotations.Beta;
|
||||
import org.jclouds.googlecompute.features.DiskAsyncApi;
|
||||
import org.jclouds.googlecompute.features.FirewallAsyncApi;
|
||||
import org.jclouds.googlecompute.features.KernelAsyncApi;
|
||||
import org.jclouds.googlecompute.features.MachineTypeAsyncApi;
|
||||
import org.jclouds.googlecompute.features.NetworkAsyncApi;
|
||||
|
@ -31,6 +32,7 @@ import org.jclouds.rest.annotations.Delegate;
|
|||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to GoogleCompute via their REST API.
|
||||
* <p/>
|
||||
|
@ -50,6 +52,15 @@ public interface GoogleComputeAsyncApi {
|
|||
@Path("/projects/{project}")
|
||||
DiskAsyncApi getDiskApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Firewall features
|
||||
*
|
||||
* @param projectName the name of the project
|
||||
*/
|
||||
@Delegate
|
||||
@Path("/projects/{project}")
|
||||
FirewallAsyncApi getFirewallApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Kernel features
|
||||
*
|
||||
|
|
|
@ -21,6 +21,7 @@ package org.jclouds.googlecompute.config;
|
|||
|
||||
import com.google.common.collect.ForwardingMap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Range;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonDeserializationContext;
|
||||
import com.google.gson.JsonDeserializer;
|
||||
|
@ -32,6 +33,7 @@ import com.google.gson.JsonSerializationContext;
|
|||
import com.google.gson.JsonSerializer;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import org.jclouds.googlecompute.domain.Firewall;
|
||||
import org.jclouds.googlecompute.domain.Operation;
|
||||
import org.jclouds.googlecompute.domain.Project;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
|
@ -48,6 +50,8 @@ import java.util.Date;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jclouds.googlecompute.domain.Firewall.Rule;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
|
@ -61,13 +65,14 @@ public class GoogleComputeParserModule extends AbstractModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
public Map<Type, Object> provideCustomAdapterBindings() {
|
||||
return ImmutableMap.<Type, Object>of(
|
||||
Metadata.class, new MetadataTypeAdapter(),
|
||||
Operation.class, new OperationTypeAdapter(),
|
||||
Header.class, new HeaderTypeAdapter(),
|
||||
ClaimSet.class, new ClaimSetTypeAdapter(),
|
||||
Project.class, new ProjectTypeAdapter()
|
||||
);
|
||||
return new ImmutableMap.Builder<Type, Object>()
|
||||
.put(Metadata.class, new MetadataTypeAdapter())
|
||||
.put(Operation.class, new OperationTypeAdapter())
|
||||
.put(Header.class, new HeaderTypeAdapter())
|
||||
.put(ClaimSet.class, new ClaimSetTypeAdapter())
|
||||
.put(Project.class, new ProjectTypeAdapter())
|
||||
.put(Rule.class, new RuleTypeAdapter())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -188,4 +193,43 @@ public class GoogleComputeParserModule extends AbstractModule {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
private static class RuleTypeAdapter implements JsonDeserializer<Firewall.Rule>, JsonSerializer<Firewall.Rule> {
|
||||
|
||||
@Override
|
||||
public Firewall.Rule deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws
|
||||
JsonParseException {
|
||||
JsonObject rule = json.getAsJsonObject();
|
||||
Rule.Builder builder = Rule.builder();
|
||||
builder.IPProtocol(Rule.IPProtocol.fromValue(rule.get("IPProtocol").getAsString()));
|
||||
if (rule.get("ports") != null) {
|
||||
JsonArray ports = (JsonArray) rule.get("ports");
|
||||
for (JsonElement port : ports) {
|
||||
String portAsString = port.getAsString();
|
||||
if (portAsString.contains("-")) {
|
||||
String[] split = portAsString.split("-");
|
||||
builder.addPortRange(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
|
||||
} else {
|
||||
builder.addPort(Integer.parseInt(portAsString));
|
||||
}
|
||||
}
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(Firewall.Rule src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject ruleObject = new JsonObject();
|
||||
ruleObject.addProperty("IPProtocol", src.getIPProtocol().value());
|
||||
if (src.getPorts() != null && !src.getPorts().isEmpty()) {
|
||||
JsonArray ports = new JsonArray();
|
||||
for (Range<Integer> range : src.getPorts().asRanges()) {
|
||||
ports.add(new JsonPrimitive(range.lowerEndpoint() == range.upperEndpoint() ? range.lowerEndpoint() + "" :
|
||||
range.lowerEndpoint() + "-" + range.upperEndpoint()));
|
||||
}
|
||||
ruleObject.add("ports", ports);
|
||||
}
|
||||
return ruleObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@ import org.jclouds.googlecompute.GoogleComputeAsyncApi;
|
|||
import org.jclouds.googlecompute.domain.Operation;
|
||||
import org.jclouds.googlecompute.features.DiskApi;
|
||||
import org.jclouds.googlecompute.features.DiskAsyncApi;
|
||||
import org.jclouds.googlecompute.features.FirewallApi;
|
||||
import org.jclouds.googlecompute.features.FirewallAsyncApi;
|
||||
import org.jclouds.googlecompute.features.KernelApi;
|
||||
import org.jclouds.googlecompute.features.KernelAsyncApi;
|
||||
import org.jclouds.googlecompute.features.MachineTypeApi;
|
||||
|
@ -67,6 +69,7 @@ import static com.google.common.base.Preconditions.checkState;
|
|||
public class GoogleComputeRestClientModule extends RestClientModule<GoogleComputeApi, GoogleComputeAsyncApi> {
|
||||
public static final Map<Class<?>, Class<?>> DELEGATE_MAP = ImmutableMap.<Class<?>, Class<?>>builder()
|
||||
.put(DiskApi.class, DiskAsyncApi.class)
|
||||
.put(FirewallApi.class, FirewallAsyncApi.class)
|
||||
.put(KernelApi.class, KernelAsyncApi.class)
|
||||
.put(MachineTypeApi.class, MachineTypeAsyncApi.class)
|
||||
.put(NetworkApi.class, NetworkAsyncApi.class)
|
||||
|
|
|
@ -0,0 +1,394 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.googlecompute.domain;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.RangeSet;
|
||||
import com.google.common.collect.TreeRangeSet;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
|
||||
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 static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.collect.Range.closed;
|
||||
import static com.google.common.collect.Range.singleton;
|
||||
|
||||
/**
|
||||
* Represents a network firewall
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/firewalls"/>
|
||||
* @see <a href="https://developers.google.com/compute/docs/networking#firewalls"/>
|
||||
*/
|
||||
@Beta
|
||||
public final class Firewall extends Resource {
|
||||
|
||||
private final URI network;
|
||||
private final Set<String> sourceRanges;
|
||||
private final Set<String> sourceTags;
|
||||
private final Set<String> targetTags;
|
||||
private final Set<Rule> allowed;
|
||||
|
||||
@ConstructorProperties({
|
||||
"id", "creationTimestamp", "selfLink", "name", "description", "network", "sourceRanges",
|
||||
"sourceTags", "targetTags", "allowed"
|
||||
})
|
||||
protected Firewall(String id, Date creationTimestamp, URI selfLink, String name, String description,
|
||||
URI network, Set<String> sourceRanges, Set<String> sourceTags, Set<String> targetTags,
|
||||
Set<Rule> allowed) {
|
||||
super(Kind.FIREWALL, id, fromNullable(creationTimestamp), selfLink, checkNotNull(name, "name"),
|
||||
fromNullable(description));
|
||||
this.network = checkNotNull(network, "network of %s", name);
|
||||
this.sourceRanges = sourceRanges == null ? ImmutableSet.<String>of() : sourceRanges;
|
||||
this.sourceTags = sourceTags == null ? ImmutableSet.<String>of() : sourceTags;
|
||||
this.targetTags = targetTags == null ? ImmutableSet.<String>of() : targetTags;
|
||||
this.allowed = allowed == null ? ImmutableSet.<Rule>of() : allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return URI of the network to which this firewall is applied; provided by the client when the firewall is created.
|
||||
*/
|
||||
public URI getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
/**
|
||||
* One or both of sourceRanges and sourceTags may be set; an inbound connection is allowed if either the range or
|
||||
* the tag of the source matches.
|
||||
*
|
||||
* @return a list of IP address blocks expressed in CIDR format which this rule applies to.
|
||||
*/
|
||||
public Set<String> getSourceRanges() {
|
||||
return sourceRanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a list of instance tags which this rule applies to. One or both of sourceRanges and sourceTags may be
|
||||
* set; an inbound connection is allowed if either the range or the tag of the source matches.
|
||||
*/
|
||||
public Set<String> getSourceTags() {
|
||||
return sourceTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* If no targetTags are specified, the firewall rule applies to all instances on the specified network.
|
||||
*
|
||||
* @return a list of instance tags indicating sets of instances located on network which may make network
|
||||
* connections as specified in allowed.
|
||||
*/
|
||||
public Set<String> getTargetTags() {
|
||||
return targetTags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Each rule specifies a protocol and port-range tuple that describes a permitted connection.
|
||||
*
|
||||
* @return the list of rules specified by this firewall.
|
||||
*/
|
||||
public Set<Rule> getAllowed() {
|
||||
return allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
return super.string()
|
||||
.add("network", network).add("sourceRanges", sourceRanges).add("sourceTags",
|
||||
sourceTags).add("targetTags", targetTags).add("allowed", allowed);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return new Builder().fromFirewall(this);
|
||||
}
|
||||
|
||||
public static final class Builder extends Resource.Builder<Builder> {
|
||||
|
||||
private URI network;
|
||||
private ImmutableSet.Builder<String> sourceRanges = ImmutableSet.builder();
|
||||
private ImmutableSet.Builder<String> sourceTags = ImmutableSet.builder();
|
||||
private ImmutableSet.Builder<String> targetTags = ImmutableSet.builder();
|
||||
private ImmutableSet.Builder<Rule> allowed = ImmutableSet.builder();
|
||||
|
||||
/**
|
||||
* @see Firewall#getNetwork()
|
||||
*/
|
||||
public Builder network(URI network) {
|
||||
this.network = network;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Firewall#getSourceRanges()
|
||||
*/
|
||||
public Builder addSourceRange(String sourceRange) {
|
||||
this.sourceRanges.add(checkNotNull(sourceRange));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Firewall#getSourceRanges()
|
||||
*/
|
||||
public Builder sourceRanges(Set<String> sourceRanges) {
|
||||
this.sourceRanges.addAll(checkNotNull(sourceRanges));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Firewall#getSourceTags()
|
||||
*/
|
||||
public Builder addSourceTag(String sourceTag) {
|
||||
this.sourceTags.add(checkNotNull(sourceTag));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Firewall#getSourceTags()
|
||||
*/
|
||||
public Builder sourceTags(Set<String> sourceTags) {
|
||||
this.sourceTags.addAll(checkNotNull(sourceTags));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Firewall#getTargetTags()
|
||||
*/
|
||||
public Builder addTargetTag(String targetTag) {
|
||||
this.targetTags.add(checkNotNull(targetTag));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Firewall#getTargetTags()
|
||||
*/
|
||||
public Builder targetTags(Set<String> targetTags) {
|
||||
this.targetTags.addAll(checkNotNull(targetTags));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Firewall#getAllowed()
|
||||
*/
|
||||
public Builder addAllowed(Rule firewallRule) {
|
||||
this.allowed.add(checkNotNull(firewallRule));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Firewall#getAllowed()
|
||||
*/
|
||||
public Builder allowed(Set<Rule> firewallRules) {
|
||||
this.allowed = ImmutableSet.builder();
|
||||
this.allowed.addAll(firewallRules);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Builder self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Firewall build() {
|
||||
return new Firewall(super.id, super.creationTimestamp, super.selfLink, super.name,
|
||||
super.description, network, sourceRanges.build(), sourceTags.build(), targetTags.build(),
|
||||
allowed.build());
|
||||
}
|
||||
|
||||
public Builder fromFirewall(Firewall in) {
|
||||
return super.fromResource(in).network(in.getNetwork()).sourceRanges(in.getSourceRanges()).sourceTags(in
|
||||
.getSourceTags()).targetTags(in.getTargetTags()).allowed(in.getAllowed());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A Firewall rule. Rule specifies a protocol and port-range tuple that describes a
|
||||
* permitted connection.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/firewalls"/>
|
||||
*/
|
||||
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 RangeSet<Integer> ports;
|
||||
|
||||
@ConstructorProperties({
|
||||
"IPProtocol", "ports"
|
||||
})
|
||||
private Rule(IPProtocol IPProtocol, RangeSet<Integer> ports) {
|
||||
this.ipProtocol = checkNotNull(IPProtocol);
|
||||
this.ports = ports == null ? TreeRangeSet.<Integer>create() : ports;
|
||||
}
|
||||
|
||||
/**
|
||||
* This can either be a well known protocol string (tcp, udp or icmp) or the IP protocol number.
|
||||
*
|
||||
* @return this is the IP protocol that is allowed for this rule.
|
||||
*/
|
||||
public IPProtocol getIPProtocol() {
|
||||
return ipProtocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Each entry must be either an integer or a range. If not specified, connections through any port are allowed.
|
||||
* Example inputs include: ["22"], ["80,"443"], and ["12345-12349"].
|
||||
* <p/>
|
||||
* It is an error to specify this for any protocol that isn't UDP or TCP.
|
||||
*
|
||||
* @return An optional list of ports which are allowed.
|
||||
*/
|
||||
public RangeSet<Integer> getPorts() {
|
||||
return ports;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(ipProtocol, ports);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null || getClass() != obj.getClass()) return false;
|
||||
Rule that = Rule.class.cast(obj);
|
||||
return equal(this.ipProtocol, that.ipProtocol)
|
||||
&& equal(this.ports, that.ports);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public Objects.ToStringHelper string() {
|
||||
return toStringHelper(this)
|
||||
.add("IPProtocol", ipProtocol).add("ports", ports);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return builder().fromFirewallRule(this);
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
|
||||
private IPProtocol ipProtocol;
|
||||
private RangeSet<Integer> ports = TreeRangeSet.create();
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Firewall.Rule#getIPProtocol()
|
||||
*/
|
||||
public Builder IPProtocol(IPProtocol IPProtocol) {
|
||||
this.ipProtocol = checkNotNull(IPProtocol);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Firewall.Rule#getPorts()
|
||||
*/
|
||||
public Builder addPort(Integer port) {
|
||||
this.ports.add(singleton(checkNotNull(port, "port")));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Firewall.Rule#getPorts()
|
||||
*/
|
||||
public Builder addPortRange(Integer start, Integer end) {
|
||||
checkState(checkNotNull(start, "start") < checkNotNull(end, "end"),
|
||||
"start of range must be lower than end of range");
|
||||
this.ports.add(closed(start, end));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecompute.domain.Firewall.Rule#getPorts()
|
||||
*/
|
||||
public Builder ports(RangeSet<Integer> ports) {
|
||||
this.ports = TreeRangeSet.create();
|
||||
this.ports.addAll(ports);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Rule build() {
|
||||
return new Rule(ipProtocol, ports);
|
||||
}
|
||||
|
||||
public Builder fromFirewallRule(Rule firewallRule) {
|
||||
return new Builder().IPProtocol(firewallRule.getIPProtocol()).ports(firewallRule.getPorts());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.googlecompute.features;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecompute.domain.Firewall;
|
||||
import org.jclouds.googlecompute.domain.ListPage;
|
||||
import org.jclouds.googlecompute.domain.Operation;
|
||||
import org.jclouds.googlecompute.options.ListOptions;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Firewalls via their REST API.
|
||||
* <p/>
|
||||
* TODO support PATCH
|
||||
* (GCE uses PATCH as a Http method. Using this method is the only way to partially update a firewall.)
|
||||
*
|
||||
* @author David Alves
|
||||
* @see FirewallAsyncApi
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/firewalls"/>
|
||||
*/
|
||||
public interface FirewallApi {
|
||||
|
||||
/**
|
||||
* Returns the specified image resource.
|
||||
*
|
||||
* @param firewallName name of the firewall resource to return.
|
||||
* @return an Firewall resource
|
||||
*/
|
||||
Firewall get(String firewallName);
|
||||
|
||||
/**
|
||||
* Creates a firewall resource in the specified project using the data included in the request.
|
||||
*
|
||||
*
|
||||
* @param firewall the firewall to be inserted.
|
||||
* @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
|
||||
* you, and look for the status field.
|
||||
*/
|
||||
Operation create(Firewall firewall);
|
||||
|
||||
/**
|
||||
* Updates the specified firewall resource with the data included in the request.
|
||||
*
|
||||
* @param firewallName the name firewall to be updated.
|
||||
* @param firewall the new firewall.
|
||||
* @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
|
||||
* you, and look for the status field.
|
||||
*/
|
||||
Operation update(String firewallName, Firewall firewall);
|
||||
|
||||
/**
|
||||
* Updates the specified firewall resource, with patch semantics, with the data included in the request.
|
||||
*
|
||||
* @param firewallName the name firewall to be updated.
|
||||
* @param firewall the new firewall.
|
||||
* @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
|
||||
* you, and look for the status field.
|
||||
*/
|
||||
Operation patch(String firewallName, Firewall firewall);
|
||||
|
||||
/**
|
||||
* Deletes the specified image resource.
|
||||
*
|
||||
* @param imageName name of the firewall resource to delete.
|
||||
* @return an Operation resource. To check on the status of an operation, poll the Operations resource returned to
|
||||
* you, and look for the status field. If the image did not exist the result is null.
|
||||
*/
|
||||
Operation delete(String imageName);
|
||||
|
||||
/**
|
||||
* @see FirewallApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions)
|
||||
*/
|
||||
ListPage<Firewall> listFirstPage();
|
||||
|
||||
/**
|
||||
* @see FirewallApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions)
|
||||
*/
|
||||
ListPage<Firewall> listAtMarker(@Nullable String marker);
|
||||
|
||||
/**
|
||||
* Retrieves the list of firewall resources available to the specified project.
|
||||
* By default the list as a maximum size of 100, if no options are provided or ListOptions#getMaxResults() has not
|
||||
* been set.
|
||||
*
|
||||
* @param marker marks the beginning of the next list page
|
||||
* @param listOptions listing options
|
||||
* @return a page of the list
|
||||
* @see ListOptions
|
||||
* @see org.jclouds.googlecompute.domain.ListPage
|
||||
*/
|
||||
ListPage<Firewall> listAtMarker(@Nullable String marker, @Nullable ListOptions listOptions);
|
||||
|
||||
/**
|
||||
* @see FirewallApi#list(org.jclouds.googlecompute.options.ListOptions)
|
||||
*/
|
||||
public PagedIterable<Firewall> list();
|
||||
|
||||
/**
|
||||
* A paged version of FirewallApi#list()
|
||||
*
|
||||
* @return a Paged, Fluent Iterable that is able to fetch additional pages when required
|
||||
* @see PagedIterable
|
||||
* @see FirewallApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions)
|
||||
*/
|
||||
PagedIterable<Firewall> list(@Nullable ListOptions listOptions);
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.googlecompute.features;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecompute.domain.Firewall;
|
||||
import org.jclouds.googlecompute.domain.ListPage;
|
||||
import org.jclouds.googlecompute.domain.Operation;
|
||||
import org.jclouds.googlecompute.functions.internal.PATCH;
|
||||
import org.jclouds.googlecompute.functions.internal.ParseFirewalls;
|
||||
import org.jclouds.googlecompute.options.ListOptions;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.oauth.v2.config.OAuthScopes;
|
||||
import org.jclouds.oauth.v2.filters.OAuthAuthenticator;
|
||||
import org.jclouds.rest.annotations.BinderParam;
|
||||
import org.jclouds.rest.annotations.Fallback;
|
||||
import org.jclouds.rest.annotations.RequestFilters;
|
||||
import org.jclouds.rest.annotations.ResponseParser;
|
||||
import org.jclouds.rest.annotations.SkipEncoding;
|
||||
import org.jclouds.rest.annotations.Transform;
|
||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import static org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
|
||||
import static org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
||||
import static org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import static org.jclouds.googlecompute.GoogleComputeConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecompute.GoogleComputeConstants.COMPUTE_SCOPE;
|
||||
|
||||
/**
|
||||
* Provides asynchronous access to Firewalls via their REST API.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see FirewallApi
|
||||
* <p/>
|
||||
* Note: Patch is unsupported, jclouds side, at the moment
|
||||
*/
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(OAuthAuthenticator.class)
|
||||
public interface FirewallAsyncApi {
|
||||
|
||||
/**
|
||||
* @see FirewallApi#get(String)
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls/{firewall}")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
ListenableFuture<Firewall> get(@PathParam("firewall") String firewallName);
|
||||
|
||||
/**
|
||||
* @see FirewallApi#create(org.jclouds.googlecompute.domain.Firewall)
|
||||
*/
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls")
|
||||
@OAuthScopes({COMPUTE_SCOPE})
|
||||
ListenableFuture<Operation> create(@BinderParam(BindToJsonPayload.class) Firewall firewall);
|
||||
|
||||
/**
|
||||
* @see FirewallApi#update(String, org.jclouds.googlecompute.domain.Firewall)
|
||||
*/
|
||||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls/{firewall}")
|
||||
@OAuthScopes({COMPUTE_SCOPE})
|
||||
ListenableFuture<Operation> update(@PathParam("firewall") String firewallName,
|
||||
@BinderParam(BindToJsonPayload.class) Firewall firewall);
|
||||
|
||||
/**
|
||||
* @see FirewallApi#patch(String, org.jclouds.googlecompute.domain.Firewall)
|
||||
*/
|
||||
@PATCH
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls/{firewall}")
|
||||
@OAuthScopes({COMPUTE_SCOPE})
|
||||
ListenableFuture<Operation> patch(@PathParam("firewall") String firewallName,
|
||||
@BinderParam(BindToJsonPayload.class) Firewall firewall);
|
||||
|
||||
/**
|
||||
* @see FirewallApi#delete(String)
|
||||
*/
|
||||
@DELETE
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls/{firewall}")
|
||||
@OAuthScopes(COMPUTE_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
ListenableFuture<Operation> delete(@PathParam("firewall") String firewallName);
|
||||
|
||||
/**
|
||||
* @see FirewallApi#listFirstPage()
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseFirewalls.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListenableFuture<ListPage<Firewall>> listFirstPage();
|
||||
|
||||
/**
|
||||
* @see FirewallApi#listAtMarker(String)
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseFirewalls.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListenableFuture<ListPage<Firewall>> listAtMarker(@QueryParam("pageToken") @Nullable String marker);
|
||||
|
||||
/**
|
||||
* @see FirewallApi#listAtMarker(String, org.jclouds.googlecompute.options.ListOptions)
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseFirewalls.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListenableFuture<ListPage<Firewall>> listAtMarker(@QueryParam("pageToken") @Nullable String marker,
|
||||
ListOptions options);
|
||||
|
||||
/**
|
||||
* @see FirewallApi#list()
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseFirewalls.class)
|
||||
@Transform(ParseFirewalls.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PagedIterable<Firewall>> list();
|
||||
|
||||
|
||||
/**
|
||||
* @see FirewallApi#list(org.jclouds.googlecompute.options.ListOptions)
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseFirewalls.class)
|
||||
@Transform(ParseFirewalls.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
ListenableFuture<? extends PagedIterable<Firewall>> list(ListOptions options);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.googlecompute.functions.internal;
|
||||
|
||||
import javax.ws.rs.HttpMethod;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Indicates that the annotated method responds to HTTP PATCH requests
|
||||
*
|
||||
* @author David Alves
|
||||
* @see javax.ws.rs.HttpMethod
|
||||
*/
|
||||
@Target({ElementType.METHOD})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@HttpMethod("PATCH")
|
||||
public @interface PATCH {
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.googlecompute.functions.internal;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.googlecompute.GoogleComputeApi;
|
||||
import org.jclouds.googlecompute.domain.Firewall;
|
||||
import org.jclouds.googlecompute.domain.ListPage;
|
||||
import org.jclouds.googlecompute.options.ListOptions;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
import org.jclouds.json.Json;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class ParseFirewalls extends ParseJson<ListPage<Firewall>> {
|
||||
|
||||
@Inject
|
||||
public ParseFirewalls(Json json) {
|
||||
super(json, new TypeLiteral<ListPage<Firewall>>() {});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends BaseToPagedIterable<Firewall, ToPagedIterable> {
|
||||
|
||||
private final GoogleComputeApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(GoogleComputeApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Firewall>> fetchNextPage(final String projectName,
|
||||
final String marker,
|
||||
final ListOptions options) {
|
||||
return new Function<Object, IterableWithMarker<Firewall>>() {
|
||||
|
||||
@Override
|
||||
public IterableWithMarker<Firewall> apply(Object input) {
|
||||
return api.getFirewallApiForProject(projectName).listAtMarker(marker, options);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.googlecompute.features;
|
||||
|
||||
import org.jclouds.googlecompute.domain.Firewall;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeApiExpectTest;
|
||||
import org.jclouds.googlecompute.parse.ParseFirewallListTest;
|
||||
import org.jclouds.googlecompute.parse.ParseFirewallTest;
|
||||
import org.jclouds.googlecompute.parse.ParseOperationTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.net.URI;
|
||||
|
||||
import static org.jclouds.googlecompute.GoogleComputeConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecompute.GoogleComputeConstants.COMPUTE_SCOPE;
|
||||
import static org.jclouds.googlecompute.domain.Firewall.Rule.IPProtocol;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.AssertJUnit.assertNull;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class FirewallApiExpectTest extends BaseGoogleComputeApiExpectTest {
|
||||
|
||||
public void testGetFirewallResponseIs2xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/google/firewalls/default-allow-internal")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/firewall_get.json")).build();
|
||||
|
||||
FirewallApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getFirewallApiForProject("google");
|
||||
|
||||
assertEquals(api.get("default-allow-internal"),
|
||||
new ParseFirewallTest().expected());
|
||||
}
|
||||
|
||||
public void testGetFirewallResponseIs4xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/google/firewalls/default-allow-internal")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
FirewallApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getFirewallApiForProject("google");
|
||||
|
||||
assertNull(api.get("default-allow-internal"));
|
||||
}
|
||||
|
||||
public void testInsertFirewallResponseIs2xx() {
|
||||
HttpRequest insert = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/firewalls")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromResourceWithContentType("/firewall_insert.json", MediaType.APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
HttpResponse insertFirewallResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
FirewallApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, insert,
|
||||
insertFirewallResponse).getFirewallApiForProject("myproject");
|
||||
|
||||
assertEquals(api.create(Firewall.builder()
|
||||
.name("myfw")
|
||||
.network(URI.create("https://www.googleapis.com/compute/v1beta13/projects/myproject/networks/default"))
|
||||
.addAllowed(Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(22)
|
||||
.addPortRange(23, 24).build())
|
||||
.addSourceTag("tag1")
|
||||
.addSourceRange("10.0.1.0/32")
|
||||
.addTargetTag("tag2")
|
||||
.build()), new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testUpdateFirewallResponseIs2xx() {
|
||||
HttpRequest update = HttpRequest
|
||||
.builder()
|
||||
.method("PUT")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/firewalls/myfw")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromResourceWithContentType("/firewall_insert.json", MediaType.APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
HttpResponse updateFirewallResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
FirewallApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, update,
|
||||
updateFirewallResponse).getFirewallApiForProject("myproject");
|
||||
|
||||
assertEquals(api.update("myfw", Firewall.builder()
|
||||
.name("myfw")
|
||||
.network(URI.create("https://www.googleapis.com/compute/v1beta13/projects/myproject/networks/default"))
|
||||
.addAllowed(Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(22)
|
||||
.addPortRange(23, 24).build())
|
||||
.addSourceTag("tag1")
|
||||
.addSourceRange("10.0.1.0/32")
|
||||
.addTargetTag("tag2")
|
||||
.build()), new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testPatchFirewallResponseIs2xx() {
|
||||
HttpRequest update = HttpRequest
|
||||
.builder()
|
||||
.method("PATCH")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/firewalls/myfw")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromResourceWithContentType("/firewall_insert.json", MediaType.APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
HttpResponse updateFirewallResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
FirewallApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, update,
|
||||
updateFirewallResponse).getFirewallApiForProject("myproject");
|
||||
|
||||
assertEquals(api.patch("myfw", Firewall.builder()
|
||||
.name("myfw")
|
||||
.network(URI.create("https://www.googleapis.com/compute/v1beta13/projects/myproject/networks/default"))
|
||||
.addAllowed(Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(22)
|
||||
.addPortRange(23, 24).build())
|
||||
.addSourceTag("tag1")
|
||||
.addSourceRange("10.0.1.0/32")
|
||||
.addTargetTag("tag2")
|
||||
.build()), new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testDeleteFirewallResponseIs2xx() {
|
||||
HttpRequest delete = HttpRequest
|
||||
.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/firewalls/default-allow-internal")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse deleteResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
FirewallApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, delete, deleteResponse).getFirewallApiForProject("myproject");
|
||||
|
||||
assertEquals(api.delete("default-allow-internal"),
|
||||
new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testDeleteFirewallResponseIs4xx() {
|
||||
HttpRequest delete = HttpRequest
|
||||
.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/firewalls/default-allow-internal")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse deleteResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
FirewallApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, delete, deleteResponse).getFirewallApiForProject("myproject");
|
||||
|
||||
assertNull(api.delete("default-allow-internal"));
|
||||
}
|
||||
|
||||
public void testListFirewallsResponseIs2xx() {
|
||||
HttpRequest list = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/firewalls")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/firewall_list.json")).build();
|
||||
|
||||
FirewallApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, list, operationResponse).getFirewallApiForProject("myproject");
|
||||
|
||||
assertEquals(api.listFirstPage().toString(),
|
||||
new ParseFirewallListTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testListFirewallsResponseIs4xx() {
|
||||
HttpRequest list = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/firewalls")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
FirewallApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, list, operationResponse).getFirewallApiForProject("myproject");
|
||||
|
||||
assertTrue(api.list().concat().isEmpty());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.googlecompute.features;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecompute.domain.Firewall;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeApiLiveTest;
|
||||
import org.jclouds.googlecompute.options.ListOptions;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static org.jclouds.googlecompute.domain.Firewall.Rule.IPProtocol;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class FirewallApiLiveTest extends BaseGoogleComputeApiLiveTest {
|
||||
|
||||
private static final String FIREWALL_NAME = "firewall-api-live-test-firewall";
|
||||
private static final int TIME_WAIT = 30;
|
||||
|
||||
private Firewall firewall;
|
||||
|
||||
@BeforeClass(groups = {"integration", "live"})
|
||||
public void setupContext() {
|
||||
super.setupContext();
|
||||
firewall = Firewall.builder()
|
||||
.name(FIREWALL_NAME)
|
||||
.network(getDefaultNetworkUrl(getUserProject()))
|
||||
.addAllowed(
|
||||
Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(22).build())
|
||||
.addSourceRange("10.0.0.0/8")
|
||||
.addSourceTag("tag1")
|
||||
.addTargetTag("tag2")
|
||||
.build();
|
||||
}
|
||||
|
||||
private FirewallApi api() {
|
||||
return context.getApi().getFirewallApiForProject(getUserProject());
|
||||
}
|
||||
|
||||
@Test(groups = "live")
|
||||
public void testInsertFirewall() {
|
||||
|
||||
assertOperationDoneSucessfully(api().create(firewall), TIME_WAIT);
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testInsertFirewall")
|
||||
public void testUpdateFirewall() {
|
||||
|
||||
// replace 22 with 23
|
||||
firewall = firewall.toBuilder()
|
||||
.allowed(ImmutableSet.of(
|
||||
Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(23)
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
assertOperationDoneSucessfully(api().update(firewall.getName(), firewall), TIME_WAIT);
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testUpdateFirewall")
|
||||
public void testPatchFirewall() {
|
||||
|
||||
// readd 22 with "patch" semantics
|
||||
firewall = firewall.toBuilder()
|
||||
.allowed(ImmutableSet.of(
|
||||
Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(22)
|
||||
.build(),
|
||||
Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(23)
|
||||
.build()))
|
||||
.build();
|
||||
|
||||
assertOperationDoneSucessfully(api().update(firewall.getName(), firewall), TIME_WAIT);
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testInsertFirewall")
|
||||
public void testGetFirewall() {
|
||||
|
||||
Firewall firewall = api().get(FIREWALL_NAME);
|
||||
assertNotNull(firewall);
|
||||
assertFirewallEquals(firewall, this.firewall);
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testGetFirewall")
|
||||
public void testListFirewall() {
|
||||
|
||||
PagedIterable<Firewall> firewalls = api().list(new ListOptions.Builder()
|
||||
.filter("name eq " + FIREWALL_NAME));
|
||||
|
||||
List<Firewall> firewallsAsList = Lists.newArrayList(firewalls.concat());
|
||||
|
||||
assertEquals(firewallsAsList.size(), 1);
|
||||
|
||||
assertFirewallEquals(getOnlyElement(firewallsAsList),
|
||||
firewall.toBuilder()
|
||||
.addAllowed(Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(23)
|
||||
.build())
|
||||
.build());
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testListFirewall")
|
||||
public void testDeleteFirewall() {
|
||||
|
||||
assertOperationDoneSucessfully(api().delete(FIREWALL_NAME), TIME_WAIT);
|
||||
}
|
||||
|
||||
private void assertFirewallEquals(Firewall result, Firewall expected) {
|
||||
assertEquals(result.getName(), expected.getName());
|
||||
assertEquals(getOnlyElement(result.getSourceRanges()), getOnlyElement(expected.getSourceRanges()));
|
||||
assertEquals(getOnlyElement(result.getSourceTags()), getOnlyElement(expected.getSourceTags()));
|
||||
assertEquals(getOnlyElement(result.getTargetTags()), getOnlyElement(expected.getTargetTags()));
|
||||
assertEquals(result.getAllowed(), expected.getAllowed());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.googlecompute.parse;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.googlecompute.domain.Firewall;
|
||||
import org.jclouds.googlecompute.domain.ListPage;
|
||||
import org.jclouds.googlecompute.domain.Resource;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeParseTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ParseFirewallListTest extends BaseGoogleComputeParseTest<ListPage<Firewall>> {
|
||||
|
||||
@Override
|
||||
public String resource() {
|
||||
return "/firewall_list.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public ListPage<Firewall> expected() {
|
||||
return ListPage.<Firewall>builder()
|
||||
.kind(Resource.Kind.FIREWALL_LIST)
|
||||
.id("projects/google/firewalls")
|
||||
.selfLink(URI.create("https://www.googleapis.com/compute/v1beta13/projects/google/firewalls"))
|
||||
.items(ImmutableSet.of(
|
||||
new ParseFirewallTest().expected()
|
||||
, Firewall.builder()
|
||||
.id("12862241067393040785")
|
||||
.creationTimestamp(new SimpleDateFormatDateService().iso8601DateParse("2012-04-13T03:05:04.365"))
|
||||
.selfLink(URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/google/firewalls/default-ssh"))
|
||||
.name("default-ssh")
|
||||
.description("SSH allowed from anywhere")
|
||||
.network(URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/google/networks/default"))
|
||||
.addSourceRange("0.0.0.0/0")
|
||||
.addAllowed(Firewall.Rule.builder()
|
||||
.IPProtocol(Firewall.Rule.IPProtocol.TCP)
|
||||
.addPort(22).build())
|
||||
.build()
|
||||
))
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds 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.googlecompute.parse;
|
||||
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.googlecompute.domain.Firewall;
|
||||
import org.jclouds.googlecompute.internal.BaseGoogleComputeParseTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.net.URI;
|
||||
|
||||
import static org.jclouds.googlecompute.domain.Firewall.Rule.IPProtocol;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ParseFirewallTest extends BaseGoogleComputeParseTest<Firewall> {
|
||||
|
||||
@Override
|
||||
public String resource() {
|
||||
return "/firewall_get.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public Firewall expected() {
|
||||
return Firewall.builder()
|
||||
.id("12862241031274216284")
|
||||
.creationTimestamp(new SimpleDateFormatDateService().iso8601DateParse("2012-04-13T03:05:02.855"))
|
||||
.selfLink(URI.create("https://www.googleapis.com/compute/v1beta13/projects/google/firewalls/default" +
|
||||
"-allow-internal"))
|
||||
.name("default-allow-internal")
|
||||
.description("Internal traffic from default allowed")
|
||||
.network(URI.create("https://www.googleapis.com/compute/v1beta13/projects/google/networks/default"))
|
||||
.addSourceRange("10.0.0.0/8")
|
||||
.addAllowed(Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPortRange(1, 65535).build())
|
||||
.addAllowed(Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.UDP)
|
||||
.addPortRange(1, 65535).build())
|
||||
.addAllowed(Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.ICMP).build())
|
||||
.build();
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
|
||||
"kind": "compute#firewall",
|
||||
"id": "12862241031274216284",
|
||||
"creationTimestamp": "2012-04-13T03:05:02.855",
|
||||
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/firewalls/default-allow-internal",
|
||||
"name": "default-allow-internal",
|
||||
"description": "Internal traffic from default allowed",
|
||||
"network": "https://www.googleapis.com/compute/v1beta13/projects/google/networks/default",
|
||||
"sourceRanges": [
|
||||
"10.0.0.0/8"
|
||||
],
|
||||
"allowed": [
|
||||
{
|
||||
"IPProtocol": "tcp",
|
||||
"ports": [
|
||||
"1-65535"
|
||||
]
|
||||
},
|
||||
{
|
||||
"IPProtocol": "udp",
|
||||
"ports": [
|
||||
"1-65535"
|
||||
]
|
||||
},
|
||||
{
|
||||
"IPProtocol": "icmp"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
{"network":"https://www.googleapis.com/compute/v1beta13/projects/myproject/networks/default","sourceRanges":["10.0.1.0/32"],"sourceTags":["tag1"],"targetTags":["tag2"],"allowed":[{"IPProtocol":"tcp","ports":["22","23-24"]}],"kind":"compute#firewall","name":"myfw"}
|
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"kind": "compute#firewallList",
|
||||
"id": "projects/google/firewalls",
|
||||
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/firewalls",
|
||||
"items": [
|
||||
{
|
||||
|
||||
"kind": "compute#firewall",
|
||||
"id": "12862241031274216284",
|
||||
"creationTimestamp": "2012-04-13T03:05:02.855",
|
||||
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/firewalls/default-allow-internal",
|
||||
"name": "default-allow-internal",
|
||||
"description": "Internal traffic from default allowed",
|
||||
"network": "https://www.googleapis.com/compute/v1beta13/projects/google/networks/default",
|
||||
"sourceRanges": [
|
||||
"10.0.0.0/8"
|
||||
],
|
||||
"allowed": [
|
||||
{
|
||||
"IPProtocol": "tcp",
|
||||
"ports": [
|
||||
"1-65535"
|
||||
]
|
||||
},
|
||||
{
|
||||
"IPProtocol": "udp",
|
||||
"ports": [
|
||||
"1-65535"
|
||||
]
|
||||
},
|
||||
{
|
||||
"IPProtocol": "icmp"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
"kind": "compute#firewall",
|
||||
"id": "12862241067393040785",
|
||||
"creationTimestamp": "2012-04-13T03:05:04.365",
|
||||
"selfLink": "https://www.googleapis.com/compute/v1beta13/projects/google/firewalls/default-ssh",
|
||||
"name": "default-ssh",
|
||||
"description": "SSH allowed from anywhere",
|
||||
"network": "https://www.googleapis.com/compute/v1beta13/projects/google/networks/default",
|
||||
"sourceRanges": [
|
||||
"0.0.0.0/0"
|
||||
],
|
||||
"allowed": [
|
||||
{
|
||||
"IPProtocol": "tcp",
|
||||
"ports": [
|
||||
"22"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue