mirror of https://github.com/apache/jclouds.git
organized google code into its own subdir
This commit is contained in:
commit
98846381ba
|
@ -0,0 +1,63 @@
|
|||
jclouds Google Compute Engine Provider
|
||||
======
|
||||
|
||||
|
||||
Authenticating into the instances:
|
||||
--------
|
||||
|
||||
User:
|
||||
If no user is provided in GoogleComputeEngineTemplateOptions when launching an instance by default "jclouds" is used.
|
||||
|
||||
Credential:
|
||||
|
||||
GCE uses exclusively ssh keys to login into instances.
|
||||
In order for an instance to be sshable a public key must be installed. Public keys are installed if they are present in the project or instance's metatada.
|
||||
|
||||
For an instance to be ssable one of the following must happen:
|
||||
1 - the project's metadata has an adequately built "sshKeys" entry and a corresponding private key is provided in GoogleComputeEngineTemplateOptions when createNodesInGroup is called.
|
||||
2 - an instance of GoogleComputeEngineTemplateOptions with an adequate public and private key is provided.
|
||||
|
||||
NOTE: if methods 2 is chosen the global project keys will not be installed in the instance.
|
||||
|
||||
Please refer to Google's documentation on how to form valid project wide ssh keys metadata entries.
|
||||
|
||||
FAQ:
|
||||
--------
|
||||
|
||||
* Q. What is the identity for GCE?
|
||||
|
||||
A. the identity is the developer email which can be obtained from the admin GUI. Its usually something in the form: <my account id>@developer.gserviceaccount.com
|
||||
|
||||
* Q. What is the credential for GCE
|
||||
|
||||
A. the credential is a private key, in pem format. It can be extracted from the p12 keystore that is obtained when creating a "Service Account" (in the GUI: Google apis console > Api Access > Create another client ID > "Service Account"
|
||||
|
||||
* Q. How to convert a p12 keystore into a pem format jclouds Google Compute Engine can handle:
|
||||
|
||||
A.
|
||||
|
||||
1. Convert the p12 file into pem format (it will ask for the keystore password, which is usually "notasecret"):
|
||||
openssl pkcs12 -in <my_keystore>.p12 -out <my_keystore>.pem -nodes
|
||||
|
||||
2. Extract only the pk and remove passphrase
|
||||
openssl rsa -in <my_keystore>.pem -out <my_key>.pem
|
||||
|
||||
The last file (<my_key>.pem) should contain the pk that needs to be passed to `ContextBuilder.credential()` for the provider `google-compute-engine`.
|
||||
|
||||
|
||||
Running the live tests:
|
||||
--------
|
||||
|
||||
1. Place the following in your ~/.m2/settings.xml in a profile enabled when live:
|
||||
```
|
||||
<test.google-compute-engine.identity>YOUR_ACCOUNT_NUMBER@developer.gserviceaccount.com</test.google-compute-engine.identity>
|
||||
<test.google-compute-engine.credential>-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXgIBAAKBgQRRbRqVDtJLN1MO/xJoKqZuphDeBh5jIKueW3aNIiWs1XFcct+h
|
||||
-- this text is literally from your <my_key>.pem
|
||||
aH7xmpHSTbbXmQkuuv+z8EKijigprd/FoJpTX1f5/R+4wQ==
|
||||
-----END RSA PRIVATE KEY-----</test.google-compute-engine.credential>
|
||||
</properties>
|
||||
```
|
||||
|
||||
2. mvn clean install -Plive
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.jclouds.labs</groupId>
|
||||
<artifactId>jclouds-labs-google</artifactId>
|
||||
<version>1.7.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<!-- TODO: when out of labs, switch to org.jclouds.provider -->
|
||||
<groupId>org.jclouds.labs</groupId>
|
||||
<artifactId>google-compute-engine</artifactId>
|
||||
<name>jclouds Google Compute Engine provider</name>
|
||||
<description>jclouds components to access GoogleCompute</description>
|
||||
|
||||
<properties>
|
||||
<test.google-compute-engine.identity>Email associated with the Google API client_id</test.google-compute-engine.identity>
|
||||
<test.google-compute-engine.credential>Private key (PKCS12 file) associated with the Google API client_id</test.google-compute-engine.credential>
|
||||
<test.google-compute-engine.api-version>v1beta13</test.google-compute-engine.api-version>
|
||||
<test.google-compute-engine.build-version />
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<artifactId>jclouds-core</artifactId>
|
||||
<version>${jclouds.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.labs</groupId>
|
||||
<artifactId>oauth</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>jar</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.labs</groupId>
|
||||
<artifactId>oauth</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<artifactId>jclouds-compute</artifactId>
|
||||
<version>${jclouds.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<artifactId>jclouds-compute</artifactId>
|
||||
<version>${jclouds.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds</groupId>
|
||||
<artifactId>jclouds-core</artifactId>
|
||||
<version>${jclouds.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.driver</groupId>
|
||||
<artifactId>jclouds-slf4j</artifactId>
|
||||
<version>${jclouds.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jclouds.driver</groupId>
|
||||
<artifactId>jclouds-sshj</artifactId>
|
||||
<version>${jclouds.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>live</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>integration</id>
|
||||
<phase>integration-test</phase>
|
||||
<goals>
|
||||
<goal>test</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<test.google-compute-engine.identity>${test.google-compute-engine.identity}</test.google-compute-engine.identity>
|
||||
<test.google-compute-engine.credential>${test.google-compute-engine.credential}</test.google-compute-engine.credential>
|
||||
<test.google-compute-engine.api-version>${test.google-compute-engine.api-version}</test.google-compute-engine.api-version>
|
||||
<test.google-compute-engine.build-version>${test.google-compute-engine.build-version}</test.google-compute-engine.build-version>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* 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.googlecomputeengine;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
|
||||
import org.jclouds.googlecomputeengine.features.DiskApi;
|
||||
import org.jclouds.googlecomputeengine.features.FirewallApi;
|
||||
import org.jclouds.googlecomputeengine.features.ImageApi;
|
||||
import org.jclouds.googlecomputeengine.features.InstanceApi;
|
||||
import org.jclouds.googlecomputeengine.features.KernelApi;
|
||||
import org.jclouds.googlecomputeengine.features.MachineTypeApi;
|
||||
import org.jclouds.googlecomputeengine.features.NetworkApi;
|
||||
import org.jclouds.googlecomputeengine.features.OperationApi;
|
||||
import org.jclouds.googlecomputeengine.features.ProjectApi;
|
||||
import org.jclouds.googlecomputeengine.features.ZoneApi;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
|
||||
/**
|
||||
* Provides access to GoogleCompute.
|
||||
* <p/>
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13">api doc</a>
|
||||
*/
|
||||
@Beta
|
||||
public interface GoogleComputeEngineApi extends Closeable {
|
||||
|
||||
/**
|
||||
* Provides access to Disk features
|
||||
*
|
||||
* @param projectName the name of the project
|
||||
*/
|
||||
@Delegate
|
||||
@Path("/projects/{project}")
|
||||
DiskApi getDiskApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides access to Firewall features
|
||||
*
|
||||
* @param projectName the name of the project
|
||||
*/
|
||||
@Delegate
|
||||
@Path("/projects/{project}")
|
||||
FirewallApi getFirewallApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides access to Image features
|
||||
*
|
||||
* @param projectName the name of the project
|
||||
*/
|
||||
@Delegate
|
||||
@Path("/projects/{project}")
|
||||
ImageApi getImageApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides access to Instance features
|
||||
*
|
||||
* @param projectName the name of the project
|
||||
*/
|
||||
@Delegate
|
||||
@Path("/projects/{project}")
|
||||
InstanceApi getInstanceApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides access to Kernel features
|
||||
*
|
||||
* @param projectName the name of the project
|
||||
*/
|
||||
@Delegate
|
||||
@Path("/projects/{project}")
|
||||
KernelApi getKernelApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides access to MachineType features
|
||||
*
|
||||
* @param projectName the name of the project
|
||||
*/
|
||||
@Delegate
|
||||
@Path("/projects/{project}")
|
||||
MachineTypeApi getMachineTypeApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides access to Network features
|
||||
*
|
||||
* @param projectName the name of the project
|
||||
*/
|
||||
@Delegate
|
||||
@Path("/projects/{project}")
|
||||
NetworkApi getNetworkApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides access to Operation features
|
||||
*
|
||||
* @param projectName the name of the project
|
||||
*/
|
||||
@Delegate
|
||||
@Path("/projects/{project}")
|
||||
OperationApi getOperationApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Provides access to Project features
|
||||
*/
|
||||
@Delegate
|
||||
ProjectApi getProjectApi();
|
||||
|
||||
/**
|
||||
* Provides access to Zone features
|
||||
*
|
||||
* @param projectName the name of the project
|
||||
*/
|
||||
@Delegate
|
||||
@Path("/projects/{project}")
|
||||
ZoneApi getZoneApiForProject(@PathParam("project") String projectName);
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
/**
|
||||
* 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.googlecomputeengine;
|
||||
|
||||
import static org.jclouds.Constants.PROPERTY_SESSION_INTERVAL;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GCE_PROVIDER_NAME;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
|
||||
import static org.jclouds.oauth.v2.config.OAuthProperties.AUDIENCE;
|
||||
import static org.jclouds.oauth.v2.config.OAuthProperties.SIGNATURE_OR_MAC_ALGORITHM;
|
||||
import static org.jclouds.reflect.Reflection2.typeToken;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.apis.ApiMetadata;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.googlecomputeengine.compute.config.GoogleComputeEngineServiceContextModule;
|
||||
import org.jclouds.googlecomputeengine.config.GoogleComputeEngineHttpApiModule;
|
||||
import org.jclouds.googlecomputeengine.config.GoogleComputeEngineParserModule;
|
||||
import org.jclouds.googlecomputeengine.config.OAuthModuleWithoutTypeAdapters;
|
||||
import org.jclouds.oauth.v2.config.OAuthAuthenticationModule;
|
||||
import org.jclouds.rest.internal.BaseHttpApiMetadata;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* Implementation of {@link ApiMetadata} for GoogleCompute v1beta13 API
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
public class GoogleComputeEngineApiMetadata extends BaseHttpApiMetadata<GoogleComputeEngineApi> {
|
||||
|
||||
@Override
|
||||
public Builder toBuilder() {
|
||||
return new Builder().fromApiMetadata(this);
|
||||
}
|
||||
|
||||
public GoogleComputeEngineApiMetadata() {
|
||||
this(new Builder());
|
||||
}
|
||||
|
||||
protected GoogleComputeEngineApiMetadata(Builder builder) {
|
||||
super(builder);
|
||||
}
|
||||
|
||||
public static Properties defaultProperties() {
|
||||
Properties properties = BaseHttpApiMetadata.defaultProperties();
|
||||
properties.put("oauth.endpoint", "https://accounts.google.com/o/oauth2/token");
|
||||
properties.put(AUDIENCE, "https://accounts.google.com/o/oauth2/token");
|
||||
properties.put(SIGNATURE_OR_MAC_ALGORITHM, "RS256");
|
||||
properties.put(PROPERTY_SESSION_INTERVAL, 3600);
|
||||
properties.setProperty(TEMPLATE, "osFamily=GCEL,osVersionMatches=1[012].[01][04],locationId=us-central1-a," +
|
||||
"loginUser=jclouds");
|
||||
properties.put(OPERATION_COMPLETE_INTERVAL, 500);
|
||||
properties.put(OPERATION_COMPLETE_TIMEOUT, 600000);
|
||||
return properties;
|
||||
}
|
||||
|
||||
public static class Builder extends BaseHttpApiMetadata.Builder<GoogleComputeEngineApi, Builder> {
|
||||
|
||||
protected Builder() {
|
||||
id(GCE_PROVIDER_NAME)
|
||||
.name("Google Compute Engine Api")
|
||||
.identityName("Email associated with the Google API client_id")
|
||||
.credentialName("Private key literal associated with the Google API client_id")
|
||||
.documentation(URI.create("https://developers.google.com/compute/docs"))
|
||||
.version("v1beta13")
|
||||
.defaultEndpoint("https://www.googleapis.com/compute/v1beta13")
|
||||
.defaultProperties(GoogleComputeEngineApiMetadata.defaultProperties())
|
||||
.view(typeToken(ComputeServiceContext.class))
|
||||
.defaultModules(ImmutableSet.<Class<? extends Module>>builder()
|
||||
.add(GoogleComputeEngineHttpApiModule.class)
|
||||
.add(GoogleComputeEngineParserModule.class)
|
||||
.add(OAuthAuthenticationModule.class)
|
||||
.add(OAuthModuleWithoutTypeAdapters.class)
|
||||
.add(GoogleComputeEngineServiceContextModule.class)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public GoogleComputeEngineApiMetadata build() {
|
||||
return new GoogleComputeEngineApiMetadata(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Builder self() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* 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.googlecomputeengine;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public interface GoogleComputeEngineConstants {
|
||||
|
||||
public static final String GCE_PROVIDER_NAME = "google-compute-engine";
|
||||
|
||||
/**
|
||||
* The name of the project that keeps public resources.
|
||||
*/
|
||||
public static final String GOOGLE_PROJECT = "google";
|
||||
|
||||
public static final String COMPUTE_SCOPE = "https://www.googleapis.com/auth/compute";
|
||||
|
||||
public static final String COMPUTE_READONLY_SCOPE = "https://www.googleapis.com/auth/compute.readonly";
|
||||
|
||||
/**
|
||||
* The total time, in msecs, to wait for an operation to complete.
|
||||
*/
|
||||
@Beta
|
||||
public static final String OPERATION_COMPLETE_TIMEOUT = "jclouds.google-compute-engine.operation-complete-timeout";
|
||||
|
||||
/**
|
||||
* The interval, in msecs, between calls to check whether an operation has completed.
|
||||
*/
|
||||
@Beta
|
||||
public static final String OPERATION_COMPLETE_INTERVAL = "jclouds.google-compute-engine.operation-complete-interval";
|
||||
|
||||
public static final Location GOOGLE_PROVIDER_LOCATION = new LocationBuilder().scope(LocationScope.PROVIDER).id
|
||||
(GCE_PROVIDER_NAME).description(GCE_PROVIDER_NAME).build();
|
||||
|
||||
}
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.callables.RunScriptOnNode;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.functions.GroupNamingConvention;
|
||||
import org.jclouds.compute.internal.BaseComputeService;
|
||||
import org.jclouds.compute.internal.PersistNodeCredentials;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
import org.jclouds.compute.strategy.GetImageStrategy;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
|
||||
import org.jclouds.googlecomputeengine.config.UserProject;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.scriptbuilder.functions.InitAdminAccess;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_RUNNING;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_SUSPENDED;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TIMEOUT_NODE_TERMINATED;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class GoogleComputeEngineService extends BaseComputeService {
|
||||
|
||||
private final Function<Set<? extends NodeMetadata>, Set<String>> findOrphanedGroups;
|
||||
private final GroupNamingConvention.Factory namingConvention;
|
||||
private final GoogleComputeEngineApi api;
|
||||
private final Supplier<String> project;
|
||||
private final Predicate<AtomicReference<Operation>> operationDonePredicate;
|
||||
private final long operationCompleteCheckInterval;
|
||||
private final long operationCompleteCheckTimeout;
|
||||
|
||||
@Inject
|
||||
protected GoogleComputeEngineService(ComputeServiceContext context,
|
||||
Map<String, Credentials> credentialStore,
|
||||
@Memoized Supplier<Set<? extends Image>> images,
|
||||
@Memoized Supplier<Set<? extends Hardware>> hardwareProfiles,
|
||||
@Memoized Supplier<Set<? extends Location>> locations,
|
||||
ListNodesStrategy listNodesStrategy,
|
||||
GetImageStrategy getImageStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy,
|
||||
CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy,
|
||||
RebootNodeStrategy rebootNodeStrategy,
|
||||
DestroyNodeStrategy destroyNodeStrategy,
|
||||
ResumeNodeStrategy resumeNodeStrategy,
|
||||
SuspendNodeStrategy suspendNodeStrategy,
|
||||
Provider<TemplateBuilder> templateBuilderProvider,
|
||||
@Named("DEFAULT") Provider<TemplateOptions> templateOptionsProvider,
|
||||
@Named(TIMEOUT_NODE_RUNNING) Predicate<AtomicReference<NodeMetadata>>
|
||||
nodeRunning,
|
||||
@Named(TIMEOUT_NODE_TERMINATED) Predicate<AtomicReference<NodeMetadata>>
|
||||
nodeTerminated,
|
||||
@Named(TIMEOUT_NODE_SUSPENDED)
|
||||
Predicate<AtomicReference<NodeMetadata>> nodeSuspended,
|
||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory,
|
||||
InitAdminAccess initAdminAccess,
|
||||
RunScriptOnNode.Factory runScriptOnNodeFactory,
|
||||
PersistNodeCredentials persistNodeCredentials,
|
||||
ComputeServiceConstants.Timeouts timeouts,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ListeningExecutorService userExecutor,
|
||||
Optional<ImageExtension> imageExtension,
|
||||
Function<Set<? extends NodeMetadata>, Set<String>> findOrphanedGroups,
|
||||
GroupNamingConvention.Factory namingConvention,
|
||||
GoogleComputeEngineApi api,
|
||||
@UserProject Supplier<String> project,
|
||||
Predicate<AtomicReference<Operation>> operationDonePredicate,
|
||||
@Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
|
||||
@Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout) {
|
||||
|
||||
super(context, credentialStore, images, hardwareProfiles, locations, listNodesStrategy, getImageStrategy,
|
||||
getNodeMetadataStrategy, runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy,
|
||||
resumeNodeStrategy, suspendNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning,
|
||||
nodeTerminated, nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory,
|
||||
persistNodeCredentials, timeouts, userExecutor, imageExtension);
|
||||
this.findOrphanedGroups = checkNotNull(findOrphanedGroups, "find orphaned groups function");
|
||||
this.namingConvention = checkNotNull(namingConvention, "naming convention factory");
|
||||
this.api = checkNotNull(api, "google compute api");
|
||||
this.project = checkNotNull(project, "user project name");
|
||||
this.operationDonePredicate = checkNotNull(operationDonePredicate, "operation completed predicate");
|
||||
this.operationCompleteCheckInterval = checkNotNull(operationCompleteCheckInterval,
|
||||
"operation completed check interval");
|
||||
this.operationCompleteCheckTimeout = checkNotNull(operationCompleteCheckTimeout,
|
||||
"operation completed check timeout");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void cleanUpIncidentalResourcesOfDeadNodes(Set<? extends NodeMetadata> deadNodes) {
|
||||
Set<String> orphanedGroups = findOrphanedGroups.apply(deadNodes);
|
||||
for (String orphanedGroup : orphanedGroups) {
|
||||
cleanUpNetworksAndFirewallsForGroup(orphanedGroup);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void cleanUpNetworksAndFirewallsForGroup(String groupName) {
|
||||
String resourceName = namingConvention.create().sharedNameForGroup(groupName);
|
||||
AtomicReference<Operation> operation = new AtomicReference<Operation>(api.getFirewallApiForProject(project.get())
|
||||
.delete(resourceName));
|
||||
|
||||
retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
|
||||
MILLISECONDS).apply(operation);
|
||||
|
||||
if (operation.get().getHttpError().isPresent()) {
|
||||
HttpResponse response = operation.get().getHttpError().get();
|
||||
logger.warn("delete orphaned firewall failed. Http Error Code: " + response.getStatusCode() +
|
||||
" HttpError: " + response.getMessage());
|
||||
}
|
||||
|
||||
operation = new AtomicReference<Operation>(api.getNetworkApiForProject(project.get()).delete(resourceName));
|
||||
|
||||
retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
|
||||
MILLISECONDS).apply(operation);
|
||||
|
||||
if (operation.get().getHttpError().isPresent()) {
|
||||
HttpResponse response = operation.get().getHttpError().get();
|
||||
logger.warn("delete orphaned network failed. Http Error Code: " + response.getStatusCode() +
|
||||
" HttpError: " + response.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* returns template options, except of type {@link org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions}.
|
||||
*/
|
||||
@Override
|
||||
public GoogleComputeEngineTemplateOptions templateOptions() {
|
||||
return GoogleComputeEngineTemplateOptions.class.cast(super.templateOptions());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,265 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.util.concurrent.UncheckedTimeoutException;
|
||||
import com.google.inject.Inject;
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
|
||||
import org.jclouds.googlecomputeengine.config.UserProject;
|
||||
import org.jclouds.googlecomputeengine.domain.Image;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance;
|
||||
import org.jclouds.googlecomputeengine.domain.InstanceTemplate;
|
||||
import org.jclouds.googlecomputeengine.domain.MachineType;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.domain.Zone;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.logging.Logger;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Named;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.collect.Iterables.contains;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static java.util.concurrent.TimeUnit.MILLISECONDS;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GOOGLE_PROJECT;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_INTERVAL;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.OPERATION_COMPLETE_TIMEOUT;
|
||||
import static org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface.AccessConfig.Type;
|
||||
import static org.jclouds.util.Predicates2.retry;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class GoogleComputeEngineServiceAdapter implements ComputeServiceAdapter<Instance, MachineType, Image, Zone> {
|
||||
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final GoogleComputeEngineApi api;
|
||||
private final Supplier<String> userProject;
|
||||
private final Function<TemplateOptions, ImmutableMap.Builder<String, String>> metatadaFromTemplateOptions;
|
||||
private final Predicate<AtomicReference<Operation>> retryOperationDonePredicate;
|
||||
private final long operationCompleteCheckInterval;
|
||||
private final long operationCompleteCheckTimeout;
|
||||
|
||||
@Inject
|
||||
public GoogleComputeEngineServiceAdapter(GoogleComputeEngineApi api,
|
||||
@UserProject Supplier<String> userProject,
|
||||
Function<TemplateOptions,
|
||||
ImmutableMap.Builder<String, String>> metatadaFromTemplateOptions,
|
||||
Predicate<AtomicReference<Operation>> operationDonePredicate,
|
||||
@Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
|
||||
@Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout) {
|
||||
this.api = checkNotNull(api, "google compute api");
|
||||
this.userProject = checkNotNull(userProject, "user project name");
|
||||
this.metatadaFromTemplateOptions = checkNotNull(metatadaFromTemplateOptions,
|
||||
"metadata from template options function");
|
||||
this.operationCompleteCheckInterval = checkNotNull(operationCompleteCheckInterval,
|
||||
"operation completed check interval");
|
||||
this.operationCompleteCheckTimeout = checkNotNull(operationCompleteCheckTimeout,
|
||||
"operation completed check timeout");
|
||||
this.retryOperationDonePredicate = retry(operationDonePredicate, operationCompleteCheckTimeout,
|
||||
operationCompleteCheckInterval, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeAndInitialCredentials<Instance> createNodeWithGroupEncodedIntoName(
|
||||
final String group, final String name, Template template) {
|
||||
|
||||
checkNotNull(template, "template");
|
||||
|
||||
GoogleComputeEngineTemplateOptions options = GoogleComputeEngineTemplateOptions.class.cast(template.getOptions()).clone();
|
||||
checkState(options.getNetwork().isPresent(), "network was not present in template options");
|
||||
Hardware hardware = checkNotNull(template.getHardware(), "hardware must be set");
|
||||
URI machineType = checkNotNull(hardware.getUri(), "hardware uri must be set");
|
||||
|
||||
InstanceTemplate instanceTemplate = InstanceTemplate.builder()
|
||||
.forMachineType(machineType);
|
||||
|
||||
if (options.isEnableNat()) {
|
||||
instanceTemplate.addNetworkInterface(options.getNetwork().get(), Type.ONE_TO_ONE_NAT);
|
||||
} else {
|
||||
instanceTemplate.addNetworkInterface(options.getNetwork().get());
|
||||
}
|
||||
|
||||
LoginCredentials credentials = getFromImageAndOverrideIfRequired(template.getImage(), options);
|
||||
|
||||
ImmutableMap.Builder<String, String> metadataBuilder = metatadaFromTemplateOptions.apply(options);
|
||||
instanceTemplate.metadata(metadataBuilder.build());
|
||||
instanceTemplate.tags(options.getTags());
|
||||
instanceTemplate.serviceAccounts(options.getServiceAccounts());
|
||||
instanceTemplate.image(checkNotNull(template.getImage().getUri(), "image URI is null"));
|
||||
|
||||
Operation operation = api.getInstanceApiForProject(userProject.get())
|
||||
.createInZone(name, instanceTemplate, template.getLocation().getId());
|
||||
|
||||
if (options.shouldBlockUntilRunning()) {
|
||||
waitOperationDone(operation);
|
||||
}
|
||||
|
||||
// some times the newly created instances are not immediately returned
|
||||
AtomicReference<Instance> instance = new AtomicReference<Instance>();
|
||||
|
||||
retry(new Predicate<AtomicReference<Instance>>() {
|
||||
@Override
|
||||
public boolean apply(AtomicReference<Instance> input) {
|
||||
input.set(api.getInstanceApiForProject(userProject.get()).get(name));
|
||||
return input.get() != null;
|
||||
}
|
||||
}, operationCompleteCheckTimeout, operationCompleteCheckInterval, MILLISECONDS).apply(instance);
|
||||
|
||||
return new NodeAndInitialCredentials<Instance>(instance.get(), name, credentials);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Iterable<MachineType> listHardwareProfiles() {
|
||||
return api.getMachineTypeApiForProject(userProject.get()).list().concat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Image> listImages() {
|
||||
return ImmutableSet.<Image>builder()
|
||||
.addAll(api.getImageApiForProject(userProject.get()).list().concat())
|
||||
.addAll(api.getImageApiForProject(GOOGLE_PROJECT).list().concat())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image getImage(String id) {
|
||||
return Objects.firstNonNull(api.getImageApiForProject(userProject.get()).get(id),
|
||||
api.getImageApiForProject(GOOGLE_PROJECT).get(id));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Zone> listLocations() {
|
||||
return api.getZoneApiForProject(userProject.get()).list().concat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instance getNode(String name) {
|
||||
return api.getInstanceApiForProject(userProject.get()).get(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Instance> listNodes() {
|
||||
return api.getInstanceApiForProject(userProject.get()).list().concat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Instance> listNodesByIds(final Iterable<String> ids) {
|
||||
return filter(listNodes(), new Predicate<Instance>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(Instance instance) {
|
||||
return contains(ids, instance.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyNode(final String name) {
|
||||
waitOperationDone(api.getInstanceApiForProject(userProject.get()).delete(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rebootNode(String name) {
|
||||
throw new UnsupportedOperationException("reboot is not supported by GCE");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeNode(String name) {
|
||||
throw new UnsupportedOperationException("resume is not supported by GCE");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suspendNode(String name) {
|
||||
throw new UnsupportedOperationException("suspend is not supported by GCE");
|
||||
}
|
||||
|
||||
private LoginCredentials getFromImageAndOverrideIfRequired(org.jclouds.compute.domain.Image image,
|
||||
GoogleComputeEngineTemplateOptions options) {
|
||||
LoginCredentials defaultCredentials = image.getDefaultCredentials();
|
||||
String[] keys = defaultCredentials.getPrivateKey().split(":");
|
||||
String publicKey = keys[0];
|
||||
String privateKey = keys[1];
|
||||
|
||||
LoginCredentials.Builder credentialsBuilder = defaultCredentials.toBuilder();
|
||||
credentialsBuilder.privateKey(privateKey);
|
||||
|
||||
// LoginCredentials from image stores the public key along with the private key in the privateKey field
|
||||
// @see GoogleComputePopulateDefaultLoginCredentialsForImageStrategy
|
||||
// so if options doesn't have a public key set we set it from the default
|
||||
if (options.getPublicKey() == null) {
|
||||
options.authorizePublicKey(publicKey);
|
||||
}
|
||||
if (options.hasLoginPrivateKeyOption()) {
|
||||
credentialsBuilder.privateKey(options.getPrivateKey());
|
||||
}
|
||||
if (options.getLoginUser() != null) {
|
||||
credentialsBuilder.identity(options.getLoginUser());
|
||||
}
|
||||
if (options.hasLoginPasswordOption()) {
|
||||
credentialsBuilder.password(options.getLoginPassword());
|
||||
}
|
||||
if (options.shouldAuthenticateSudo() != null) {
|
||||
credentialsBuilder.authenticateSudo(options.shouldAuthenticateSudo());
|
||||
}
|
||||
LoginCredentials credentials = credentialsBuilder.build();
|
||||
options.overrideLoginCredentials(credentials);
|
||||
return credentials;
|
||||
}
|
||||
|
||||
private void waitOperationDone(Operation operation) {
|
||||
AtomicReference<Operation> operationRef = new AtomicReference<Operation>(operation);
|
||||
|
||||
// wait for the operation to complete
|
||||
if (!retryOperationDonePredicate.apply(operationRef)) {
|
||||
throw new UncheckedTimeoutException("operation did not reach DONE state" + operationRef.get());
|
||||
}
|
||||
|
||||
// check if the operation failed
|
||||
if (operationRef.get().getHttpError().isPresent()) {
|
||||
HttpResponse response = operationRef.get().getHttpError().get();
|
||||
throw new IllegalStateException("operation failed. Http Error Code: " + response.getStatusCode() +
|
||||
" HttpError: " + response.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute.config;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.extensions.ImageExtension;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.compute.GoogleComputeEngineService;
|
||||
import org.jclouds.googlecomputeengine.compute.GoogleComputeEngineServiceAdapter;
|
||||
import org.jclouds.googlecomputeengine.compute.functions.BuildInstanceMetadata;
|
||||
import org.jclouds.googlecomputeengine.compute.functions.GoogleComputeEngineImageToImage;
|
||||
import org.jclouds.googlecomputeengine.compute.functions.InstanceToNodeMetadata;
|
||||
import org.jclouds.googlecomputeengine.compute.functions.MachineTypeToHardware;
|
||||
import org.jclouds.googlecomputeengine.compute.functions.OrphanedGroupsFromDeadNodes;
|
||||
import org.jclouds.googlecomputeengine.compute.functions.ZoneToLocation;
|
||||
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
|
||||
import org.jclouds.googlecomputeengine.compute.predicates.AllNodesInGroupTerminated;
|
||||
import org.jclouds.googlecomputeengine.compute.strategy.CreateNodesWithGroupEncodedIntoNameThenAddToSet;
|
||||
import org.jclouds.googlecomputeengine.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy;
|
||||
import org.jclouds.googlecomputeengine.compute.strategy.UseNodeCredentialsButOverrideFromTemplate;
|
||||
import org.jclouds.googlecomputeengine.config.UserProject;
|
||||
import org.jclouds.googlecomputeengine.domain.Image;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance;
|
||||
import org.jclouds.googlecomputeengine.domain.MachineType;
|
||||
import org.jclouds.googlecomputeengine.domain.Zone;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static com.google.common.collect.Maps.uniqueIndex;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class GoogleComputeEngineServiceContextModule
|
||||
extends ComputeServiceAdapterContextModule<Instance, MachineType, Image, Zone> {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
|
||||
bind(ComputeService.class).to(GoogleComputeEngineService.class);
|
||||
|
||||
bind(new TypeLiteral<ComputeServiceAdapter<Instance, MachineType, Image, Zone>>() {})
|
||||
.to(GoogleComputeEngineServiceAdapter.class);
|
||||
|
||||
bind(new TypeLiteral<Function<Instance, NodeMetadata>>() {})
|
||||
.to(InstanceToNodeMetadata.class);
|
||||
|
||||
bind(new TypeLiteral<Function<MachineType, Hardware>>() {})
|
||||
.to(MachineTypeToHardware.class);
|
||||
|
||||
bind(new TypeLiteral<Function<Image, org.jclouds.compute.domain.Image>>() {})
|
||||
.to(GoogleComputeEngineImageToImage.class);
|
||||
|
||||
bind(new TypeLiteral<Function<Zone, Location>>() {})
|
||||
.to(ZoneToLocation.class);
|
||||
|
||||
bind(new TypeLiteral<Function<TemplateOptions, ImmutableMap.Builder<String, String>>>() {})
|
||||
.to(BuildInstanceMetadata.class);
|
||||
|
||||
bind(org.jclouds.compute.strategy.PopulateDefaultLoginCredentialsForImageStrategy.class)
|
||||
.to(PopulateDefaultLoginCredentialsForImageStrategy.class);
|
||||
|
||||
bind(org.jclouds.compute.strategy.impl.CreateNodesWithGroupEncodedIntoNameThenAddToSet.class).to(
|
||||
CreateNodesWithGroupEncodedIntoNameThenAddToSet.class);
|
||||
|
||||
bind(TemplateOptions.class).to(GoogleComputeEngineTemplateOptions.class);
|
||||
|
||||
bind(new TypeLiteral<Function<Set<? extends NodeMetadata>, Set<String>>>() {})
|
||||
.to(OrphanedGroupsFromDeadNodes.class);
|
||||
|
||||
bind(new TypeLiteral<Predicate<String>>() {}).to(AllNodesInGroupTerminated.class);
|
||||
|
||||
bind(PrioritizeCredentialsFromTemplate.class).to(UseNodeCredentialsButOverrideFromTemplate.class);
|
||||
|
||||
install(new LocationsFromComputeServiceAdapterModule<Instance, MachineType, Image, Zone>() {});
|
||||
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Memoized
|
||||
public Supplier<Map<URI, ? extends org.jclouds.compute.domain.Image>> provideImagesMap(
|
||||
final Supplier<Set<? extends org.jclouds.compute.domain.Image>> images) {
|
||||
return new Supplier<Map<URI, ? extends org.jclouds.compute.domain.Image>>() {
|
||||
@Override
|
||||
public Map<URI, ? extends org.jclouds.compute.domain.Image> get() {
|
||||
return uniqueIndex(images.get(), new Function<org.jclouds.compute.domain.Image, URI>() {
|
||||
@Override
|
||||
public URI apply(org.jclouds.compute.domain.Image input) {
|
||||
return input.getUri();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Memoized
|
||||
public Supplier<Map<URI, ? extends Hardware>> provideHardwaresMap(
|
||||
final Supplier<Set<? extends Hardware>> hardwares) {
|
||||
return new Supplier<Map<URI, ? extends Hardware>>() {
|
||||
@Override
|
||||
public Map<URI, ? extends Hardware> get() {
|
||||
return uniqueIndex(hardwares.get(), new Function<Hardware, URI>() {
|
||||
@Override
|
||||
public URI apply(Hardware input) {
|
||||
return input.getUri();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Memoized
|
||||
public Supplier<Map<URI, ? extends Location>> provideLocations(
|
||||
final GoogleComputeEngineApi api, final Function<Zone, Location> zoneToLocation,
|
||||
final @UserProject Supplier<String> userProject) {
|
||||
return new Supplier<Map<URI, ? extends Location>>() {
|
||||
@Override
|
||||
public Map<URI, ? extends Location> get() {
|
||||
return uniqueIndex(transform(api.getZoneApiForProject(userProject.get()).list().concat(), zoneToLocation),
|
||||
new Function<Location, URI>() {
|
||||
@Override
|
||||
public URI apply(Location input) {
|
||||
return (URI) input.getMetadata().get("selfLink");
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Optional<ImageExtension> provideImageExtension(Injector i) {
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static final Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus =
|
||||
ImmutableMap.<Instance.Status, NodeMetadata.Status>builder()
|
||||
.put(Instance.Status.PROVISIONING, NodeMetadata.Status.PENDING)
|
||||
.put(Instance.Status.STAGING, NodeMetadata.Status.PENDING)
|
||||
.put(Instance.Status.RUNNING, NodeMetadata.Status.RUNNING)
|
||||
.put(Instance.Status.STOPPING, NodeMetadata.Status.PENDING)
|
||||
.put(Instance.Status.STOPPED, NodeMetadata.Status.SUSPENDED)
|
||||
.put(Instance.Status.TERMINATED, NodeMetadata.Status.TERMINATED).build();
|
||||
|
||||
@Singleton
|
||||
@Provides
|
||||
protected Map<Instance.Status, NodeMetadata.Status> toPortableNodeStatus() {
|
||||
return toPortableNodeStatus;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute.functions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* Prepares metadata from the provided TemplateOptions
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute.functions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Lists;
|
||||
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 java.util.List;
|
||||
|
||||
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 static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GOOGLE_PROVIDER_LOCATION;
|
||||
|
||||
/**
|
||||
* Transforms a google compute domain specific image to a generic Image object.
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
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)
|
||||
.location(GOOGLE_PROVIDER_LOCATION)
|
||||
.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);
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute.functions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
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.domain.Instance;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Transforms a google compute domain Instance into a generic NodeMetatada object.
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
public class InstanceToNodeMetadata implements Function<Instance, 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;
|
||||
|
||||
@Inject
|
||||
public InstanceToNodeMetadata(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) {
|
||||
this.toPortableNodeStatus = toPortableNodeStatus;
|
||||
this.nodeNamingConvention = namingConvention.createWithoutPrefix();
|
||||
this.images = images;
|
||||
this.hardwares = hardwares;
|
||||
this.locations = locations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeMetadata apply(Instance input) {
|
||||
Map<URI, ? extends Image> imagesMap = images.get();
|
||||
Image image = checkNotNull(imagesMap.get(checkNotNull(input.getImage(), "image")),
|
||||
"no image for %s. images: %s", input.getImage(), imagesMap.values());
|
||||
|
||||
return new NodeMetadataBuilder()
|
||||
.id(input.getName())
|
||||
.name(input.getName())
|
||||
.providerId(input.getId())
|
||||
.hostname(input.getName())
|
||||
.imageId(image.getId())
|
||||
.location(checkNotNull(locations.get().get(input.getZone()), "location for %s", input.getZone()))
|
||||
.hardware(checkNotNull(hardwares.get().get(input.getMachineType()), "hardware type for %s",
|
||||
input.getMachineType().toString()))
|
||||
.operatingSystem(image.getOperatingSystem())
|
||||
.status(toPortableNodeStatus.get(input.getStatus()))
|
||||
.tags(input.getTags())
|
||||
.uri(input.getSelfLink())
|
||||
.userMetadata(input.getMetadata())
|
||||
.group(nodeNamingConvention.groupInUniqueNameOrNull(input.getName()))
|
||||
.privateAddresses(collectPrivateAddresses(input))
|
||||
.publicAddresses(collectPublicAddresses(input))
|
||||
.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();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute.functions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.HardwareBuilder;
|
||||
import org.jclouds.compute.domain.Processor;
|
||||
import org.jclouds.compute.domain.Volume;
|
||||
import org.jclouds.compute.domain.internal.VolumeImpl;
|
||||
import org.jclouds.googlecomputeengine.domain.MachineType;
|
||||
|
||||
/**
|
||||
* Transforms a google compute domain specific machine type to a generic Hardware object.
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
public class MachineTypeToHardware implements Function<MachineType, Hardware> {
|
||||
|
||||
@Override
|
||||
public Hardware apply(MachineType input) {
|
||||
return new HardwareBuilder()
|
||||
.id(input.getName())
|
||||
.name(input.getName())
|
||||
.hypervisor("kvm")
|
||||
.processor(new Processor(input.getGuestCpus(), 1.0))
|
||||
.providerId(input.getId())
|
||||
.ram(input.getMemoryMb())
|
||||
.uri(input.getSelfLink())
|
||||
.volumes(collectVolumes(input))
|
||||
.build();
|
||||
}
|
||||
|
||||
private Iterable<Volume> collectVolumes(MachineType input) {
|
||||
ImmutableSet.Builder<Volume> volumes = ImmutableSet.builder();
|
||||
for (MachineType.EphemeralDisk disk : input.getEphemeralDisks()) {
|
||||
volumes.add(new VolumeImpl(null, Volume.Type.LOCAL, new Integer(disk.getDiskGb()).floatValue(), null, true,
|
||||
false));
|
||||
}
|
||||
return volumes.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute.functions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute.functions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.googlecomputeengine.domain.Zone;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.GOOGLE_PROVIDER_LOCATION;
|
||||
|
||||
/**
|
||||
* Transforms a google compute domain specific zone to a generic Zone object.
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,280 @@
|
|||
package org.jclouds.googlecomputeengine.compute.options;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance;
|
||||
import org.jclouds.scriptbuilder.domain.Statement;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Optional.fromNullable;
|
||||
import static org.jclouds.googlecomputeengine.domain.Instance.ServiceAccount;
|
||||
|
||||
/**
|
||||
* Instance options specific to Google Compute Engine.
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
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;
|
||||
|
||||
@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.network(getNetworkName().orNull());
|
||||
eTo.serviceAccounts(getServiceAccounts());
|
||||
eTo.enableNat(isEnableNat());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #getNetworkName()
|
||||
*/
|
||||
public GoogleComputeEngineTemplateOptions network(String networkName) {
|
||||
this.networkName = fromNullable(networkName);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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 #isEnableNat()
|
||||
*/
|
||||
public GoogleComputeEngineTemplateOptions enableNat(boolean enableNat) {
|
||||
this.enableNat = enableNat;
|
||||
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 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 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.
|
||||
*/
|
||||
public Optional<String> getNetworkName() {
|
||||
return networkName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute.predicates;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@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);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute.strategy;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.ListeningExecutorService;
|
||||
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.strategy.CreateNodeWithGroupEncodedIntoName;
|
||||
import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
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.options.FirewallOptions;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
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 Predicate<AtomicReference<Operation>> operationDonePredicate;
|
||||
private final long operationCompleteCheckInterval;
|
||||
private final long operationCompleteCheckTimeout;
|
||||
|
||||
@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,
|
||||
Predicate<AtomicReference<Operation>> operationDonePredicate,
|
||||
@Named(OPERATION_COMPLETE_INTERVAL) Long operationCompleteCheckInterval,
|
||||
@Named(OPERATION_COMPLETE_TIMEOUT) Long operationCompleteCheckTimeout) {
|
||||
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 = operationDonePredicate;
|
||||
}
|
||||
|
||||
@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);
|
||||
getOrCreateFirewall(templateOptions, network, sharedResourceName);
|
||||
templateOptions.network(network.getSelfLink());
|
||||
|
||||
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);
|
||||
|
||||
// check if the network was previously created (cache???)
|
||||
Network network = api.getNetworkApiForProject(userProject.get()).get(networkName);
|
||||
|
||||
if (network != null) {
|
||||
return network;
|
||||
} else if (templateOptions.getNetwork().isPresent()) {
|
||||
throw new IllegalArgumentException("requested network " + networkName + " does not exist");
|
||||
}
|
||||
|
||||
AtomicReference<Operation> operation = new AtomicReference<Operation>(api.getNetworkApiForProject(userProject
|
||||
.get()).createInIPv4Range(sharedResourceName, DEFAULT_INTERNAL_NETWORK_RANGE));
|
||||
retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
|
||||
MILLISECONDS).apply(operation);
|
||||
|
||||
checkState(!operation.get().getHttpError().isPresent(),"Could not create network, operation failed" + operation);
|
||||
|
||||
return checkNotNull(api.getNetworkApiForProject(userProject.get()).get(sharedResourceName),
|
||||
"no network with name %s was found", sharedResourceName);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to find if a firewall already exists for this group, if not it creates one.
|
||||
*
|
||||
* @see org.jclouds.googlecomputeengine.features.FirewallAsyncApi#patch(String, org.jclouds.googlecomputeengine.options.FirewallOptions)
|
||||
*/
|
||||
private void getOrCreateFirewall(GoogleComputeEngineTemplateOptions templateOptions, Network network,
|
||||
String sharedResourceName) {
|
||||
|
||||
Firewall firewall = api.getFirewallApiForProject(userProject.get()).get(sharedResourceName);
|
||||
|
||||
if (firewall != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ImmutableSet.Builder<Firewall.Rule> rules = ImmutableSet.builder();
|
||||
|
||||
Firewall.Rule.Builder tcpRule = Firewall.Rule.builder();
|
||||
tcpRule.IPProtocol(Firewall.Rule.IPProtocol.TCP);
|
||||
Firewall.Rule.Builder udpRule = Firewall.Rule.builder();
|
||||
udpRule.IPProtocol(Firewall.Rule.IPProtocol.UDP);
|
||||
for (Integer port : templateOptions.getInboundPorts()) {
|
||||
tcpRule.addPort(port);
|
||||
udpRule.addPort(port);
|
||||
}
|
||||
rules.add(tcpRule.build());
|
||||
rules.add(udpRule.build());
|
||||
|
||||
|
||||
FirewallOptions options = new FirewallOptions()
|
||||
.name(sharedResourceName)
|
||||
.network(network.getSelfLink())
|
||||
.sourceTags(templateOptions.getTags())
|
||||
.allowedRules(rules.build())
|
||||
.sourceRanges(of(DEFAULT_INTERNAL_NETWORK_RANGE, EXTERIOR_RANGE));
|
||||
|
||||
AtomicReference<Operation> operation = new AtomicReference<Operation>(api.getFirewallApiForProject(userProject
|
||||
.get()).createInNetwork(
|
||||
sharedResourceName,
|
||||
network.getSelfLink(),
|
||||
options));
|
||||
|
||||
retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval,
|
||||
MILLISECONDS).apply(operation);
|
||||
|
||||
checkState(!operation.get().getHttpError().isPresent(),"Could not create firewall, operation failed" + operation);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute.strategy;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import org.jclouds.compute.domain.TemplateBuilderSpec;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.ssh.internal.RsaSshKeyPairGenerator;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.compute.config.ComputeServiceProperties.TEMPLATE;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@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();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package org.jclouds.googlecomputeengine.compute.strategy;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Singleton;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.options.RunScriptOptions;
|
||||
import org.jclouds.compute.strategy.PrioritizeCredentialsFromTemplate;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* GCE needs the credentials to create the node so the node credentials already take the Image credentials into account,
|
||||
* as such only overriding the TemplateOptions credentials is required.
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
@Singleton
|
||||
public class UseNodeCredentialsButOverrideFromTemplate extends PrioritizeCredentialsFromTemplate {
|
||||
|
||||
|
||||
@Inject
|
||||
public UseNodeCredentialsButOverrideFromTemplate(
|
||||
Function<Template, LoginCredentials> credentialsFromImageOrTemplateOptions) {
|
||||
super(credentialsFromImageOrTemplateOptions);
|
||||
}
|
||||
|
||||
public LoginCredentials apply(Template template, LoginCredentials fromNode) {
|
||||
RunScriptOptions options = checkNotNull(template.getOptions(), "template options are required");
|
||||
LoginCredentials.Builder builder = LoginCredentials.builder(fromNode);
|
||||
if (options.getLoginUser() != null)
|
||||
builder.user(template.getOptions().getLoginUser());
|
||||
if (options.getLoginPassword() != null)
|
||||
builder.password(options.getLoginPassword());
|
||||
if (options.getLoginPrivateKey() != null)
|
||||
builder.privateKey(options.getLoginPrivateKey());
|
||||
if (options.shouldAuthenticateSudo() != null && options.shouldAuthenticateSudo())
|
||||
builder.authenticateSudo(true);
|
||||
return builder.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
/**
|
||||
* 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.googlecomputeengine.config;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.base.Suppliers.compose;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.handlers.GoogleComputeEngineErrorHandler;
|
||||
import org.jclouds.googlecomputeengine.predicates.OperationDonePredicate;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.Uris;
|
||||
import org.jclouds.http.annotation.ClientError;
|
||||
import org.jclouds.http.annotation.Redirection;
|
||||
import org.jclouds.http.annotation.ServerError;
|
||||
import org.jclouds.json.config.GsonModule.DateAdapter;
|
||||
import org.jclouds.json.config.GsonModule.Iso8601DateAdapter;
|
||||
import org.jclouds.location.Provider;
|
||||
import org.jclouds.rest.ConfiguresHttpApi;
|
||||
import org.jclouds.rest.config.HttpApiModule;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.inject.Provides;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
/**
|
||||
* Configures the GoogleCompute connection.
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
@ConfiguresHttpApi
|
||||
public class GoogleComputeEngineHttpApiModule extends HttpApiModule<GoogleComputeEngineApi> {
|
||||
public GoogleComputeEngineHttpApiModule() {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(DateAdapter.class).to(Iso8601DateAdapter.class);
|
||||
bind(new TypeLiteral<Predicate<AtomicReference<Operation>>>() {}).to(OperationDonePredicate.class);
|
||||
super.configure();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void bindErrorHandlers() {
|
||||
bind(HttpErrorHandler.class).annotatedWith(Redirection.class).to(GoogleComputeEngineErrorHandler.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ClientError.class).to(GoogleComputeEngineErrorHandler.class);
|
||||
bind(HttpErrorHandler.class).annotatedWith(ServerError.class).to(GoogleComputeEngineErrorHandler.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@UserProject
|
||||
public Supplier<String> supplyProject(@org.jclouds.location.Provider final Supplier<Credentials> creds) {
|
||||
return compose(new Function<Credentials, String>() {
|
||||
public String apply(Credentials in) {
|
||||
checkState(in.identity.indexOf("@") != 1, "identity should be in project_id@developer.gserviceaccount.com" +
|
||||
" format");
|
||||
return Iterables.get(Splitter.on("@").split(in.identity), 0);
|
||||
}
|
||||
}, creds);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("machineTypes")
|
||||
public Function<String, URI> provideMachineTypeNameToURIFunction(final @Provider Supplier<URI> endpoint,
|
||||
final @UserProject Supplier<String> userProject) {
|
||||
return new Function<String, URI>() {
|
||||
@Override
|
||||
public URI apply(String input) {
|
||||
return Uris.uriBuilder(endpoint.get()).appendPath("/projects/").appendPath(userProject.get()).appendPath
|
||||
("/machineTypes/").appendPath(input).build();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("networks")
|
||||
public Function<String, URI> provideNetworkNameToURIFunction(final @Provider Supplier<URI> endpoint,
|
||||
final @UserProject Supplier<String> userProject) {
|
||||
return new Function<String, URI>() {
|
||||
@Override
|
||||
public URI apply(String input) {
|
||||
return Uris.uriBuilder(endpoint.get()).appendPath("/projects/").appendPath(userProject.get()).appendPath
|
||||
("/networks/").appendPath(input).build();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@Named("zones")
|
||||
public Function<String, URI> provideZoneNameToURIFunction(final @Provider Supplier<URI> endpoint,
|
||||
final @UserProject Supplier<String> userProject) {
|
||||
return new Function<String, URI>() {
|
||||
@Override
|
||||
public URI apply(String input) {
|
||||
return Uris.uriBuilder(endpoint.get()).appendPath("/projects/").appendPath(userProject.get()).appendPath
|
||||
("/zones/").appendPath(input).build();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,375 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.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;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSerializationContext;
|
||||
import com.google.gson.JsonSerializer;
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.Provides;
|
||||
import org.jclouds.googlecomputeengine.domain.Firewall;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance;
|
||||
import org.jclouds.googlecomputeengine.domain.InstanceTemplate;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.domain.Project;
|
||||
import org.jclouds.googlecomputeengine.options.FirewallOptions;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.oauth.v2.domain.ClaimSet;
|
||||
import org.jclouds.oauth.v2.domain.Header;
|
||||
import org.jclouds.oauth.v2.json.ClaimSetTypeAdapter;
|
||||
import org.jclouds.oauth.v2.json.HeaderTypeAdapter;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.domain.Firewall.Rule;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class GoogleComputeEngineParserModule extends AbstractModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(GsonModule.DateAdapter.class).to(GsonModule.Iso8601DateAdapter.class);
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
public Map<Type, Object> provideCustomAdapterBindings() {
|
||||
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(Instance.class, new InstanceTypeAdapter())
|
||||
.put(InstanceTemplate.class, new InstanceTemplateTypeAdapter())
|
||||
.put(FirewallOptions.class, new FirewallOptionsTypeAdapter())
|
||||
.put(Rule.class, new RuleTypeAdapter())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parser for operations that unwraps errors avoiding an extra intermediate object.
|
||||
*
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/operations"/>
|
||||
*/
|
||||
@Singleton
|
||||
private static class OperationTypeAdapter implements JsonDeserializer<Operation> {
|
||||
|
||||
@Override
|
||||
public Operation deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws
|
||||
JsonParseException {
|
||||
Operation.Builder operationBuilder = ((Operation) context.deserialize(json,
|
||||
OperationInternal.class)).toBuilder();
|
||||
JsonObject error = json.getAsJsonObject().getAsJsonObject("error");
|
||||
if (error != null) {
|
||||
JsonArray array = error.getAsJsonArray("errors");
|
||||
if (array != null) {
|
||||
for (JsonElement element : array) {
|
||||
operationBuilder.addError((Operation.Error) context.deserialize(element, Operation.Error.class));
|
||||
}
|
||||
}
|
||||
}
|
||||
return operationBuilder.build();
|
||||
}
|
||||
|
||||
private static class OperationInternal extends Operation {
|
||||
@ConstructorProperties({
|
||||
"id", "creationTimestamp", "selfLink", "name", "description", "targetLink", "targetId",
|
||||
"clientOperationId", "status", "statusMessage", "user", "progress", "insertTime", "startTime",
|
||||
"endTime", "httpErrorStatusCode", "httpErrorMessage", "operationType"
|
||||
})
|
||||
private OperationInternal(String id, Date creationTimestamp, URI selfLink, String name,
|
||||
String description, URI targetLink, String targetId, String clientOperationId,
|
||||
Status status, String statusMessage, String user, int progress, Date insertTime,
|
||||
Date startTime, Date endTime, int httpErrorStatusCode, String httpErrorMessage,
|
||||
String operationType) {
|
||||
super(id, creationTimestamp, selfLink, name, description, targetLink, targetId, clientOperationId,
|
||||
status, statusMessage, user, progress, insertTime, startTime, endTime, httpErrorStatusCode,
|
||||
httpErrorMessage, operationType, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
private static class InstanceTemplateTypeAdapter implements JsonSerializer<InstanceTemplate> {
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(InstanceTemplate src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
InstanceTemplateInternal template = new InstanceTemplateInternal(src);
|
||||
JsonObject instance = (JsonObject) context.serialize(template, InstanceTemplateInternal.class);
|
||||
|
||||
// deal with network
|
||||
JsonArray networkInterfaces = new JsonArray();
|
||||
for (InstanceTemplate.NetworkInterface networkInterface : template.getNetworkInterfaces()){
|
||||
networkInterfaces.add(context.serialize(networkInterface, InstanceTemplate.NetworkInterface.class));
|
||||
}
|
||||
instance.add("networkInterfaces", networkInterfaces);
|
||||
|
||||
// deal with persistent disks
|
||||
if (src.getDisks() != null && !src.getDisks().isEmpty()) {
|
||||
JsonArray disks = new JsonArray();
|
||||
for (InstanceTemplate.PersistentDisk persistentDisk : src.getDisks()) {
|
||||
JsonObject disk = (JsonObject) context.serialize(persistentDisk, InstanceTemplate.PersistentDisk.class);
|
||||
disk.addProperty("type", "PERSISTENT");
|
||||
disks.add(disk);
|
||||
}
|
||||
instance.add("disks", disks);
|
||||
}
|
||||
|
||||
// deal with metadata
|
||||
if (src.getMetadata() != null && !src.getMetadata().isEmpty()) {
|
||||
JsonObject metadata = (JsonObject) context.serialize(new Metadata(src.getMetadata()));
|
||||
instance.add("metadata", metadata);
|
||||
return instance;
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static class InstanceTemplateInternal extends InstanceTemplate {
|
||||
private InstanceTemplateInternal(InstanceTemplate template) {
|
||||
super(template.getMachineType());
|
||||
name(template.getName());
|
||||
description(template.getDescription());
|
||||
zone(template.getZone());
|
||||
image(template.getImage());
|
||||
tags(template.getTags());
|
||||
serviceAccounts(template.getServiceAccounts());
|
||||
networkInterfaces(template.getNetworkInterfaces());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
private static class InstanceTypeAdapter implements JsonDeserializer<Instance> {
|
||||
|
||||
@Override
|
||||
public Instance deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws
|
||||
JsonParseException {
|
||||
Instance.Builder instanceBuilder = ((Instance) context.deserialize(json,
|
||||
InstanceInternal.class)).toBuilder();
|
||||
JsonObject object = (JsonObject) json;
|
||||
if (object.get("disks") != null) {
|
||||
JsonArray disks = (JsonArray) object.get("disks");
|
||||
for (JsonElement element : disks) {
|
||||
JsonObject disk = (JsonObject) element;
|
||||
if (disk.get("type").getAsString().equals("PERSISTENT")) {
|
||||
instanceBuilder.addDisk((Instance.PersistentAttachedDisk) context.deserialize(disk,
|
||||
Instance.PersistentAttachedDisk.class));
|
||||
} else {
|
||||
instanceBuilder.addDisk((Instance.AttachedDisk) context.deserialize(disk,
|
||||
Instance.AttachedDisk.class));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return Instance.builder().fromInstance(instanceBuilder.build()).build();
|
||||
}
|
||||
|
||||
|
||||
private static class InstanceInternal extends Instance {
|
||||
@ConstructorProperties({
|
||||
"id", "creationTimestamp", "selfLink", "name", "description", "tags", "image", "machineType",
|
||||
"status", "statusMessage", "zone", "networkInterfaces", "metadata", "serviceAccounts"
|
||||
})
|
||||
private InstanceInternal(String id, Date creationTimestamp, URI selfLink, String name, String description,
|
||||
Set<String> tags, URI image, URI machineType, Status status, String statusMessage,
|
||||
URI zone, Set<NetworkInterface> networkInterfaces, Metadata metadata,
|
||||
Set<ServiceAccount> serviceAccounts) {
|
||||
super(id, creationTimestamp, selfLink, name, description, tags, image, machineType,
|
||||
status, statusMessage, zone, networkInterfaces, null, metadata, serviceAccounts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parser for Metadata.
|
||||
*/
|
||||
@Singleton
|
||||
private static class MetadataTypeAdapter implements JsonDeserializer<Metadata>, JsonSerializer<Metadata> {
|
||||
|
||||
|
||||
@Override
|
||||
public Metadata deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws
|
||||
JsonParseException {
|
||||
ImmutableMap.Builder<String, String> builder = ImmutableMap.builder();
|
||||
JsonObject metadata = json.getAsJsonObject();
|
||||
JsonArray items = metadata.getAsJsonArray("items");
|
||||
if (items != null) {
|
||||
for (JsonElement element : items) {
|
||||
JsonObject object = element.getAsJsonObject();
|
||||
builder.put(object.get("key").getAsString(), object.get("value").getAsString());
|
||||
}
|
||||
}
|
||||
return new Metadata(builder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(Metadata src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject metadataObject = new JsonObject();
|
||||
metadataObject.add("kind", new JsonPrimitive("compute#metadata"));
|
||||
JsonArray items = new JsonArray();
|
||||
for (Map.Entry<String, String> entry : src.entrySet()) {
|
||||
JsonObject object = new JsonObject();
|
||||
object.addProperty("key", entry.getKey());
|
||||
object.addProperty("value", entry.getValue());
|
||||
items.add(object);
|
||||
}
|
||||
metadataObject.add("items", items);
|
||||
return metadataObject;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Metadata extends ForwardingMap<String, String> {
|
||||
|
||||
private final Map<String, String> delegate;
|
||||
|
||||
public Metadata(Map<String, String> delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Map<String, String> delegate() {
|
||||
return delegate;
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
private static class ProjectTypeAdapter implements JsonDeserializer<Project> {
|
||||
|
||||
@Override
|
||||
public Project deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws
|
||||
JsonParseException {
|
||||
return Project.builder().fromProject((Project) context.deserialize(json, ProjectInternal.class)).build();
|
||||
}
|
||||
|
||||
private static class ProjectInternal extends Project {
|
||||
|
||||
@ConstructorProperties({
|
||||
"id", "creationTimestamp", "selfLink", "name", "description", "commonInstanceMetadata", "quotas",
|
||||
"externalIpAddresses"
|
||||
})
|
||||
private ProjectInternal(String id, Date creationTimestamp, URI selfLink, String name, String description,
|
||||
Metadata commonInstanceMetadata, Set<Quota> quotas, Set<String> externalIpAddresses) {
|
||||
super(id, creationTimestamp, selfLink, name, description, commonInstanceMetadata, quotas,
|
||||
externalIpAddresses);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Singleton
|
||||
private static class FirewallOptionsTypeAdapter implements JsonSerializer<FirewallOptions> {
|
||||
|
||||
@Override
|
||||
public JsonElement serialize(FirewallOptions src, Type typeOfSrc, JsonSerializationContext context) {
|
||||
JsonObject firewall = new JsonObject();
|
||||
if (src.getName() != null) {
|
||||
firewall.addProperty("name", src.getName());
|
||||
}
|
||||
if (src.getNetwork() != null) {
|
||||
firewall.addProperty("network", src.getNetwork().toString());
|
||||
}
|
||||
if (!src.getSourceRanges().isEmpty()) {
|
||||
firewall.add("sourceRanges", buildArrayOfStrings(src.getSourceRanges()));
|
||||
}
|
||||
if (!src.getSourceTags().isEmpty()) {
|
||||
firewall.add("sourceTags", buildArrayOfStrings(src.getSourceTags()));
|
||||
}
|
||||
if (!src.getTargetTags().isEmpty()) {
|
||||
firewall.add("targetTags", buildArrayOfStrings(src.getTargetTags()));
|
||||
}
|
||||
if (!src.getAllowed().isEmpty()) {
|
||||
JsonArray rules = new JsonArray();
|
||||
for (Rule rule : src.getAllowed()) {
|
||||
rules.add(context.serialize(rule, Firewall.Rule.class));
|
||||
}
|
||||
firewall.add("allowed", rules);
|
||||
}
|
||||
return firewall;
|
||||
}
|
||||
}
|
||||
|
||||
private static JsonArray buildArrayOfStrings(Set<String> strings) {
|
||||
JsonArray array = new JsonArray();
|
||||
for (String string : strings) {
|
||||
array.add(new JsonPrimitive(string));
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.config;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.oauth.v2.config.OAuthModule;
|
||||
import org.jclouds.oauth.v2.domain.OAuthCredentials;
|
||||
import org.jclouds.oauth.v2.domain.Token;
|
||||
import org.jclouds.oauth.v2.domain.TokenRequest;
|
||||
import org.jclouds.oauth.v2.functions.BuildTokenRequest;
|
||||
import org.jclouds.oauth.v2.functions.FetchToken;
|
||||
import org.jclouds.oauth.v2.functions.OAuthCredentialsSupplier;
|
||||
import org.jclouds.oauth.v2.functions.SignOrProduceMacForToken;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
|
||||
/**
|
||||
* Overrides OAuthModule leaving TypeAdapters bindings out.
|
||||
* <p/>
|
||||
* TODO overcome this by using multibindings on GSonModule?
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
public class OAuthModuleWithoutTypeAdapters extends OAuthModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
bind(new TypeLiteral<Function<byte[], byte[]>>() {}).to(SignOrProduceMacForToken.class);
|
||||
bind(new TypeLiteral<Supplier<OAuthCredentials>>() {}).to(OAuthCredentialsSupplier.class);
|
||||
bind(new TypeLiteral<Function<GeneratedHttpRequest, TokenRequest>>() {}).to(BuildTokenRequest.class);
|
||||
bind(new TypeLiteral<Function<TokenRequest, Token>>() {}).to(FetchToken.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.config;
|
||||
|
||||
import javax.inject.Qualifier;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Qualifies a property as the user's project id.
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
@Retention(value = RetentionPolicy.RUNTIME)
|
||||
@Target(value = {ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
|
||||
@Qualifier
|
||||
public @interface UserProject {
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.domain;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* A persistent disk resource
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/disks"/>
|
||||
*/
|
||||
@Beta
|
||||
public final class Disk extends Resource {
|
||||
|
||||
private final Integer sizeGb;
|
||||
private final URI zone;
|
||||
private final String status;
|
||||
|
||||
@ConstructorProperties({
|
||||
"id", "creationTimestamp", "selfLink", "name", "description", "sizeGb", "zone",
|
||||
"status"
|
||||
})
|
||||
private Disk(String id, Date creationTimestamp, URI selfLink, String name, String description,
|
||||
Integer sizeGb, URI zone, String status) {
|
||||
super(Kind.DISK, id, creationTimestamp, selfLink, name, description);
|
||||
this.sizeGb = checkNotNull(sizeGb, "sizeGb of %s", name);
|
||||
this.zone = checkNotNull(zone, "zone of %s", name);
|
||||
this.status = checkNotNull(status, "status of %s", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return size of the persistent disk, specified in GB.
|
||||
*/
|
||||
public int getSizeGb() {
|
||||
return sizeGb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return URL for the zone where the persistent disk resides.
|
||||
*/
|
||||
public URI getZone() {
|
||||
return zone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the status of disk creation.
|
||||
*/
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
return super.string()
|
||||
.omitNullValues()
|
||||
.add("sizeGb", sizeGb)
|
||||
.add("zone", zone)
|
||||
.add("status", status);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return new Builder().fromDisk(this);
|
||||
}
|
||||
|
||||
public static final class Builder extends Resource.Builder<Builder> {
|
||||
|
||||
private Integer sizeGb;
|
||||
private URI zone;;
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* @see Disk#getSizeGb()
|
||||
*/
|
||||
public Builder sizeGb(Integer sizeGb) {
|
||||
this.sizeGb = sizeGb;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Disk#getZone()
|
||||
*/
|
||||
public Builder zone(URI zone) {
|
||||
this.zone = zone;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Disk#getStatus()
|
||||
*/
|
||||
public Builder status(String status) {
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Builder self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Disk build() {
|
||||
return new Disk(super.id, super.creationTimestamp, super.selfLink, super.name,
|
||||
super.description, sizeGb, zone, status);
|
||||
}
|
||||
|
||||
public Builder fromDisk(Disk in) {
|
||||
return super.fromResource(in)
|
||||
.sizeGb(in.getSizeGb())
|
||||
.zone(in.getZone())
|
||||
.status(in.getStatus());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,395 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.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.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, creationTimestamp, selfLink, name, 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.googlecomputeengine.domain.Firewall.Rule#getIPProtocol()
|
||||
*/
|
||||
public Builder IPProtocol(IPProtocol IPProtocol) {
|
||||
this.ipProtocol = IPProtocol;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall.Rule#getPorts()
|
||||
*/
|
||||
public Builder addPort(Integer port) {
|
||||
this.ports.add(singleton(checkNotNull(port, "port")));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.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.googlecomputeengine.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,290 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.domain;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Represents a disk image to use on an instance.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/images"/>
|
||||
*/
|
||||
@Beta
|
||||
public final class Image extends Resource {
|
||||
|
||||
private final String sourceType;
|
||||
private final Optional<URI> preferredKernel;
|
||||
private final RawDisk rawDisk;
|
||||
|
||||
@ConstructorProperties({
|
||||
"id", "creationTimestamp", "selfLink", "name", "description", "sourceType", "preferredKernel",
|
||||
"rawDisk"
|
||||
})
|
||||
protected Image(String id, Date creationTimestamp, URI selfLink, String name, String description,
|
||||
String sourceType, URI preferredKernel, RawDisk rawDisk) {
|
||||
super(Kind.IMAGE, id, creationTimestamp, selfLink, name, description);
|
||||
this.sourceType = checkNotNull(sourceType, "sourceType of %s", name);
|
||||
this.preferredKernel = fromNullable(preferredKernel);
|
||||
this.rawDisk = checkNotNull(rawDisk, "rawDisk of %s", name); ;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return must be RAW; provided by the client when the disk image is created.
|
||||
*/
|
||||
public String getSourceType() {
|
||||
return sourceType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An optional URL of the preferred kernel for use with this disk image.
|
||||
*/
|
||||
public Optional<URI> getPreferredKernel() {
|
||||
return preferredKernel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the raw disk image parameters.
|
||||
*/
|
||||
public RawDisk getRawDisk() {
|
||||
return rawDisk;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
return super.string()
|
||||
.omitNullValues()
|
||||
.add("sourceType", sourceType)
|
||||
.add("preferredKernel", preferredKernel.orNull())
|
||||
.add("rawDisk", rawDisk);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return new Builder().fromImage(this);
|
||||
}
|
||||
|
||||
public static final class Builder extends Resource.Builder<Builder> {
|
||||
|
||||
private String sourceType;
|
||||
private URI preferredKernel;
|
||||
private RawDisk rawDisk;
|
||||
|
||||
/**
|
||||
* @see Image#getSourceType()
|
||||
*/
|
||||
public Builder sourceType(String sourceType) {
|
||||
this.sourceType = checkNotNull(sourceType, "sourceType");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Image#getPreferredKernel()
|
||||
*/
|
||||
public Builder preferredKernel(URI preferredKernel) {
|
||||
this.preferredKernel = preferredKernel;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Image#getRawDisk()
|
||||
*/
|
||||
public Builder rawDisk(RawDisk rawDisk) {
|
||||
this.rawDisk = checkNotNull(rawDisk);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Builder self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Image build() {
|
||||
return new Image(super.id, super.creationTimestamp, super.selfLink, super.name,
|
||||
super.description, sourceType, preferredKernel, rawDisk);
|
||||
}
|
||||
|
||||
public Builder fromImage(Image in) {
|
||||
return super.fromResource(in)
|
||||
.sourceType(in.getSourceType())
|
||||
.preferredKernel(in.getPreferredKernel().orNull())
|
||||
.rawDisk(in.getRawDisk());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A raw disk image, usually the base for an image.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/images"/>
|
||||
*/
|
||||
public static class RawDisk {
|
||||
|
||||
private final String source;
|
||||
private final String containerType;
|
||||
private final Optional<String> sha1Checksum;
|
||||
|
||||
@ConstructorProperties({
|
||||
"source", "containerType", "sha1Checksum"
|
||||
})
|
||||
private RawDisk(String source, String containerType, String sha1Checksum) {
|
||||
this.source = checkNotNull(source, "source");
|
||||
this.containerType = checkNotNull(containerType, "containerType");
|
||||
this.sha1Checksum = fromNullable(sha1Checksum);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the full Google Cloud Storage URL where the disk image is stored; provided by the client when the disk
|
||||
* image is created.
|
||||
*/
|
||||
public String getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the format used to encode and transmit the block device.
|
||||
*/
|
||||
public String getContainerType() {
|
||||
return containerType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an optional SHA1 checksum of the disk image before unpackaging; provided by the client when the disk
|
||||
* image is created.
|
||||
*/
|
||||
public Optional<String> getSha1Checksum() {
|
||||
return sha1Checksum;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(source, containerType, sha1Checksum);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null || getClass() != obj.getClass()) return false;
|
||||
RawDisk that = RawDisk.class.cast(obj);
|
||||
return equal(this.source, that.source)
|
||||
&& equal(this.containerType, that.containerType)
|
||||
&& equal(this.sha1Checksum, that.sha1Checksum);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
return toStringHelper(this)
|
||||
.omitNullValues()
|
||||
.add("source", source)
|
||||
.add("containerType", containerType)
|
||||
.add("sha1Checksum", sha1Checksum.orNull());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return builder().fromImageRawDisk(this);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private String source;
|
||||
private String containerType;
|
||||
private String sha1Checksum;
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Image.RawDisk#getSource()
|
||||
*/
|
||||
public Builder source(String source) {
|
||||
this.source = checkNotNull(source);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Image.RawDisk#getContainerType()
|
||||
*/
|
||||
public Builder containerType(String containerType) {
|
||||
this.containerType = checkNotNull(containerType);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Image.RawDisk#getSha1Checksum()
|
||||
*/
|
||||
public Builder sha1Checksum(String sha1Checksum) {
|
||||
this.sha1Checksum = sha1Checksum;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RawDisk build() {
|
||||
return new RawDisk(source, containerType, sha1Checksum);
|
||||
}
|
||||
|
||||
public Builder fromImageRawDisk(RawDisk rawDisk) {
|
||||
return new Builder().source(rawDisk.getSource())
|
||||
.containerType(rawDisk.getContainerType())
|
||||
.sha1Checksum(rawDisk.getSha1Checksum().orNull());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,483 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.domain;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Objects.equal;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.googlecomputeengine.domain.Instance.NetworkInterface.AccessConfig.Type;
|
||||
|
||||
/**
|
||||
* Optional information for creating an instance.
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
public class InstanceTemplate {
|
||||
|
||||
protected String name;
|
||||
protected String description;
|
||||
protected URI machineType;
|
||||
protected URI zone;
|
||||
protected URI image;
|
||||
protected Set<String> tags = Sets.newLinkedHashSet();
|
||||
protected Set<Instance.ServiceAccount> serviceAccounts = Sets.newLinkedHashSet();
|
||||
|
||||
protected transient Set<PersistentDisk> disks = Sets.newLinkedHashSet();
|
||||
protected transient Set<NetworkInterface> networkInterfaces = Sets.newLinkedHashSet();
|
||||
protected transient Map<String, String> metadata = Maps.newLinkedHashMap();
|
||||
protected transient String machineTypeName;
|
||||
protected transient String zoneName;
|
||||
|
||||
|
||||
protected InstanceTemplate(URI machineType) {
|
||||
this.machineType = checkNotNull(machineType, "machineType");
|
||||
}
|
||||
|
||||
protected InstanceTemplate(String machineTypeName) {
|
||||
this.machineTypeName = checkNotNull(machineTypeName, "machineTypeName");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getName()
|
||||
*/
|
||||
public InstanceTemplate name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getDescription()
|
||||
*/
|
||||
public InstanceTemplate description(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getImage()
|
||||
*/
|
||||
public InstanceTemplate image(URI image) {
|
||||
this.image = image;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getMachineType()
|
||||
*/
|
||||
public InstanceTemplate machineType(URI machineType) {
|
||||
this.machineType = machineType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getMachineType()
|
||||
*/
|
||||
public InstanceTemplate machineType(String machineTypeName) {
|
||||
this.machineTypeName = machineTypeName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getZone()
|
||||
*/
|
||||
public InstanceTemplate zone(String zoneName) {
|
||||
this.zoneName = zoneName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getZone()
|
||||
*/
|
||||
public InstanceTemplate zone(URI zone) {
|
||||
this.zone = zone;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getTags()
|
||||
*/
|
||||
public InstanceTemplate addTag(String tag) {
|
||||
this.tags.add(checkNotNull(tag, "tag"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getTags()
|
||||
*/
|
||||
public InstanceTemplate tags(Set<String> tags) {
|
||||
this.tags = Sets.newLinkedHashSet();
|
||||
this.tags.addAll(checkNotNull(tags, "tags"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getDisks()
|
||||
*/
|
||||
public InstanceTemplate addDisk(PersistentDisk.Mode mode, URI source) {
|
||||
this.disks.add(new PersistentDisk(mode, source, null, null));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getDisks()
|
||||
*/
|
||||
public InstanceTemplate addDisk(PersistentDisk.Mode mode, URI source, String deviceName, Boolean deleteOnTerminate) {
|
||||
this.disks.add(new PersistentDisk(mode, source, deviceName, deleteOnTerminate));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getDisks()
|
||||
*/
|
||||
public InstanceTemplate disks(Set<PersistentDisk> disks) {
|
||||
this.disks = Sets.newLinkedHashSet();
|
||||
this.disks.addAll(checkNotNull(disks, "disks"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getNetworkInterfaces()
|
||||
*/
|
||||
public InstanceTemplate addNetworkInterface(URI network) {
|
||||
this.networkInterfaces.add(new NetworkInterface(checkNotNull(network, "network"), null,null));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getNetworkInterfaces()
|
||||
*/
|
||||
public InstanceTemplate addNetworkInterface(URI network, Type type) {
|
||||
this.networkInterfaces.add(new NetworkInterface(checkNotNull(network, "network"), null,
|
||||
ImmutableSet.of(Instance.NetworkInterface.AccessConfig.builder()
|
||||
.type(type)
|
||||
.build())));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getNetworkInterfaces()
|
||||
*/
|
||||
public InstanceTemplate addNetworkInterface(NetworkInterface networkInterface) {
|
||||
this.networkInterfaces.add(networkInterface);
|
||||
return this;
|
||||
}
|
||||
|
||||
public InstanceTemplate networkInterfaces(Set<NetworkInterface> networkInterfaces) {
|
||||
this.networkInterfaces = Sets.newLinkedHashSet(networkInterfaces);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getMetadata()
|
||||
*/
|
||||
public InstanceTemplate addMetadata(String key, String value) {
|
||||
this.metadata.put(checkNotNull(key, "key"), checkNotNull(value, "value of %", key));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getMetadata()
|
||||
*/
|
||||
public InstanceTemplate metadata(Map<String, String> metadata) {
|
||||
this.metadata = Maps.newLinkedHashMap();
|
||||
this.metadata.putAll(checkNotNull(metadata, "metadata"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getServiceAccounts()
|
||||
*/
|
||||
public InstanceTemplate addServiceAccount(Instance.ServiceAccount serviceAccount) {
|
||||
this.serviceAccounts.add(checkNotNull(serviceAccount, "serviceAccount"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getServiceAccounts()
|
||||
*/
|
||||
public InstanceTemplate serviceAccounts(Set<Instance.ServiceAccount> serviceAccounts) {
|
||||
this.serviceAccounts = Sets.newLinkedHashSet();
|
||||
this.serviceAccounts.addAll(checkNotNull(serviceAccounts, "serviceAccounts"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getDescription()
|
||||
*/
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getDisks()
|
||||
*/
|
||||
public Set<PersistentDisk> getDisks() {
|
||||
return disks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getImage()
|
||||
*/
|
||||
public URI getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getMachineType()
|
||||
*/
|
||||
public URI getMachineType() {
|
||||
return machineType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getMachineType()
|
||||
*/
|
||||
public String getMachineTypeName() {
|
||||
return machineTypeName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getMetadata()
|
||||
*/
|
||||
public Map<String, String> getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getNetworkInterfaces()
|
||||
*/
|
||||
public Set<NetworkInterface> getNetworkInterfaces() {
|
||||
return networkInterfaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getServiceAccounts()
|
||||
*/
|
||||
public Set<Instance.ServiceAccount> getServiceAccounts() {
|
||||
return serviceAccounts;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getTags()
|
||||
*/
|
||||
public Set<String> getTags() {
|
||||
return tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getZone()
|
||||
*/
|
||||
public URI getZone() {
|
||||
return zone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Instance#getZone()
|
||||
*/
|
||||
public String getZoneName() {
|
||||
return zoneName;
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static InstanceTemplate fromInstanceTemplate(InstanceTemplate instanceTemplate) {
|
||||
return Builder.fromInstanceTemplate(instanceTemplate);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
public InstanceTemplate forMachineType(URI machineType) {
|
||||
return new InstanceTemplate(machineType);
|
||||
}
|
||||
|
||||
public InstanceTemplate forMachineType(String machineTypeName) {
|
||||
return new InstanceTemplate(machineTypeName);
|
||||
}
|
||||
|
||||
public static InstanceTemplate fromInstanceTemplate(InstanceTemplate instanceTemplate) {
|
||||
return InstanceTemplate.builder()
|
||||
.forMachineType(instanceTemplate.getMachineType())
|
||||
.networkInterfaces(instanceTemplate.getNetworkInterfaces())
|
||||
.name(instanceTemplate.getName())
|
||||
.description(instanceTemplate.getDescription())
|
||||
.zone(instanceTemplate.getZone())
|
||||
.image(instanceTemplate.getImage())
|
||||
.tags(instanceTemplate.getTags())
|
||||
.disks(instanceTemplate.getDisks())
|
||||
.metadata(instanceTemplate.getMetadata())
|
||||
.serviceAccounts(instanceTemplate.getServiceAccounts());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class PersistentDisk {
|
||||
|
||||
public enum Mode {
|
||||
READ_WRITE,
|
||||
READ_ONLY
|
||||
}
|
||||
|
||||
public PersistentDisk(Mode mode, URI source, String deviceName, Boolean deleteOnTerminate) {
|
||||
this.mode = checkNotNull(mode, "mode");
|
||||
this.source = checkNotNull(source, "source");
|
||||
this.deviceName = deviceName;
|
||||
this.deleteOnTerminate = deleteOnTerminate;
|
||||
}
|
||||
|
||||
private final Mode mode;
|
||||
private final URI source;
|
||||
private final Boolean deleteOnTerminate;
|
||||
private final String deviceName;
|
||||
|
||||
/**
|
||||
* @return the mode in which to attach this disk, either READ_WRITE or READ_ONLY.
|
||||
*/
|
||||
public Mode getMode() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the URL of the persistent disk resource.
|
||||
*/
|
||||
public URI getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Must be unique within the instance when specified. This represents a unique
|
||||
* device name that is reflected into the /dev/ tree of a Linux operating system running within the
|
||||
* instance. If not specified, a default will be chosen by the system.
|
||||
*/
|
||||
public String getDeviceName() {
|
||||
return deviceName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return If true, delete the disk and all its data when the associated instance is deleted.
|
||||
*/
|
||||
public boolean isDeleteOnTerminate() {
|
||||
return deleteOnTerminate;
|
||||
}
|
||||
}
|
||||
|
||||
public static class NetworkInterface {
|
||||
|
||||
private final URI network;
|
||||
private final String networkIP;
|
||||
private final Set<Instance.NetworkInterface.AccessConfig> accessConfigs;
|
||||
|
||||
public NetworkInterface(URI network, String networkIP, Set<Instance.NetworkInterface.AccessConfig>
|
||||
accessConfigs) {
|
||||
this.networkIP = networkIP;
|
||||
this.network = network;
|
||||
this.accessConfigs = accessConfigs != null ? accessConfigs : ImmutableSet.<Instance.NetworkInterface.AccessConfig>of();
|
||||
}
|
||||
|
||||
public Set<Instance.NetworkInterface.AccessConfig> getAccessConfigs() {
|
||||
return accessConfigs;
|
||||
}
|
||||
|
||||
public URI getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
public String getNetworkIP() {
|
||||
return networkIP;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (this == object) {
|
||||
return true;
|
||||
}
|
||||
if (object instanceof InstanceTemplate) {
|
||||
final InstanceTemplate other = InstanceTemplate.class.cast(object);
|
||||
return equal(description, other.description)
|
||||
&& equal(tags, other.tags)
|
||||
&& equal(image, other.image)
|
||||
&& equal(disks, other.disks)
|
||||
&& equal(networkInterfaces, other.networkInterfaces)
|
||||
&& equal(metadata, other.metadata)
|
||||
&& equal(serviceAccounts, other.serviceAccounts);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(description, tags, image, disks, networkInterfaces, metadata, serviceAccounts);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
Objects.ToStringHelper toString = Objects.toStringHelper("")
|
||||
.omitNullValues();
|
||||
toString.add("description", description);
|
||||
if (tags.size() > 0)
|
||||
toString.add("tags", tags);
|
||||
if (disks.size() > 0)
|
||||
toString.add("disks", disks);
|
||||
if (metadata.size() > 0)
|
||||
toString.add("metadata", metadata);
|
||||
if (serviceAccounts.size() > 0)
|
||||
toString.add("serviceAccounts", serviceAccounts);
|
||||
toString.add("image", image);
|
||||
toString.add("networkInterfaces", networkInterfaces);
|
||||
return toString;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.domain;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Represents a kernel.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/kernels"/>
|
||||
*/
|
||||
@Beta
|
||||
public final class Kernel extends Resource {
|
||||
|
||||
@ConstructorProperties({
|
||||
"id", "creationTimestamp", "selfLink", "name", "description"
|
||||
})
|
||||
private Kernel(String id, Date creationTimestamp, URI selfLink, String name, String description) {
|
||||
super(Kind.KERNEL, id, creationTimestamp, selfLink, name, description);
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return new Builder().fromKernel(this);
|
||||
}
|
||||
|
||||
public static final class Builder extends Resource.Builder<Builder> {
|
||||
|
||||
@Override
|
||||
protected Builder self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Kernel build() {
|
||||
return new Kernel(super.id, super.creationTimestamp, super.selfLink, super.name,
|
||||
super.description);
|
||||
}
|
||||
|
||||
public Builder fromKernel(Kernel in) {
|
||||
return super.fromResource(in);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,183 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.domain;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.net.URI;
|
||||
import java.util.Iterator;
|
||||
|
||||
import static com.google.common.base.Objects.equal;
|
||||
import static com.google.common.base.Objects.toStringHelper;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.googlecomputeengine.domain.Resource.Kind;
|
||||
|
||||
/**
|
||||
* The collection returned from any <code>listFirstPage()</code> method.
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
public class ListPage<T> extends IterableWithMarker<T> {
|
||||
|
||||
private final Kind kind;
|
||||
private final String id;
|
||||
private final URI selfLink;
|
||||
private final String nextPageToken;
|
||||
private final Iterable<T> items;
|
||||
|
||||
@ConstructorProperties({
|
||||
"kind", "id", "selfLink", "nextPageToken", "items"
|
||||
})
|
||||
protected ListPage(Kind kind, String id, URI selfLink, String nextPageToken, Iterable<T> items) {
|
||||
this.id = checkNotNull(id, "id");
|
||||
this.kind = checkNotNull(kind, "kind of %id", id);
|
||||
this.selfLink = checkNotNull(selfLink, "selfLink of %id", id);
|
||||
this.nextPageToken = nextPageToken;
|
||||
this.items = items != null ? ImmutableSet.copyOf(items) : ImmutableSet.<T>of();
|
||||
}
|
||||
|
||||
public Kind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public URI getSelfLink() {
|
||||
return selfLink;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Object> nextMarker() {
|
||||
return Optional.<Object>fromNullable(nextPageToken);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return checkNotNull(items, "items").iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(kind, id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null || getClass() != obj.getClass()) return false;
|
||||
ListPage<?> that = ListPage.class.cast(obj);
|
||||
return equal(this.kind, that.kind)
|
||||
&& equal(this.id, that.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
return toStringHelper(this)
|
||||
.omitNullValues()
|
||||
.add("kind", kind)
|
||||
.add("id", id)
|
||||
.add("selfLink", selfLink)
|
||||
.add("nextPageToken", nextPageToken)
|
||||
.add("items", items);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static <T> Builder<T> builder() {
|
||||
return new Builder<T>();
|
||||
}
|
||||
|
||||
public Builder<T> toBuilder() {
|
||||
return new Builder<T>().fromPagedList(this);
|
||||
}
|
||||
|
||||
public static final class Builder<T> {
|
||||
|
||||
private Kind kind;
|
||||
private String id;
|
||||
private URI selfLink;
|
||||
private String nextPageToken;
|
||||
private ImmutableSet.Builder<T> items = ImmutableSet.builder();
|
||||
|
||||
public Builder<T> kind(Kind kind) {
|
||||
this.kind = kind;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> id(String id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> selfLink(URI selfLink) {
|
||||
this.selfLink = selfLink;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> addItem(T item) {
|
||||
this.items.add(item);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> items(Iterable<T> items) {
|
||||
this.items.addAll(items);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> nextPageToken(String nextPageToken) {
|
||||
this.nextPageToken = nextPageToken;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ListPage<T> build() {
|
||||
return new ListPage<T>(kind, id, selfLink, nextPageToken, items.build());
|
||||
}
|
||||
|
||||
public Builder<T> fromPagedList(ListPage<T> in) {
|
||||
return this
|
||||
.kind(in.getKind())
|
||||
.id(in.getId())
|
||||
.selfLink(in.getSelfLink())
|
||||
.nextPageToken((String) in.nextMarker().orNull())
|
||||
.items(in);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.domain;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
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.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Represents a machine type used to host an instance.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/machineTypes"/>
|
||||
*/
|
||||
@Beta
|
||||
public final class MachineType extends Resource {
|
||||
|
||||
private final Integer guestCpus;
|
||||
private final Integer memoryMb;
|
||||
private final Integer imageSpaceGb;
|
||||
private final List<EphemeralDisk> ephemeralDisks;
|
||||
private final Integer maximumPersistentDisks;
|
||||
private final Long maximumPersistentDisksSizeGb;
|
||||
private final Set<String> availableZone;
|
||||
|
||||
@ConstructorProperties({
|
||||
"id", "creationTimestamp", "selfLink", "name", "description", "guestCpus", "memoryMb",
|
||||
"imageSpaceGb", "ephemeralDisks", "maximumPersistentDisks", "maximumPersistentDisksSizeGb", "availableZone"
|
||||
})
|
||||
private MachineType(String id, Date creationTimestamp, URI selfLink, String name, String description,
|
||||
int guestCpus, int memoryMb, int imageSpaceGb, List<EphemeralDisk> ephemeralDisks,
|
||||
int maximumPersistentDisks, long maximumPersistentDisksSizeGb, Set<String> availableZone) {
|
||||
super(Kind.MACHINE_TYPE, id, creationTimestamp, selfLink, name, description);
|
||||
this.guestCpus = checkNotNull(guestCpus, "guestCpus of %s", name);
|
||||
this.memoryMb = checkNotNull(memoryMb, "memoryMb of %s", name);
|
||||
this.imageSpaceGb = checkNotNull(imageSpaceGb, "imageSpaceGb of %s", name);
|
||||
this.ephemeralDisks = ephemeralDisks == null ? ImmutableList.<EphemeralDisk>of() : ephemeralDisks;
|
||||
this.maximumPersistentDisks = checkNotNull(maximumPersistentDisks, "maximumPersistentDisks of %s", name);
|
||||
this.maximumPersistentDisksSizeGb = maximumPersistentDisksSizeGb;
|
||||
this.availableZone = availableZone == null ? ImmutableSet.<String>of() : availableZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return count of CPUs exposed to the instance.
|
||||
*/
|
||||
public int getGuestCpus() {
|
||||
return guestCpus;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return physical memory assigned to the instance, defined in MB.
|
||||
*/
|
||||
public int getMemoryMb() {
|
||||
return memoryMb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return space allotted for the image, defined in GB.
|
||||
*/
|
||||
public int getImageSpaceGb() {
|
||||
return imageSpaceGb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return extended ephemeral disks assigned to the instance.
|
||||
*/
|
||||
public List<EphemeralDisk> getEphemeralDisks() {
|
||||
return ephemeralDisks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return maximum persistent disks allowed.
|
||||
*/
|
||||
public int getMaximumPersistentDisks() {
|
||||
return maximumPersistentDisks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return maximum total persistent disks size (GB) allowed.
|
||||
*/
|
||||
public long getMaximumPersistentDisksSizeGb() {
|
||||
return maximumPersistentDisksSizeGb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the zones that this machine type can run in.
|
||||
*/
|
||||
public Set<String> getAvailableZone() {
|
||||
return availableZone;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
return super.string()
|
||||
.add("guestCpus", guestCpus)
|
||||
.add("memoryMb", memoryMb)
|
||||
.add("imageSpaceGb", imageSpaceGb)
|
||||
.add("ephemeralDisks", ephemeralDisks)
|
||||
.add("maximumPersistentDisks", maximumPersistentDisks)
|
||||
.add("maximumPersistentDisksSizeGb", maximumPersistentDisksSizeGb)
|
||||
.add("availableZone", availableZone);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return new Builder().fromMachineType(this);
|
||||
}
|
||||
|
||||
public static final class Builder extends Resource.Builder<Builder> {
|
||||
|
||||
private Integer guestCpus;
|
||||
private Integer memoryMb;
|
||||
private Integer imageSpaceGb;
|
||||
private ImmutableList.Builder<EphemeralDisk> ephemeralDisks = ImmutableList.builder();
|
||||
private Integer maximumPersistentDisks;
|
||||
private Long maximumPersistentDisksSizeGb;
|
||||
private ImmutableSet.Builder<String> availableZone = ImmutableSet.builder();
|
||||
|
||||
/**
|
||||
* @see MachineType#getGuestCpus()
|
||||
*/
|
||||
public Builder guestCpus(int guesCpus) {
|
||||
this.guestCpus = guesCpus;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see MachineType#getMemoryMb()
|
||||
*/
|
||||
public Builder memoryMb(int memoryMb) {
|
||||
this.memoryMb = memoryMb;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see MachineType#getImageSpaceGb()
|
||||
*/
|
||||
public Builder imageSpaceGb(int imageSpaceGb) {
|
||||
this.imageSpaceGb = imageSpaceGb;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see MachineType#getEphemeralDisks()
|
||||
*/
|
||||
public Builder addEphemeralDisk(int diskGb) {
|
||||
this.ephemeralDisks.add(EphemeralDisk.builder().diskGb(diskGb).build());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see MachineType#getEphemeralDisks()
|
||||
*/
|
||||
public Builder ephemeralDisks(List<EphemeralDisk> ephemeralDisks) {
|
||||
this.ephemeralDisks.addAll(ephemeralDisks);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see MachineType#getMaximumPersistentDisks()
|
||||
*/
|
||||
public Builder maximumPersistentDisks(int maximumPersistentDisks) {
|
||||
this.maximumPersistentDisks = maximumPersistentDisks;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see MachineType#getMaximumPersistentDisksSizeGb()
|
||||
*/
|
||||
public Builder maximumPersistentDisksSizeGb(long maximumPersistentDisksSizeGb) {
|
||||
this.maximumPersistentDisksSizeGb = maximumPersistentDisksSizeGb;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see MachineType#getAvailableZone()
|
||||
*/
|
||||
public Builder addAvailableZone(String availableZone) {
|
||||
this.availableZone.add(availableZone);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see MachineType#getAvailableZone()
|
||||
*/
|
||||
public Builder availableZones(Set<String> availableZone) {
|
||||
this.availableZone.addAll(availableZone);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Builder self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public MachineType build() {
|
||||
return new MachineType(id, creationTimestamp, selfLink, name, description, guestCpus, memoryMb,
|
||||
imageSpaceGb, ephemeralDisks.build(), maximumPersistentDisks, maximumPersistentDisksSizeGb,
|
||||
availableZone.build());
|
||||
}
|
||||
|
||||
|
||||
public Builder fromMachineType(MachineType in) {
|
||||
return super.fromResource(in).memoryMb(in.getMemoryMb()).imageSpaceGb(in.getImageSpaceGb()).ephemeralDisks(in
|
||||
.getEphemeralDisks()).maximumPersistentDisks(in.getMaximumPersistentDisks())
|
||||
.maximumPersistentDisksSizeGb(in.getMaximumPersistentDisksSizeGb()).availableZones(in
|
||||
.getAvailableZone());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An ephemeral disk of a MachineType
|
||||
*/
|
||||
public static final class EphemeralDisk {
|
||||
|
||||
private final int diskGb;
|
||||
|
||||
@ConstructorProperties({
|
||||
"diskGb"
|
||||
})
|
||||
private EphemeralDisk(int diskGb) {
|
||||
this.diskGb = diskGb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return size of the ephemeral disk, defined in GB.
|
||||
*/
|
||||
public int getDiskGb() {
|
||||
return diskGb;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(diskGb);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null || getClass() != obj.getClass()) return false;
|
||||
EphemeralDisk that = EphemeralDisk.class.cast(obj);
|
||||
return equal(this.diskGb, that.diskGb);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
return toStringHelper(this)
|
||||
.add("diskGb", diskGb);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return builder().fromEphemeralDisk(this);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private int diskGb;
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.MachineType.EphemeralDisk#getDiskGb()
|
||||
*/
|
||||
public Builder diskGb(int diskGb) {
|
||||
this.diskGb = diskGb;
|
||||
return this;
|
||||
}
|
||||
|
||||
public EphemeralDisk build() {
|
||||
return new EphemeralDisk(diskGb);
|
||||
}
|
||||
|
||||
public Builder fromEphemeralDisk(EphemeralDisk in) {
|
||||
return new Builder().diskGb(in.getDiskGb());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.domain;
|
||||
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
|
||||
import static com.google.common.base.Optional.fromNullable;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Represents a network used to enable instance communication.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/networks"/>
|
||||
*/
|
||||
@Beta
|
||||
public final class Network extends Resource {
|
||||
|
||||
private final String IPv4Range;
|
||||
private final Optional<String> gatewayIPv4;
|
||||
|
||||
@ConstructorProperties({
|
||||
"id", "creationTimestamp", "selfLink", "name", "description", "IPv4Range",
|
||||
"gatewayIPv4"
|
||||
})
|
||||
protected Network(String id, Date creationTimestamp, URI selfLink, String name, String description,
|
||||
String IPv4Range, String gatewayIPv4) {
|
||||
super(Kind.NETWORK, id, creationTimestamp, selfLink, name, description);
|
||||
this.IPv4Range = checkNotNull(IPv4Range);
|
||||
this.gatewayIPv4 = fromNullable(gatewayIPv4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Required; The range of internal addresses that are legal on this network. This range is a CIDR
|
||||
* specification, for example: 192.168.0.0/16.
|
||||
*/
|
||||
public String getIPv4Range() {
|
||||
return IPv4Range;
|
||||
}
|
||||
|
||||
/**
|
||||
* This must be within the range specified by IPv4Range, and is typically the first usable address in that range.
|
||||
* If not specified, the default value is the first usable address in IPv4Range.
|
||||
*
|
||||
* @return an optional address that is used for default routing to other networks.
|
||||
*/
|
||||
public Optional<String> getGatewayIPv4() {
|
||||
return gatewayIPv4;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
return super.string()
|
||||
.omitNullValues()
|
||||
.add("IPv4Range", IPv4Range)
|
||||
.add("gatewayIPv4", gatewayIPv4.orNull());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return new Builder().fromNetwork(this);
|
||||
}
|
||||
|
||||
public static final class Builder extends Resource.Builder<Builder> {
|
||||
|
||||
private String IPv4Range;
|
||||
private String gatewayIPv4;
|
||||
|
||||
/**
|
||||
* @see Network#getIPv4Range()
|
||||
*/
|
||||
public Builder IPv4Range(String IPv4Range) {
|
||||
this.IPv4Range = IPv4Range;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Network#getGatewayIPv4()
|
||||
*/
|
||||
public Builder gatewayIPv4(String gatewayIPv4) {
|
||||
this.gatewayIPv4 = gatewayIPv4;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Builder self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Network build() {
|
||||
return new Network(super.id, super.creationTimestamp, super.selfLink, super.name,
|
||||
super.description, IPv4Range, gatewayIPv4);
|
||||
}
|
||||
|
||||
public Builder fromNetwork(Network in) {
|
||||
return super.fromResource(in);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,519 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.domain;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Describes an operation being executed on some Resource
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/operations"/>
|
||||
*/
|
||||
@Beta
|
||||
public class Operation extends Resource {
|
||||
|
||||
public static enum Status {
|
||||
PENDING,
|
||||
RUNNING,
|
||||
DONE
|
||||
}
|
||||
|
||||
private final URI targetLink;
|
||||
private final Optional<String> targetId;
|
||||
private final Optional<String> clientOperationId;
|
||||
private final Status status;
|
||||
private final Optional<String> statusMessage;
|
||||
private final String user;
|
||||
private final Optional<Integer> progress;
|
||||
private final Date insertTime;
|
||||
private final Optional<Date> startTime;
|
||||
private final Optional<Date> endTime;
|
||||
private final Optional<HttpResponse> httpError;
|
||||
private final String operationType;
|
||||
private final List<Error> errors;
|
||||
|
||||
protected Operation(String id, Date creationTimestamp, URI selfLink, String name, String description,
|
||||
URI targetLink, String targetId, String clientOperationId, Status status,
|
||||
String statusMessage, String user, Integer progress, Date insertTime, Date startTime,
|
||||
Date endTime, Integer httpErrorStatusCode, String httpErrorMessage, String operationType,
|
||||
List<Error> errors) {
|
||||
super(Kind.OPERATION, id, creationTimestamp, selfLink, name, description);
|
||||
this.targetLink = checkNotNull(targetLink, "targetLink of %s", name);
|
||||
this.targetId = fromNullable(targetId);
|
||||
this.clientOperationId = fromNullable(clientOperationId);
|
||||
this.status = checkNotNull(status, "status of %s", name);
|
||||
this.statusMessage = fromNullable(statusMessage);
|
||||
this.user = checkNotNull(user, "user of %s", name);
|
||||
this.progress = fromNullable(progress);
|
||||
this.insertTime = checkNotNull(insertTime, "insertTime of %s", name);
|
||||
this.startTime = fromNullable(startTime);
|
||||
this.endTime = fromNullable(endTime);
|
||||
this.httpError = httpErrorStatusCode != null && httpErrorStatusCode != 0 ?
|
||||
Optional.of(HttpResponse.builder()
|
||||
.statusCode(httpErrorStatusCode)
|
||||
.message(httpErrorMessage)
|
||||
.build())
|
||||
: Optional.<HttpResponse>absent();
|
||||
this.operationType = checkNotNull(operationType, "insertTime of %s", name);
|
||||
this.errors = errors == null ? ImmutableList.<Error>of() : ImmutableList.copyOf(errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return URL of the resource the operation is mutating.
|
||||
*/
|
||||
public URI getTargetLink() {
|
||||
return targetLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return unique target id which identifies a particular incarnation of the target.
|
||||
*/
|
||||
public Optional<String> getTargetId() {
|
||||
return targetId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An optional identifier specified by the client when the mutation was initiated. Must be unique for all
|
||||
* operation resources in the project.
|
||||
*/
|
||||
public Optional<String> getClientOperationId() {
|
||||
return clientOperationId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Status of the operation. Can be one of the following: PENDING, RUNNING, or DONE.
|
||||
*/
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return An optional textual description of the current status of the operation.
|
||||
*/
|
||||
public Optional<String> getStatusMessage() {
|
||||
return statusMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return User who requested the operation, for example "user@example.com".
|
||||
*/
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an optional progress indicator that ranges from 0 to 100. This should not be used to guess at when the
|
||||
* operation will be complete. This number should be monotonically increasing as the operation progresses
|
||||
* (output only).
|
||||
*/
|
||||
public Optional<Integer> getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the time that this operation was requested.
|
||||
*/
|
||||
public Date getInsertTime() {
|
||||
return insertTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the time that this operation was started by the server.
|
||||
*/
|
||||
public Optional<Date> getStartTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the time that this operation was completed.
|
||||
*/
|
||||
public Optional<Date> getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if operation fails, the HttpResponse with error status code returned and the message, e.g. NOT_FOUND.
|
||||
*/
|
||||
public Optional<HttpResponse> getHttpError() {
|
||||
return httpError;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return type of the operation. Examples include insert, update, and delete.
|
||||
*/
|
||||
public String getOperationType() {
|
||||
return operationType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if error occurred during processing of this operation, this field will be populated.
|
||||
*/
|
||||
public List<Error> getErrors() {
|
||||
return errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
return super.string()
|
||||
.omitNullValues()
|
||||
.add("targetLink", targetLink)
|
||||
.add("targetId", targetId.orNull())
|
||||
.add("clientOperationId", clientOperationId.orNull())
|
||||
.add("status", status)
|
||||
.add("statusMessage", statusMessage.orNull())
|
||||
.add("user", user)
|
||||
.add("progress", progress.orNull())
|
||||
.add("insertTime", insertTime)
|
||||
.add("startTime", startTime.orNull())
|
||||
.add("endTime", endTime.orNull())
|
||||
.add("httpError", httpError.orNull())
|
||||
.add("operationType", operationType)
|
||||
.add("errors", errors);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return new Builder().fromOperation(this);
|
||||
}
|
||||
|
||||
public static final class Builder extends Resource.Builder<Builder> {
|
||||
|
||||
private URI targetLink;
|
||||
private String targetId;
|
||||
private String clientOperationId;
|
||||
private Status status;
|
||||
private String statusMessage;
|
||||
private String user;
|
||||
private Integer progress;
|
||||
private Date insertTime;
|
||||
private Date startTime;
|
||||
private Date endTime;
|
||||
private Integer httpErrorStatusCode;
|
||||
private String httpErrorMessage;
|
||||
private String operationType;
|
||||
private ImmutableList.Builder<Error> errors = ImmutableList.builder();
|
||||
|
||||
/**
|
||||
* @see Operation#getTargetLink()
|
||||
*/
|
||||
public Builder targetLink(URI targetLink) {
|
||||
this.targetLink = targetLink;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Operation#getTargetId()
|
||||
*/
|
||||
public Builder targetId(String targetId) {
|
||||
this.targetId = targetId;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Operation#getClientOperationId()
|
||||
*/
|
||||
public Builder clientOperationId(String clientOperationId) {
|
||||
this.clientOperationId = clientOperationId;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Operation#getStatus()
|
||||
*/
|
||||
public Builder status(Status status) {
|
||||
this.status = status;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Operation#getStatusMessage()
|
||||
*/
|
||||
public Builder statusMessage(String statusMessage) {
|
||||
this.statusMessage = statusMessage;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Operation#getUser()
|
||||
*/
|
||||
public Builder user(String user) {
|
||||
this.user = user;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Operation#getProgress()
|
||||
*/
|
||||
public Builder progress(Integer progress) {
|
||||
this.progress = progress;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Operation#getInsertTime()
|
||||
*/
|
||||
public Builder insertTime(Date insertTime) {
|
||||
this.insertTime = insertTime;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Operation#getStartTime()
|
||||
*/
|
||||
public Builder startTime(Date startTime) {
|
||||
this.startTime = startTime;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Operation#getEndTime()
|
||||
*/
|
||||
public Builder endTime(Date endTime) {
|
||||
this.endTime = endTime;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Operation#getHttpError()
|
||||
*/
|
||||
public Builder httpErrorStatusCode(Integer httpErrorStatusCode) {
|
||||
this.httpErrorStatusCode = httpErrorStatusCode;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Operation#getHttpError()
|
||||
*/
|
||||
public Builder httpErrorMessage(String httpErrorMessage) {
|
||||
this.httpErrorMessage = httpErrorMessage;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Operation#getOperationType()
|
||||
*/
|
||||
public Builder operationType(String operationType) {
|
||||
this.operationType = operationType;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Operation#getErrors()
|
||||
*/
|
||||
public Builder errors(Iterable<Error> errors) {
|
||||
if (errors != null)
|
||||
this.errors.addAll(errors);
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Operation#getErrors()
|
||||
*/
|
||||
public Builder addError(Error error) {
|
||||
this.errors.add(error);
|
||||
return self();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Builder self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Operation build() {
|
||||
return new Operation(super.id, super.creationTimestamp, super.selfLink, super.name,
|
||||
super.description, targetLink, targetId, clientOperationId, status, statusMessage, user, progress,
|
||||
insertTime, startTime, endTime, httpErrorStatusCode, httpErrorMessage, operationType,
|
||||
errors.build());
|
||||
}
|
||||
|
||||
public Builder fromOperation(Operation in) {
|
||||
return super.fromResource(in)
|
||||
.targetLink(in.getTargetLink())
|
||||
.targetId(in.getTargetId().orNull())
|
||||
.clientOperationId(in.getClientOperationId().orNull())
|
||||
.status(in.getStatus())
|
||||
.statusMessage(in.getStatusMessage().orNull())
|
||||
.user(in.getUser())
|
||||
.progress(in.getProgress().get())
|
||||
.insertTime(in.getInsertTime())
|
||||
.startTime(in.getStartTime().orNull())
|
||||
.endTime(in.getEndTime().orNull())
|
||||
.httpErrorStatusCode(in.getHttpError().isPresent() ? in.getHttpError().get().getStatusCode() : null)
|
||||
.httpErrorMessage(in.getHttpError().isPresent() ? in.getHttpError().get().getMessage() : null)
|
||||
.operationType(in.getOperationType()).errors(in.getErrors());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A particular error for an operation including the details.
|
||||
*/
|
||||
public static final class Error {
|
||||
|
||||
private final String code;
|
||||
private final Optional<String> location;
|
||||
private final Optional<String> message;
|
||||
|
||||
@ConstructorProperties({
|
||||
"code", "location", "message"
|
||||
})
|
||||
private Error(String code, String location, String message) {
|
||||
this.code = checkNotNull(code, "code");
|
||||
this.location = fromNullable(location);
|
||||
this.message = fromNullable(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the error type identifier for this error.
|
||||
*/
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return indicates the field in the request which caused the error..
|
||||
*/
|
||||
public Optional<String> getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an optional, human-readable error message.
|
||||
*/
|
||||
public Optional<String> getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(code, location, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null || getClass() != obj.getClass()) return false;
|
||||
Error that = Error.class.cast(obj);
|
||||
return equal(this.code, that.code)
|
||||
&& equal(this.location, that.location)
|
||||
&& equal(this.message, that.message);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
return toStringHelper(this)
|
||||
.omitNullValues()
|
||||
.add("code", code)
|
||||
.add("location", location.orNull())
|
||||
.add("message", message.orNull());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return builder().fromOperationErrorDetail(this);
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
|
||||
private String code;
|
||||
private String location;
|
||||
private String message;
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Operation.Error#getCode()
|
||||
*/
|
||||
public Builder code(String code) {
|
||||
this.code = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Operation.Error#getLocation()
|
||||
*/
|
||||
public Builder location(String location) {
|
||||
this.location = location;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Operation.Error#getMessage()
|
||||
*/
|
||||
public Builder message(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Error build() {
|
||||
return new Error(code, location, message);
|
||||
}
|
||||
|
||||
public Builder fromOperationErrorDetail(Error in) {
|
||||
return new Builder().code(in.getCode()).location(in.getLocation().orNull()).message
|
||||
(in.getMessage().orNull());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.domain;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
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.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* A Project resource is the root collection and settings resource for all Google Compute Engine resources.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/projects"/>
|
||||
*/
|
||||
@Beta
|
||||
public class Project extends Resource {
|
||||
|
||||
private final Map<String, String> commonInstanceMetadata;
|
||||
private final Set<Quota> quotas;
|
||||
private final Set<String> externalIpAddresses;
|
||||
|
||||
protected Project(String id, Date creationTimestamp, URI selfLink, String name, String description,
|
||||
Map<String, String> commonInstanceMetadata, Set<Quota> quotas, Set<String> externalIpAddresses) {
|
||||
super(Kind.PROJECT, id, creationTimestamp, selfLink, name, description);
|
||||
this.commonInstanceMetadata = commonInstanceMetadata == null ? ImmutableMap.<String,
|
||||
String>of() : ImmutableMap.copyOf(commonInstanceMetadata);
|
||||
this.quotas = quotas == null ? ImmutableSet.<Quota>of() : ImmutableSet.copyOf(quotas);
|
||||
this.externalIpAddresses = externalIpAddresses == null ? ImmutableSet.<String>of() : ImmutableSet.copyOf
|
||||
(externalIpAddresses);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return metadata key/value pairs available to all instances contained in this project.
|
||||
*/
|
||||
public Map<String, String> getCommonInstanceMetadata() {
|
||||
return commonInstanceMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return quotas assigned to this project.
|
||||
*/
|
||||
public Set<Quota> getQuotas() {
|
||||
return quotas;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return internet available IP addresses available for use in this project.
|
||||
*/
|
||||
@Nullable
|
||||
public Set<String> getExternalIpAddresses() {
|
||||
return externalIpAddresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
return super.string()
|
||||
.add("commonInstanceMetadata", commonInstanceMetadata)
|
||||
.add("quotas", quotas)
|
||||
.add("externalIpAddresses", externalIpAddresses);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return new Builder().fromProject(this);
|
||||
}
|
||||
|
||||
public static final class Builder extends Resource.Builder<Builder> {
|
||||
|
||||
private ImmutableMap.Builder<String, String> commonInstanceMetadata = ImmutableMap.builder();
|
||||
private ImmutableSet.Builder<Quota> quotas = ImmutableSet.builder();
|
||||
private ImmutableSet.Builder<String> externalIpAddresses = ImmutableSet.builder();
|
||||
|
||||
/**
|
||||
* @see Project#getCommonInstanceMetadata()
|
||||
*/
|
||||
public Builder addCommonInstanceMetadata(String key, String value) {
|
||||
this.commonInstanceMetadata.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Project#getCommonInstanceMetadata()
|
||||
*/
|
||||
public Builder commonInstanceMetadata(Map<String, String> commonInstanceMetadata) {
|
||||
this.commonInstanceMetadata.putAll(checkNotNull(commonInstanceMetadata, "commonInstanceMetadata"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Project#getQuotas()
|
||||
*/
|
||||
public Builder addQuota(String metric, double usage, double limit) {
|
||||
this.quotas.add(Quota.builder().metric(metric).usage(usage).limit(limit).build());
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Project#getQuotas()
|
||||
*/
|
||||
public Builder quotas(Set<Quota> quotas) {
|
||||
this.quotas.addAll(checkNotNull(quotas));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Project#getExternalIpAddresses()
|
||||
*/
|
||||
public Builder addExternalIpAddress(String externalIpAddress) {
|
||||
this.externalIpAddresses.add(checkNotNull(externalIpAddress, "externalIpAddress"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Project#getExternalIpAddresses()
|
||||
*/
|
||||
public Builder externalIpAddresses(Set<String> externalIpAddresses) {
|
||||
this.externalIpAddresses.addAll(checkNotNull(externalIpAddresses, "externalIpAddresses"));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Builder self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Project build() {
|
||||
return new Project(super.id, super.creationTimestamp, super.selfLink, super.name,
|
||||
super.description, commonInstanceMetadata.build(), quotas.build(), externalIpAddresses.build());
|
||||
}
|
||||
|
||||
public Builder fromProject(Project in) {
|
||||
return super.fromResource(in).commonInstanceMetadata(in.getCommonInstanceMetadata()).quotas(in.getQuotas())
|
||||
.externalIpAddresses(in.getExternalIpAddresses());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Quotas assigned to a given project
|
||||
*
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/projects#resource"/>
|
||||
*/
|
||||
public static final class Quota {
|
||||
|
||||
private String metric;
|
||||
private double usage;
|
||||
private double limit;
|
||||
|
||||
@ConstructorProperties({
|
||||
"metric", "usage", "limit"
|
||||
})
|
||||
protected Quota(String metric, Double usage, Double limit) {
|
||||
this.metric = checkNotNull(metric, "metric");
|
||||
this.usage = checkNotNull(usage, "usage");
|
||||
this.limit = checkNotNull(limit, "limit");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return name of the quota metric.
|
||||
*/
|
||||
public String getMetric() {
|
||||
return metric;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current usage of this metric.
|
||||
*/
|
||||
public Double getUsage() {
|
||||
return usage;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return quota limit for this metric.
|
||||
*/
|
||||
public Double getLimit() {
|
||||
return limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(metric);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null || getClass() != obj.getClass()) return false;
|
||||
Quota that = Quota.class.cast(obj);
|
||||
return equal(this.metric, that.metric);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
return toStringHelper(this)
|
||||
.omitNullValues()
|
||||
.add("metric", metric)
|
||||
.add("usage", usage)
|
||||
.add("limit", limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return builder().fromQuota(this);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private String metric;
|
||||
private Double usage;
|
||||
private Double limit;
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Project.Quota#getMetric()
|
||||
*/
|
||||
public Builder metric(String metric) {
|
||||
this.metric = checkNotNull(metric, "metric");
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Project.Quota#getUsage()
|
||||
*/
|
||||
public Builder usage(Double usage) {
|
||||
this.usage = usage;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Project.Quota#getLimit()
|
||||
*/
|
||||
public Builder limit(Double limit) {
|
||||
this.limit = limit;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Quota build() {
|
||||
return new Quota(metric, usage, limit);
|
||||
}
|
||||
|
||||
public Builder fromQuota(Quota quota) {
|
||||
return new Builder().metric(quota.getMetric()).usage(quota.getUsage()).limit(quota.getLimit());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,281 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.domain;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.CaseFormat;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.Iterables;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.net.URI;
|
||||
import java.util.Date;
|
||||
|
||||
import static com.google.common.base.Objects.ToStringHelper;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Base class for Google Compute Engine resources.
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
@Beta
|
||||
public class Resource {
|
||||
|
||||
public enum Kind {
|
||||
DISK,
|
||||
DISK_LIST,
|
||||
FIREWALL,
|
||||
FIREWALL_LIST,
|
||||
IMAGE,
|
||||
IMAGE_LIST,
|
||||
OPERATION,
|
||||
OPERATION_LIST,
|
||||
INSTANCE,
|
||||
INSTANCE_LIST,
|
||||
KERNEL,
|
||||
KERNEL_LIST,
|
||||
MACHINE_TYPE,
|
||||
MACHINE_TYPE_LIST,
|
||||
PROJECT,
|
||||
NETWORK,
|
||||
NETWORK_LIST,
|
||||
ZONE,
|
||||
ZONE_LIST;
|
||||
|
||||
public String value() {
|
||||
return Joiner.on("#").join("compute", CaseFormat.UPPER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value();
|
||||
}
|
||||
|
||||
public static Kind fromValue(String kind) {
|
||||
return valueOf(CaseFormat.LOWER_CAMEL.to(CaseFormat
|
||||
.UPPER_UNDERSCORE,
|
||||
Iterables.getLast(Splitter.on("#").split(checkNotNull(kind,
|
||||
"kind")))));
|
||||
}
|
||||
}
|
||||
|
||||
protected final Kind kind;
|
||||
protected final String id;
|
||||
protected final Optional<Date> creationTimestamp;
|
||||
protected final URI selfLink;
|
||||
protected final String name;
|
||||
protected final Optional<String> description;
|
||||
|
||||
@ConstructorProperties({
|
||||
"kind", "id", "creationTimestamp", "selfLink", "name", "description"
|
||||
})
|
||||
protected Resource(Kind kind, String id, Date creationTimestamp, URI selfLink, String name,
|
||||
String description) {
|
||||
this.kind = checkNotNull(kind, "kind");
|
||||
this.id = checkNotNull(id, "id");
|
||||
this.creationTimestamp = fromNullable(creationTimestamp);
|
||||
this.selfLink = checkNotNull(selfLink, "selfLink");
|
||||
this.name = checkNotNull(name, "name");
|
||||
this.description = fromNullable(description);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Type of the resource
|
||||
*/
|
||||
public Kind getKind() {
|
||||
return kind;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return unique identifier for the resource; defined by the server.
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return creation timestamp in RFC3339 text format.
|
||||
*/
|
||||
public Optional<Date> getCreationTimestamp() {
|
||||
return creationTimestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return server defined URL for the resource.
|
||||
*/
|
||||
public URI getSelfLink() {
|
||||
return selfLink;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return name of the resource.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return an optional textual description of the resource.
|
||||
*/
|
||||
@Nullable
|
||||
public Optional<String> getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(kind, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null || getClass() != obj.getClass()) return false;
|
||||
Resource that = Resource.class.cast(obj);
|
||||
return equal(this.kind, that.kind)
|
||||
&& equal(this.name, that.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected ToStringHelper string() {
|
||||
return toStringHelper(this)
|
||||
.omitNullValues()
|
||||
.add("kind", kind)
|
||||
.add("id", id)
|
||||
.add("name", name)
|
||||
.add("creationTimestamp", creationTimestamp.orNull())
|
||||
.add("selfLink", selfLink)
|
||||
.add("name", name)
|
||||
.add("description", description.orNull());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static Builder<?> builder() {
|
||||
return new ConcreteBuilder();
|
||||
}
|
||||
|
||||
public Builder<?> toBuilder() {
|
||||
return new ConcreteBuilder().fromResource(this);
|
||||
}
|
||||
|
||||
public abstract static class Builder<T extends Builder<T>> {
|
||||
|
||||
protected abstract T self();
|
||||
|
||||
protected Kind kind;
|
||||
protected String id;
|
||||
protected Date creationTimestamp;
|
||||
protected URI selfLink;
|
||||
protected String name;
|
||||
protected String description;
|
||||
|
||||
/**
|
||||
* @see Resource#getKind()
|
||||
*/
|
||||
protected T kind(Kind kind) {
|
||||
this.kind = kind;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Resource#getId()
|
||||
*/
|
||||
public T id(String id) {
|
||||
this.id = id;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Resource#getCreationTimestamp()
|
||||
*/
|
||||
public T creationTimestamp(Date creationTimestamp) {
|
||||
this.creationTimestamp = creationTimestamp;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Resource#getSelfLink()
|
||||
*/
|
||||
public T selfLink(URI selfLink) {
|
||||
this.selfLink = selfLink;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Resource#getName()
|
||||
*/
|
||||
public T name(String name) {
|
||||
this.name = name;
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Resource#getDescription()
|
||||
*/
|
||||
public T description(String description) {
|
||||
this.description = description;
|
||||
return self();
|
||||
}
|
||||
|
||||
public Resource build() {
|
||||
return new Resource(kind, id, creationTimestamp, selfLink, name, description);
|
||||
}
|
||||
|
||||
public T fromResource(Resource in) {
|
||||
return this
|
||||
.kind(in.getKind())
|
||||
.id(in.getId())
|
||||
.creationTimestamp(in.getCreationTimestamp().orNull())
|
||||
.selfLink(in.getSelfLink())
|
||||
.name(in.getName())
|
||||
.description(in.getDescription().orNull());
|
||||
}
|
||||
}
|
||||
|
||||
private static class ConcreteBuilder extends Builder<ConcreteBuilder> {
|
||||
@Override
|
||||
protected ConcreteBuilder self() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.domain;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Represents a zone resource.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/zones"/>
|
||||
*/
|
||||
@Beta
|
||||
public final class Zone extends Resource {
|
||||
|
||||
public enum Status {
|
||||
UP,
|
||||
DOWN
|
||||
}
|
||||
|
||||
private final Status status;
|
||||
private final Set<MaintenanceWindow> maintenanceWindows;
|
||||
private final Set<String> availableMachineTypes;
|
||||
|
||||
@ConstructorProperties({
|
||||
"id", "creationTimestamp", "selfLink", "name", "description", "status", "maintenanceWindows",
|
||||
"availableMachineTypes"
|
||||
})
|
||||
private Zone(String id, Date creationTimestamp, URI selfLink, String name, String description,
|
||||
Status status, Set<MaintenanceWindow> maintenanceWindows, Set<String> availableMachineTypes) {
|
||||
super(Kind.ZONE, id, creationTimestamp, selfLink, name, description);
|
||||
this.status = checkNotNull(status, "status of %name", name);
|
||||
this.maintenanceWindows = maintenanceWindows == null ? ImmutableSet.<MaintenanceWindow>of() : ImmutableSet
|
||||
.copyOf(maintenanceWindows);
|
||||
this.availableMachineTypes = availableMachineTypes == null ? ImmutableSet.<String>of() : ImmutableSet
|
||||
.copyOf(availableMachineTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Status of the zone. "UP" or "DOWN".
|
||||
*/
|
||||
public Status getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return scheduled maintenance windows for the zone. When the zone is in a maintenance window,
|
||||
* all resources which reside in the zone will be unavailable.
|
||||
*/
|
||||
public Set<MaintenanceWindow> getMaintenanceWindows() {
|
||||
return maintenanceWindows;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the machine types that can be used in this zone.
|
||||
*/
|
||||
@Nullable
|
||||
public Set<String> getAvailableMachineTypes() {
|
||||
return availableMachineTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
return super.string()
|
||||
.add("status", status)
|
||||
.add("maintenanceWindows", maintenanceWindows)
|
||||
.add("availableMachineTypes", availableMachineTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return new Builder().fromZone(this);
|
||||
}
|
||||
|
||||
public static final class Builder extends Resource.Builder<Builder> {
|
||||
|
||||
private Status status;
|
||||
private ImmutableSet.Builder<MaintenanceWindow> maintenanceWindows = ImmutableSet.builder();
|
||||
private ImmutableSet.Builder<String> availableMachineTypes = ImmutableSet.builder();
|
||||
|
||||
/**
|
||||
* @see Zone#getStatus()
|
||||
*/
|
||||
public Builder status(Status status) {
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Zone#getMaintenanceWindows()
|
||||
*/
|
||||
public Builder addMaintenanceWindow(MaintenanceWindow maintenanceWindow) {
|
||||
this.maintenanceWindows.add(checkNotNull(maintenanceWindow, "maintenanceWindow"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Zone#getMaintenanceWindows()
|
||||
*/
|
||||
public Builder maintenanceWindows(Set<MaintenanceWindow> maintenanceWindows) {
|
||||
this.maintenanceWindows.addAll(checkNotNull(maintenanceWindows, "maintenanceWindows"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Zone#getAvailableMachineTypes()
|
||||
*/
|
||||
public Builder addAvailableMachineType(String availableMachineType) {
|
||||
this.availableMachineTypes.add(checkNotNull(availableMachineType, "availableMachineType"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Zone#getAvailableMachineTypes()
|
||||
*/
|
||||
public Builder availableMachineTypes(Set<String> availableMachineTypes) {
|
||||
this.availableMachineTypes.addAll(checkNotNull(availableMachineTypes, "availableMachineTypes"));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Builder self() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Zone build() {
|
||||
return new Zone(super.id, super.creationTimestamp, super.selfLink, super.name,
|
||||
super.description, status, maintenanceWindows.build(), availableMachineTypes.build());
|
||||
}
|
||||
|
||||
public Builder fromZone(Zone in) {
|
||||
return super.fromResource(in)
|
||||
.status(in.getStatus())
|
||||
.maintenanceWindows(in.getMaintenanceWindows())
|
||||
.availableMachineTypes(in.getAvailableMachineTypes());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scheduled maintenance windows for the zone. When the zone is in a maintenance window,
|
||||
* all resources which reside in the zone will be unavailable.
|
||||
*
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/zones"/>
|
||||
*/
|
||||
public static final class MaintenanceWindow {
|
||||
|
||||
private final String name;
|
||||
private final Optional<String> description;
|
||||
private final Date beginTime;
|
||||
private final Date endTime;
|
||||
|
||||
@ConstructorProperties({
|
||||
"name", "description", "beginTime", "endTime"
|
||||
})
|
||||
private MaintenanceWindow(String name, String description, Date beginTime, Date endTime) {
|
||||
this.name = checkNotNull(name, "name");
|
||||
this.description = fromNullable(description);
|
||||
this.beginTime = checkNotNull(beginTime, "beginTime of %name", name);
|
||||
this.endTime = checkNotNull(endTime, "endTime of %name", name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return name of the maintenance window.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return textual description of the maintenance window.
|
||||
*/
|
||||
public Optional<String> getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return begin time of the maintenance window.
|
||||
*/
|
||||
public Date getBeginTime() {
|
||||
return beginTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return end time of the maintenance window.
|
||||
*/
|
||||
public Date getEndTime() {
|
||||
return endTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(name, description, beginTime, endTime);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (obj == null || getClass() != obj.getClass()) return false;
|
||||
MaintenanceWindow that = MaintenanceWindow.class.cast(obj);
|
||||
return equal(this.name, that.name)
|
||||
&& equal(this.beginTime, that.beginTime)
|
||||
&& equal(this.endTime, that.endTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Objects.ToStringHelper string() {
|
||||
return toStringHelper(this)
|
||||
.omitNullValues()
|
||||
.add("name", name)
|
||||
.add("description", description.orNull())
|
||||
.add("beginTime", beginTime)
|
||||
.add("endTime", endTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return string().toString();
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public Builder toBuilder() {
|
||||
return builder().fromZoneMaintenanceWindow(this);
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
|
||||
private String name;
|
||||
private String description;
|
||||
private Date beginTime;
|
||||
private Date endTime;
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Zone.MaintenanceWindow#getName()
|
||||
*/
|
||||
public Builder name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Zone.MaintenanceWindow#getDescription()
|
||||
*/
|
||||
public Builder description(String description) {
|
||||
this.description = description;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Zone.MaintenanceWindow#getBeginTime()
|
||||
*/
|
||||
public Builder beginTime(Date beginTime) {
|
||||
this.beginTime = beginTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Zone.MaintenanceWindow#getEndTime()
|
||||
*/
|
||||
public Builder endTime(Date endTime) {
|
||||
this.endTime = endTime;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public MaintenanceWindow build() {
|
||||
return new MaintenanceWindow(name, description, beginTime, endTime);
|
||||
}
|
||||
|
||||
public Builder fromZoneMaintenanceWindow(MaintenanceWindow in) {
|
||||
return new Builder()
|
||||
.name(in.getName())
|
||||
.description(in.getDescription().orNull())
|
||||
.beginTime(in.getBeginTime())
|
||||
.endTime(in.getEndTime());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
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 org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.Disk;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.functions.internal.ParseDisks;
|
||||
import org.jclouds.googlecomputeengine.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.Fallback;
|
||||
import org.jclouds.rest.annotations.MapBinder;
|
||||
import org.jclouds.rest.annotations.PayloadParam;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Provides access to Disks via their REST API.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/disks"/>
|
||||
*/
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(OAuthAuthenticator.class)
|
||||
public interface DiskApi {
|
||||
|
||||
/**
|
||||
* Returns the specified persistent disk resource.
|
||||
*
|
||||
* @param diskName name of the persistent disk resource to return.
|
||||
* @return a Disk resource.
|
||||
*/
|
||||
@Named("Disks:get")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/disks/{disk}")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
@Nullable
|
||||
Disk get(@PathParam("disk") String diskName);
|
||||
|
||||
/**
|
||||
* Creates a persistent disk resource in the specified project specifying the size of the disk.
|
||||
*
|
||||
*
|
||||
* @param diskName the name of disk.
|
||||
* @param sizeGb the size of the disk
|
||||
* @param zone the URi of the zone where the disk is to be created.
|
||||
* @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.
|
||||
*/
|
||||
@Named("Disks:insert")
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/disks")
|
||||
@OAuthScopes({COMPUTE_SCOPE})
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
Operation createInZone(@PayloadParam("name") String diskName,
|
||||
@PayloadParam("sizeGb") int sizeGb,
|
||||
@PayloadParam("zone") URI zone);
|
||||
|
||||
/**
|
||||
* Deletes the specified persistent disk resource.
|
||||
*
|
||||
* @param diskName name of the persistent disk 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.
|
||||
*/
|
||||
@Named("Disks:delete")
|
||||
@DELETE
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/disks/{disk}")
|
||||
@OAuthScopes(COMPUTE_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
@Nullable
|
||||
Operation delete(@PathParam("disk") String diskName);
|
||||
|
||||
/**
|
||||
* @see DiskApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Disks:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/disks")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseDisks.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Disk> listFirstPage();
|
||||
|
||||
/**
|
||||
* @see DiskApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Disks:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/disks")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseDisks.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Disk> listAtMarker(@QueryParam("pageToken") @Nullable String marker);
|
||||
|
||||
/**
|
||||
* Retrieves the listPage of persistent disk resources contained within the specified project.
|
||||
* By default the listPage 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 listPage
|
||||
* @see ListOptions
|
||||
* @see org.jclouds.googlecomputeengine.domain.ListPage
|
||||
*/
|
||||
@Named("Disks:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/disks")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseDisks.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Disk> listAtMarker(@QueryParam("pageToken") @Nullable String marker, ListOptions options);
|
||||
|
||||
/**
|
||||
* A paged version of DiskApi#listPage()
|
||||
*
|
||||
* @return a Paged, Fluent Iterable that is able to fetch additional pages when required
|
||||
* @see PagedIterable
|
||||
* @see DiskApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Disks:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/disks")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseDisks.class)
|
||||
@Transform(ParseDisks.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<Disk> list();
|
||||
|
||||
@Named("Disks:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/disks")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseDisks.class)
|
||||
@Transform(ParseDisks.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<Disk> list(ListOptions options);
|
||||
}
|
|
@ -0,0 +1,231 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import javax.inject.Named;
|
||||
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 org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.Firewall;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.functions.internal.PATCH;
|
||||
import org.jclouds.googlecomputeengine.functions.internal.ParseFirewalls;
|
||||
import org.jclouds.googlecomputeengine.handlers.FirewallBinder;
|
||||
import org.jclouds.googlecomputeengine.options.FirewallOptions;
|
||||
import org.jclouds.googlecomputeengine.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.MapBinder;
|
||||
import org.jclouds.rest.annotations.PayloadParam;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Provides access to Firewalls via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/firewalls"/>
|
||||
*/
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(OAuthAuthenticator.class)
|
||||
public interface FirewallApi {
|
||||
/**
|
||||
* Returns the specified image resource.
|
||||
*
|
||||
* @param firewallName name of the firewall resource to return.
|
||||
* @return an Firewall resource
|
||||
*/
|
||||
@Named("Firewalls:get")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls/{firewall}")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
@Nullable
|
||||
Firewall get(@PathParam("firewall") String firewallName);
|
||||
|
||||
/**
|
||||
* Creates a firewall resource in the specified project using the data included in the request.
|
||||
*
|
||||
* @param name the name of the firewall to be inserted.
|
||||
* @param network the network to which to add the firewall
|
||||
* @param firewallOptions the options of the firewall to add
|
||||
* @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.
|
||||
*/
|
||||
@Named("Firewalls:insert")
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls")
|
||||
@OAuthScopes({COMPUTE_SCOPE})
|
||||
@MapBinder(FirewallBinder.class)
|
||||
Operation createInNetwork(@PayloadParam("name") String name,
|
||||
@PayloadParam("network") URI network,
|
||||
@PayloadParam("options") FirewallOptions firewallOptions);
|
||||
|
||||
/**
|
||||
* Updates the specified firewall resource with the data included in the request.
|
||||
*
|
||||
* @param firewallName the name firewall to be updated.
|
||||
* @param firewallOptions 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.
|
||||
*/
|
||||
@Named("Firewalls:update")
|
||||
@PUT
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls/{firewall}")
|
||||
@OAuthScopes({COMPUTE_SCOPE})
|
||||
Operation update(@PathParam("firewall") String firewallName,
|
||||
@BinderParam(BindToJsonPayload.class) FirewallOptions firewallOptions);
|
||||
|
||||
/**
|
||||
* Updates the specified firewall resource, with patch semantics, with the data included in the request.
|
||||
*
|
||||
* @param firewallName the name firewall to be updated.
|
||||
* @param firewallOptions 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.
|
||||
*/
|
||||
@Named("Firewalls:patch")
|
||||
@PATCH
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls/{firewall}")
|
||||
@OAuthScopes({COMPUTE_SCOPE})
|
||||
Operation patch(@PathParam("firewall") String firewallName,
|
||||
@BinderParam(BindToJsonPayload.class) FirewallOptions firewallOptions);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
@Named("Firewalls:delete")
|
||||
@DELETE
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls/{firewall}")
|
||||
@OAuthScopes(COMPUTE_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
Operation delete(@PathParam("firewall") String firewallName);
|
||||
|
||||
/**
|
||||
* @see FirewallApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Firewalls:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseFirewalls.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Firewall> listFirstPage();
|
||||
|
||||
/**
|
||||
* @see FirewallApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Firewalls:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseFirewalls.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Firewall> listAtMarker(@QueryParam("pageToken") @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.googlecomputeengine.domain.ListPage
|
||||
*/
|
||||
@Named("Firewalls:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseFirewalls.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Firewall> listAtMarker(@QueryParam("pageToken") @Nullable String marker, ListOptions options);
|
||||
|
||||
/**
|
||||
* @see FirewallApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Firewalls:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseFirewalls.class)
|
||||
@Transform(ParseFirewalls.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
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.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Firewalls:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/firewalls")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseFirewalls.class)
|
||||
@Transform(ParseFirewalls.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<Firewall> list(ListOptions options);
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.Image;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.functions.internal.ParseImages;
|
||||
import org.jclouds.googlecomputeengine.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.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;
|
||||
|
||||
/**
|
||||
* Provides access to Images via their REST API.
|
||||
* <p/>
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/images"/>
|
||||
*/
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(OAuthAuthenticator.class)
|
||||
public interface ImageApi {
|
||||
/**
|
||||
* Returns the specified image resource.
|
||||
*
|
||||
* @param imageName name of the image resource to return.
|
||||
* @return an Image resource
|
||||
*/
|
||||
@Named("Images:get")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/images/{image}")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
@Nullable
|
||||
Image get(@PathParam("image") String imageName);
|
||||
|
||||
/**
|
||||
* Deletes the specified image resource.
|
||||
*
|
||||
* @param imageName name of the image 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.
|
||||
*/
|
||||
@Named("Images:delete")
|
||||
@DELETE
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/images/{image}")
|
||||
@OAuthScopes(COMPUTE_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
@Nullable
|
||||
Operation delete(@PathParam("image") String imageName);
|
||||
|
||||
/**
|
||||
* @see ImageApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Images:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/images")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseImages.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Image> listFirstPage();
|
||||
|
||||
/**
|
||||
* @see ImageApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Images:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/images")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseImages.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Image> listAtMarker(@QueryParam("pageToken") @Nullable String marker);
|
||||
|
||||
/**
|
||||
* Retrieves the list of image 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.googlecomputeengine.domain.ListPage
|
||||
*/
|
||||
@Named("Images:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/images")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseImages.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Image> listAtMarker(@QueryParam("pageToken") @Nullable String marker, ListOptions options);
|
||||
|
||||
/**
|
||||
* A paged version of ImageApi#list()
|
||||
*
|
||||
* @return a Paged, Fluent Iterable that is able to fetch additional pages when required
|
||||
* @see PagedIterable
|
||||
* @see ImageApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Images:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/images")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseImages.class)
|
||||
@Transform(ParseImages.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<Image> list();
|
||||
|
||||
/**
|
||||
* A paged version of ImageApi#list()
|
||||
*
|
||||
* @return a Paged, Fluent Iterable that is able to fetch additional pages when required
|
||||
* @see PagedIterable
|
||||
* @see ImageApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Images:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/images")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseImages.class)
|
||||
@Transform(ParseImages.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<Image> list(ListOptions options);
|
||||
}
|
|
@ -0,0 +1,246 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
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 org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance;
|
||||
import org.jclouds.googlecomputeengine.domain.InstanceTemplate;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.functions.internal.ParseInstances;
|
||||
import org.jclouds.googlecomputeengine.handlers.InstanceBinder;
|
||||
import org.jclouds.googlecomputeengine.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.MapBinder;
|
||||
import org.jclouds.rest.annotations.PayloadParam;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Provides access to Instances via their REST API.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/instances"/>
|
||||
* @see InstanceApi
|
||||
*/
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(OAuthAuthenticator.class)
|
||||
public interface InstanceApi {
|
||||
|
||||
/**
|
||||
* Returns the specified instance resource.
|
||||
*
|
||||
* @param instanceName name of the instance resource to return.
|
||||
* @return an Instance resource
|
||||
*/
|
||||
@Named("Instances:get")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances/{instance}")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
@Nullable
|
||||
Instance get(@PathParam("instance") String instanceName);
|
||||
|
||||
/**
|
||||
* Creates a instance resource in the specified project using the data included in the request.
|
||||
*
|
||||
* @param instanceName this name of the instance to be created
|
||||
* @param template the instance template
|
||||
* @param zone the name of the zone where the instance will be created
|
||||
* @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.
|
||||
*/
|
||||
@Named("Instances:insert")
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances")
|
||||
@OAuthScopes({COMPUTE_SCOPE})
|
||||
@MapBinder(InstanceBinder.class)
|
||||
Operation createInZone(@PayloadParam("name") String instanceName,
|
||||
@PayloadParam("template") InstanceTemplate template,
|
||||
@PayloadParam("zone") String zone);
|
||||
|
||||
/**
|
||||
* Deletes the specified instance resource.
|
||||
*
|
||||
* @param instanceName name of the instance 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 instance did not exist the result is null.
|
||||
*/
|
||||
@Named("Instances:delete")
|
||||
@DELETE
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances/{instance}")
|
||||
@OAuthScopes(COMPUTE_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
@Nullable
|
||||
Operation delete(@PathParam("instance") String instanceName);
|
||||
|
||||
/**
|
||||
* A paged version of InstanceApi#list()
|
||||
*
|
||||
* @return a Paged, Fluent Iterable that is able to fetch additional pages when required
|
||||
* @see PagedIterable
|
||||
* @see InstanceApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Instances:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseInstances.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Instance> listFirstPage();
|
||||
|
||||
/**
|
||||
* Retrieves the list of instance 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.googlecomputeengine.domain.ListPage
|
||||
*/
|
||||
@Named("Instances:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseInstances.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Instance> listAtMarker(@Nullable String marker);
|
||||
|
||||
/**
|
||||
* @see InstanceApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Instances:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseInstances.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Instance> listAtMarker(@Nullable String marker, ListOptions options);
|
||||
|
||||
/**
|
||||
* @see InstanceApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Instances:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseInstances.class)
|
||||
@Transform(ParseInstances.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<Instance> list();
|
||||
|
||||
/**
|
||||
* @see InstanceApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Instances:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseInstances.class)
|
||||
@Transform(ParseInstances.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<Instance> list(ListOptions options);
|
||||
|
||||
/**
|
||||
* Adds an access config to an instance's network interface.
|
||||
*
|
||||
* @param instanceName the instance name.
|
||||
* @param accessConfig the AccessConfig to add.
|
||||
* @param networkInterfaceName network interface name.
|
||||
* @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.
|
||||
*/
|
||||
@Named("Instances:addAccessConfig")
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances/{instance}/addAccessConfig")
|
||||
@OAuthScopes({COMPUTE_SCOPE})
|
||||
Operation addAccessConfigToNic(@PathParam("instance") String instanceName,
|
||||
@BinderParam(BindToJsonPayload.class)
|
||||
Instance.NetworkInterface.AccessConfig accessConfig,
|
||||
@QueryParam("network_interface") String networkInterfaceName);
|
||||
|
||||
/**
|
||||
* Deletes an access config from an instance's network interface.
|
||||
*
|
||||
* @param instanceName the instance name.
|
||||
* @param accessConfigName the name of the access config to delete
|
||||
* @param networkInterfaceName network interface name.
|
||||
* @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.
|
||||
*/
|
||||
@Named("Instances:deleteAccessConfig")
|
||||
@DELETE
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances/{instance}/deleteAccessConfig")
|
||||
@OAuthScopes(COMPUTE_SCOPE)
|
||||
Operation deleteAccessConfigFromNic(@PathParam("instance") String instanceName,
|
||||
@QueryParam("access_config") String accessConfigName,
|
||||
@QueryParam("network_interface") String networkInterfaceName);
|
||||
|
||||
/**
|
||||
* Returns the specified instance's serial port output.
|
||||
*
|
||||
* @param instanceName the instance name.
|
||||
* @return if successful, this method returns a SerialPortOutput containing the instance's serial output.
|
||||
*/
|
||||
@Named("Instances:serialPort")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/instances/{instance}/serialPort")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
Instance.SerialPortOutput getSerialPortOutput(@PathParam("instance") String instanceName);
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.Kernel;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.functions.internal.ParseKernels;
|
||||
import org.jclouds.googlecomputeengine.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.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;
|
||||
|
||||
/**
|
||||
* Provides access to Kernels via their REST API.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/kernels"/>
|
||||
*/
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(OAuthAuthenticator.class)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public interface KernelApi {
|
||||
|
||||
/**
|
||||
* Returns the specified kernel resource
|
||||
*
|
||||
* @param kernelName name of the kernel resource to return.
|
||||
* @return If successful, this method returns a Kernel resource
|
||||
*/
|
||||
@Named("Kernels:get")
|
||||
@GET
|
||||
@Path("/kernels/{kernel}")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
Kernel get(@PathParam("kernel") String kernelName);
|
||||
|
||||
/**
|
||||
* @see KernelApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Kernels:list")
|
||||
@GET
|
||||
@Path("/kernels")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseKernels.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Kernel> listFirstPage();
|
||||
|
||||
/**
|
||||
* @see KernelApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Kernels:list")
|
||||
@GET
|
||||
@Path("/kernels")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseKernels.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Kernel> listAtMarker(@QueryParam("pageToken") @Nullable String marker);
|
||||
|
||||
/**
|
||||
* Retrieves the list of kernel 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.googlecomputeengine.domain.ListPage
|
||||
*/
|
||||
@Named("Kernels:list")
|
||||
@GET
|
||||
@Path("/kernels")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseKernels.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Kernel> listAtMarker(@QueryParam("pageToken") @Nullable String marker,
|
||||
ListOptions listOptions);
|
||||
|
||||
/**
|
||||
* @see KernelApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Kernels:list")
|
||||
@GET
|
||||
@Path("/kernels")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseKernels.class)
|
||||
@Transform(ParseKernels.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<Kernel> list();
|
||||
|
||||
/**
|
||||
* A paged version of KernelApi#list()
|
||||
*
|
||||
* @return a Paged, Fluent Iterable that is able to fetch additional pages when required
|
||||
* @see PagedIterable
|
||||
* @see KernelApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Kernels:list")
|
||||
@GET
|
||||
@Path("/kernels")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseKernels.class)
|
||||
@Transform(ParseKernels.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<Kernel> list(ListOptions listOptions);
|
||||
|
||||
}
|
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.domain.MachineType;
|
||||
import org.jclouds.googlecomputeengine.functions.internal.ParseMachineTypes;
|
||||
import org.jclouds.googlecomputeengine.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.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;
|
||||
|
||||
/**
|
||||
* Provides access to MachineTypes via their REST API.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/machineTypes"/>
|
||||
*/
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(OAuthAuthenticator.class)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public interface MachineTypeApi {
|
||||
|
||||
/**
|
||||
* Returns the specified machine type resource
|
||||
*
|
||||
* @param machineTypeName name of the machine type resource to return.
|
||||
* @return If successful, this method returns a MachineType resource
|
||||
*/
|
||||
@Named("MachineTypes:get")
|
||||
@GET
|
||||
@Path("/machineTypes/{machineType}")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
MachineType get(@PathParam("machineType") String machineTypeName);
|
||||
|
||||
/**
|
||||
* @see MachineTypeApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("MachineTypes:list")
|
||||
@GET
|
||||
@Path("/machineTypes")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseMachineTypes.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<MachineType> listFirstPage();
|
||||
|
||||
/**
|
||||
* @see MachineTypeApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("MachineTypes:list")
|
||||
@GET
|
||||
@Path("/machineTypes")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseMachineTypes.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<MachineType> listAtMarker(@QueryParam("pageToken") @Nullable String marker);
|
||||
|
||||
/**
|
||||
* Retrieves the list of machine type 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.googlecomputeengine.domain.ListPage
|
||||
*/
|
||||
@Named("MachineTypes:list")
|
||||
@GET
|
||||
@Path("/machineTypes")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseMachineTypes.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<MachineType> listAtMarker(@QueryParam("pageToken") @Nullable String marker,
|
||||
ListOptions listOptions);
|
||||
|
||||
/**
|
||||
* @see MachineTypeApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("MachineTypes:list")
|
||||
@GET
|
||||
@Path("/machineTypes")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseMachineTypes.class)
|
||||
@Transform(ParseMachineTypes.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<MachineType> list();
|
||||
|
||||
/**
|
||||
* A paged version of MachineTypeApi#list()
|
||||
*
|
||||
* @return a Paged, Fluent Iterable that is able to fetch additional pages when required
|
||||
* @see PagedIterable
|
||||
* @see MachineTypeApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("MachineTypes:list")
|
||||
@GET
|
||||
@Path("/machineTypes")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseMachineTypes.class)
|
||||
@Transform(ParseMachineTypes.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<MachineType> list(ListOptions listOptions);
|
||||
|
||||
}
|
|
@ -0,0 +1,209 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
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 org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.domain.Network;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.functions.internal.ParseNetworks;
|
||||
import org.jclouds.googlecomputeengine.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.Fallback;
|
||||
import org.jclouds.rest.annotations.MapBinder;
|
||||
import org.jclouds.rest.annotations.PayloadParam;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Provides access to Networks via their REST API.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/networks"/>
|
||||
*/
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(OAuthAuthenticator.class)
|
||||
public interface NetworkApi {
|
||||
|
||||
/**
|
||||
* Returns the specified persistent network resource.
|
||||
*
|
||||
* @param networkName name of the persistent network resource to return.
|
||||
* @return a Network resource.
|
||||
*/
|
||||
@Named("Networks:get")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/networks/{network}")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
Network get(@PathParam("network") String networkName);
|
||||
|
||||
/**
|
||||
* Creates a persistent network resource in the specified project with the specified range.
|
||||
*
|
||||
* @param networkName the network name
|
||||
* @param IPv4Range the range of the network 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.
|
||||
*/
|
||||
@Named("Networks:insert")
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/networks")
|
||||
@OAuthScopes({COMPUTE_SCOPE})
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
Operation createInIPv4Range(@PayloadParam("name") String networkName,
|
||||
@PayloadParam("IPv4Range") String IPv4Range);
|
||||
|
||||
/**
|
||||
* Creates a persistent network resource in the specified project with the specified range and specified gateway.
|
||||
*
|
||||
* @param networkName the network name
|
||||
* @param IPv4Range the range of the network to be inserted.
|
||||
* @param gatewayIPv4 the range of the network 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.
|
||||
*/
|
||||
@Named("Networks:insert")
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/networks")
|
||||
@OAuthScopes({COMPUTE_SCOPE})
|
||||
@MapBinder(BindToJsonPayload.class)
|
||||
Operation createInIPv4RangeWithGateway(@PayloadParam("name") String networkName,
|
||||
@PayloadParam("IPv4Range") String IPv4Range,
|
||||
@PayloadParam("gatewayIPv4") String gatewayIPv4);
|
||||
|
||||
/**
|
||||
* Deletes the specified persistent network resource.
|
||||
*
|
||||
* @param networkName name of the persistent network 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.
|
||||
*/
|
||||
@Named("Networks:delete")
|
||||
@DELETE
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/networks/{network}")
|
||||
@OAuthScopes(COMPUTE_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
Operation delete(@PathParam("network") String networkName);
|
||||
|
||||
/**
|
||||
* @see NetworkApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Networks:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/networks")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseNetworks.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Network> listFirstPage();
|
||||
|
||||
/**
|
||||
* @see NetworkApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Networks:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/networks")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseNetworks.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Network> listAtMarker(@QueryParam("pageToken") @Nullable String marker);
|
||||
|
||||
/**
|
||||
* Retrieves the list of persistent network resources contained within 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.googlecomputeengine.domain.ListPage
|
||||
*/
|
||||
@Named("Networks:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/networks")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseNetworks.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Network> listAtMarker(@QueryParam("pageToken") @Nullable String marker,
|
||||
ListOptions options);
|
||||
|
||||
/**
|
||||
* @see NetworkApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Networks:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/networks")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseNetworks.class)
|
||||
@Transform(ParseNetworks.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<Network> list();
|
||||
|
||||
/**
|
||||
* A paged version of NetworkApi#list()
|
||||
*
|
||||
* @return a Paged, Fluent Iterable that is able to fetch additional pages when required
|
||||
* @see PagedIterable
|
||||
* @see NetworkApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Networks:list")
|
||||
@GET
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Path("/networks")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseNetworks.class)
|
||||
@Transform(ParseNetworks.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<Network> list(ListOptions options);
|
||||
}
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.QueryParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.functions.internal.ParseOperations;
|
||||
import org.jclouds.googlecomputeengine.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.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;
|
||||
|
||||
/**
|
||||
* Provides access to Operations via their REST API.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/operations"/>
|
||||
*/
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(OAuthAuthenticator.class)
|
||||
public interface OperationApi {
|
||||
|
||||
/**
|
||||
* Retrieves the specified operation resource.
|
||||
*
|
||||
* @param operationName name of the operation resource to return.
|
||||
* @return If successful, this method returns an Operation resource
|
||||
*/
|
||||
@Named("Operations:get")
|
||||
@GET
|
||||
@Path("/operations/{operation}")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
Operation get(@PathParam("operation") String operationName);
|
||||
|
||||
/**
|
||||
* Deletes the specified operation resource.
|
||||
*
|
||||
* @param operationName name of the operation resource to delete.
|
||||
*/
|
||||
@Named("Operations:delete")
|
||||
@DELETE
|
||||
@Path("/operations/{operation}")
|
||||
@OAuthScopes(COMPUTE_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
void delete(@PathParam("operation") String operationName);
|
||||
|
||||
/**
|
||||
* @see OperationApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Operations:list")
|
||||
@GET
|
||||
@Path("/operations")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ResponseParser(ParseOperations.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Operation> listFirstPage();
|
||||
|
||||
/**
|
||||
* @see OperationApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Operations:list")
|
||||
@GET
|
||||
@Path("/operations")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ResponseParser(ParseOperations.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Operation> listAtMarker(@QueryParam("pageToken") @Nullable String marker);
|
||||
|
||||
/**
|
||||
* Retrieves the listFirstPage of operation resources contained within the specified project.
|
||||
* By default the listFirstPage 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, starting at marker
|
||||
* @see ListOptions
|
||||
* @see org.jclouds.googlecomputeengine.domain.ListPage
|
||||
*/
|
||||
@Named("Operations:list")
|
||||
@GET
|
||||
@Path("/operations")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ResponseParser(ParseOperations.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Operation> listAtMarker(@QueryParam("pageToken") @Nullable String marker,
|
||||
ListOptions listOptions);
|
||||
|
||||
/**
|
||||
* @see OperationApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Operations:list")
|
||||
@GET
|
||||
@Path("/operations")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ResponseParser(ParseOperations.class)
|
||||
@Transform(ParseOperations.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<Operation> list();
|
||||
|
||||
/**
|
||||
* A paged version of OperationApi#listFirstPage()
|
||||
*
|
||||
* @return a Paged, Fluent Iterable that is able to fetch additional pages when required
|
||||
* @see PagedIterable
|
||||
* @see OperationApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Operations:list")
|
||||
@GET
|
||||
@Path("/operations")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@ResponseParser(ParseOperations.class)
|
||||
@Transform(ParseOperations.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<Operation> list(ListOptions listOptions);
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.domain.Project;
|
||||
import org.jclouds.googlecomputeengine.handlers.MetadataBinder;
|
||||
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.SkipEncoding;
|
||||
|
||||
/**
|
||||
* Provides access to Projects via their REST API.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/projects"/>
|
||||
*/
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(OAuthAuthenticator.class)
|
||||
public interface ProjectApi {
|
||||
|
||||
/**
|
||||
* Returns the specified project resource.
|
||||
*
|
||||
* @param projectName name of the project to return
|
||||
* @return if successful, this method returns a Project resource
|
||||
*/
|
||||
@Named("Projects:get")
|
||||
@GET
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
@Path("/projects/{project}")
|
||||
Project get(@PathParam("project") String projectName);
|
||||
|
||||
/**
|
||||
* Sets metadata common to all instances within the specified project using the data included in the request.
|
||||
* <p/>
|
||||
* NOTE: This *sets* metadata items on the project (vs *adding* items to metadata),
|
||||
* if there are pre-existing metadata items that must be kept these must be fetched first and then re-set on the
|
||||
* new Metadata, e.g.
|
||||
* <pre><tt>
|
||||
* Metadata.Builder current = projectApi.get("myProject").getCommonInstanceMetadata().toBuilder();
|
||||
* current.addItem("newItem","newItemValue");
|
||||
* projectApi.setCommonInstanceMetadata(current.build());
|
||||
* </tt></pre>
|
||||
*
|
||||
* @param projectName name of the project to return
|
||||
* @param commonInstanceMetadata the metadata to set
|
||||
* @return an Operations resource. To check on the status of an operation, poll the Operations resource returned
|
||||
* to you, and look for the status field.
|
||||
*/
|
||||
@Named("Projects:setCommonInstanceMetadata")
|
||||
@POST
|
||||
@Path("/projects/{project}/setCommonInstanceMetadata")
|
||||
@OAuthScopes(COMPUTE_SCOPE)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
Operation setCommonInstanceMetadata(@PathParam("project") String projectName,
|
||||
@BinderParam(MetadataBinder.class)
|
||||
Map<String, String> commonInstanceMetadata);
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
|
||||
import javax.inject.Named;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.Fallbacks.EmptyIterableWithMarkerOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.EmptyPagedIterableOnNotFoundOr404;
|
||||
import org.jclouds.Fallbacks.NullOnNotFoundOr404;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.domain.Zone;
|
||||
import org.jclouds.googlecomputeengine.functions.internal.ParseZones;
|
||||
import org.jclouds.googlecomputeengine.options.ListOptions;
|
||||
import org.jclouds.oauth.v2.config.OAuthScopes;
|
||||
import org.jclouds.oauth.v2.filters.OAuthAuthenticator;
|
||||
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;
|
||||
|
||||
/**
|
||||
* Provides access to Zones via their REST API.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/zones"/>
|
||||
*/
|
||||
@SkipEncoding({'/', '='})
|
||||
@RequestFilters(OAuthAuthenticator.class)
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public interface ZoneApi {
|
||||
|
||||
/**
|
||||
* Returns the specified zone resource
|
||||
*
|
||||
* @param zoneName name of the zone resource to return.
|
||||
* @return If successful, this method returns a Zone resource
|
||||
*/
|
||||
@Named("Zones:get")
|
||||
@GET
|
||||
@Path("/zones/{zone}")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@Fallback(NullOnNotFoundOr404.class)
|
||||
Zone get(@PathParam("zone") String zoneName);
|
||||
|
||||
/**
|
||||
* @see ZoneApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Zones:list")
|
||||
@GET
|
||||
@Path("/zones")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseZones.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Zone> listFirstPage();
|
||||
|
||||
/**
|
||||
* @see ZoneApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Zones:list")
|
||||
@GET
|
||||
@Path("/zones")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseZones.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Zone> listAtMarker(String marker);
|
||||
|
||||
/**
|
||||
* Retrieves the listFirstPage of zone resources available to the specified project.
|
||||
* By default the listFirstPage 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 listFirstPage
|
||||
* @see ListOptions
|
||||
* @see ListPage
|
||||
*/
|
||||
@Named("Zones:list")
|
||||
@GET
|
||||
@Path("/zones")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseZones.class)
|
||||
@Fallback(EmptyIterableWithMarkerOnNotFoundOr404.class)
|
||||
ListPage<Zone> listAtMarker(String marker, ListOptions listOptions);
|
||||
|
||||
/**
|
||||
* @see ZoneApi#list(org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
*/
|
||||
@Named("Zones:list")
|
||||
@GET
|
||||
@Path("/zones")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseZones.class)
|
||||
@Transform(ParseZones.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<Zone> list();
|
||||
|
||||
/**
|
||||
* A paged version of ZoneApi#listFirstPage()
|
||||
*
|
||||
* @return a Paged, Fluent Iterable that is able to fetch additional pages when required
|
||||
* @see ZoneApi#listAtMarker(String, org.jclouds.googlecomputeengine.options.ListOptions)
|
||||
* @see PagedIterable
|
||||
*/
|
||||
@Named("Zones:list")
|
||||
@GET
|
||||
@Path("/zones")
|
||||
@OAuthScopes(COMPUTE_READONLY_SCOPE)
|
||||
@ResponseParser(ParseZones.class)
|
||||
@Transform(ParseZones.ToPagedIterable.class)
|
||||
@Fallback(EmptyPagedIterableOnNotFoundOr404.class)
|
||||
PagedIterable<Zone> list(ListOptions listOptions);
|
||||
}
|
|
@ -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.googlecomputeengine.functions.internal;
|
||||
|
||||
import com.google.common.annotations.Beta;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.collect.PagedIterables;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.options.ListOptions;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.InvocationContext;
|
||||
import org.jclouds.rest.internal.GeneratedHttpRequest;
|
||||
|
||||
import static com.google.common.base.Predicates.instanceOf;
|
||||
import static com.google.common.collect.Iterables.tryFind;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Beta
|
||||
public abstract class BaseToPagedIterable<T, I extends BaseToPagedIterable<T, I>> implements
|
||||
Function<ListPage<T>, PagedIterable<T>>, InvocationContext<I> {
|
||||
|
||||
private GeneratedHttpRequest request;
|
||||
|
||||
@Override
|
||||
public PagedIterable<T> apply(ListPage<T> input) {
|
||||
if (input.nextMarker() == null)
|
||||
return PagedIterables.of(input);
|
||||
|
||||
Optional<Object> project = tryFind(request.getCaller().get().getArgs(), instanceOf(String.class));
|
||||
|
||||
Optional<Object> listOptions = tryFind(request.getInvocation().getArgs(), instanceOf(ListOptions.class));
|
||||
|
||||
assert project.isPresent() : String.format("programming error, method %s should have a string param for the "
|
||||
+ "project", request.getCaller().get().getInvokable());
|
||||
|
||||
return PagedIterables.advance(
|
||||
input, fetchNextPage(project.get().toString(), (ListOptions) listOptions.orNull()));
|
||||
}
|
||||
|
||||
protected abstract Function<Object, IterableWithMarker<T>> fetchNextPage(String projectName,
|
||||
ListOptions listOptions);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public I setContext(HttpRequest request) {
|
||||
this.request = GeneratedHttpRequest.class.cast(request);
|
||||
return (I) this;
|
||||
}
|
||||
}
|
|
@ -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.googlecomputeengine.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,69 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.functions.internal;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.domain.Disk;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.options.ListOptions;
|
||||
import org.jclouds.http.functions.ParseJson;
|
||||
import org.jclouds.json.Json;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@Singleton
|
||||
public class ParseDisks extends ParseJson<ListPage<Disk>> {
|
||||
|
||||
@Inject
|
||||
public ParseDisks(Json json) {
|
||||
super(json, new TypeLiteral<ListPage<Disk>>() {});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends BaseToPagedIterable<Disk, ToPagedIterable> {
|
||||
|
||||
private final GoogleComputeEngineApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(GoogleComputeEngineApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Disk>> fetchNextPage(final String projectName,
|
||||
final ListOptions options) {
|
||||
return new Function<Object, IterableWithMarker<Disk>>() {
|
||||
|
||||
@Override
|
||||
public IterableWithMarker<Disk> apply(Object input) {
|
||||
return api.getDiskApiForProject(projectName).listAtMarker(input.toString(), options);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.googlecomputeengine.functions.internal;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.domain.Firewall;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.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 GoogleComputeEngineApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(GoogleComputeEngineApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Firewall>> fetchNextPage(final String projectName,
|
||||
final ListOptions options) {
|
||||
return new Function<Object, IterableWithMarker<Firewall>>() {
|
||||
|
||||
@Override
|
||||
public IterableWithMarker<Firewall> apply(Object input) {
|
||||
return api.getFirewallApiForProject(projectName).listAtMarker(input.toString(), options);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.googlecomputeengine.functions.internal;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.domain.Image;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.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 ParseImages extends ParseJson<ListPage<Image>> {
|
||||
|
||||
@Inject
|
||||
public ParseImages(Json json) {
|
||||
super(json, new TypeLiteral<ListPage<Image>>() {});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends BaseToPagedIterable<Image, ToPagedIterable> {
|
||||
|
||||
private final GoogleComputeEngineApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(GoogleComputeEngineApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Image>> fetchNextPage(final String projectName,
|
||||
final ListOptions options) {
|
||||
return new Function<Object, IterableWithMarker<Image>>() {
|
||||
|
||||
@Override
|
||||
public IterableWithMarker<Image> apply(Object input) {
|
||||
return api.getImageApiForProject(projectName).listAtMarker(input.toString(), options);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.googlecomputeengine.functions.internal;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.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 ParseInstances extends ParseJson<ListPage<Instance>> {
|
||||
|
||||
@Inject
|
||||
public ParseInstances(Json json) {
|
||||
super(json, new TypeLiteral<ListPage<Instance>>() {});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends BaseToPagedIterable<Instance, ToPagedIterable> {
|
||||
|
||||
private final GoogleComputeEngineApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(GoogleComputeEngineApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Instance>> fetchNextPage(final String projectName,
|
||||
final ListOptions options) {
|
||||
return new Function<Object, IterableWithMarker<Instance>>() {
|
||||
|
||||
@Override
|
||||
public IterableWithMarker<Instance> apply(Object input) {
|
||||
return api.getInstanceApiForProject(projectName).listAtMarker(input.toString(), options);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.googlecomputeengine.functions.internal;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.domain.Kernel;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.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 ParseKernels extends ParseJson<ListPage<Kernel>> {
|
||||
|
||||
@Inject
|
||||
public ParseKernels(Json json) {
|
||||
super(json, new TypeLiteral<ListPage<Kernel>>() {});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends BaseToPagedIterable<Kernel, ToPagedIterable> {
|
||||
|
||||
private final GoogleComputeEngineApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(GoogleComputeEngineApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Kernel>> fetchNextPage(final String projectName,
|
||||
final ListOptions options) {
|
||||
return new Function<Object, IterableWithMarker<Kernel>>() {
|
||||
|
||||
@Override
|
||||
public IterableWithMarker<Kernel> apply(Object input) {
|
||||
return api.getKernelApiForProject(projectName).listAtMarker(input.toString(), options);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.googlecomputeengine.functions.internal;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.domain.MachineType;
|
||||
import org.jclouds.googlecomputeengine.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 ParseMachineTypes extends ParseJson<ListPage<MachineType>> {
|
||||
|
||||
@Inject
|
||||
public ParseMachineTypes(Json json) {
|
||||
super(json, new TypeLiteral<ListPage<MachineType>>() {});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends BaseToPagedIterable<MachineType, ToPagedIterable> {
|
||||
|
||||
private final GoogleComputeEngineApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(GoogleComputeEngineApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<MachineType>> fetchNextPage(final String projectName,
|
||||
final ListOptions options) {
|
||||
return new Function<Object, IterableWithMarker<MachineType>>() {
|
||||
|
||||
@Override
|
||||
public IterableWithMarker<MachineType> apply(Object input) {
|
||||
return api.getMachineTypeApiForProject(projectName).listAtMarker(input.toString(), options);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.googlecomputeengine.functions.internal;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.domain.Network;
|
||||
import org.jclouds.googlecomputeengine.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 ParseNetworks extends ParseJson<ListPage<Network>> {
|
||||
|
||||
@Inject
|
||||
public ParseNetworks(Json json) {
|
||||
super(json, new TypeLiteral<ListPage<Network>>() {});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends BaseToPagedIterable<Network, ToPagedIterable> {
|
||||
|
||||
private final GoogleComputeEngineApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(GoogleComputeEngineApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Network>> fetchNextPage(final String projectName,
|
||||
final ListOptions options) {
|
||||
return new Function<Object, IterableWithMarker<Network>>() {
|
||||
|
||||
@Override
|
||||
public IterableWithMarker<Network> apply(Object input) {
|
||||
return api.getNetworkApiForProject(projectName).listAtMarker(input.toString(), options);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.googlecomputeengine.functions.internal;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.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 ParseOperations extends ParseJson<ListPage<Operation>> {
|
||||
|
||||
@Inject
|
||||
public ParseOperations(Json json) {
|
||||
super(json, new TypeLiteral<ListPage<Operation>>() {});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends BaseToPagedIterable<Operation, ToPagedIterable> {
|
||||
|
||||
private final GoogleComputeEngineApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(GoogleComputeEngineApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Operation>> fetchNextPage(final String projectName,
|
||||
final ListOptions options) {
|
||||
return new Function<Object, IterableWithMarker<Operation>>() {
|
||||
|
||||
@Override
|
||||
public IterableWithMarker<Operation> apply(Object input) {
|
||||
return api.getOperationApiForProject(projectName).listAtMarker(input.toString(), options);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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.googlecomputeengine.functions.internal;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.domain.Zone;
|
||||
import org.jclouds.googlecomputeengine.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 ParseZones extends ParseJson<ListPage<Zone>> {
|
||||
|
||||
@Inject
|
||||
public ParseZones(Json json) {
|
||||
super(json, new TypeLiteral<ListPage<Zone>>() {});
|
||||
}
|
||||
|
||||
public static class ToPagedIterable extends BaseToPagedIterable<Zone, ToPagedIterable> {
|
||||
|
||||
private final GoogleComputeEngineApi api;
|
||||
|
||||
@Inject
|
||||
protected ToPagedIterable(GoogleComputeEngineApi api) {
|
||||
this.api = checkNotNull(api, "api");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Function<Object, IterableWithMarker<Zone>> fetchNextPage(final String projectName,
|
||||
final ListOptions options) {
|
||||
return new Function<Object, IterableWithMarker<Zone>>() {
|
||||
|
||||
@Override
|
||||
public IterableWithMarker<Zone> apply(Object input) {
|
||||
return api.getZoneApiForProject(projectName).listAtMarker(input.toString(), options);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.handlers;
|
||||
|
||||
import org.jclouds.googlecomputeengine.options.FirewallOptions;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.MapBinder;
|
||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class FirewallBinder implements MapBinder {
|
||||
|
||||
@Inject
|
||||
private BindToJsonPayload jsonBinder;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
|
||||
FirewallOptions options = (FirewallOptions) checkNotNull(postParams.get("options"), "firewallOptions");
|
||||
String name = (String) checkNotNull(postParams.get("name"), "name");
|
||||
URI network = (URI) checkNotNull(postParams.get("network"), "network");
|
||||
options.name(name);
|
||||
options.network(network);
|
||||
return bindToRequest(request, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
|
||||
return jsonBinder.bindToRequest(request, input);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/**
|
||||
* 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.googlecomputeengine.handlers;
|
||||
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpErrorHandler;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.http.HttpResponseException;
|
||||
import org.jclouds.rest.AuthorizationException;
|
||||
import org.jclouds.rest.ResourceNotFoundException;
|
||||
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import static org.jclouds.http.HttpUtils.closeClientButKeepContentStream;
|
||||
|
||||
/**
|
||||
* This will parse and set an appropriate exception on the command object.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class GoogleComputeEngineErrorHandler implements HttpErrorHandler {
|
||||
public void handleError(HttpCommand command, HttpResponse response) {
|
||||
// it is important to always read fully and close streams
|
||||
byte[] data = closeClientButKeepContentStream(response);
|
||||
String message = data != null ? new String(data) : null;
|
||||
|
||||
Exception exception = message != null ? new HttpResponseException(command, response, message)
|
||||
: new HttpResponseException(command, response);
|
||||
message = message != null ? message : String.format("%s -> %s", command.getCurrentRequest().getRequestLine(),
|
||||
response.getStatusLine());
|
||||
switch (response.getStatusCode()) {
|
||||
case 400:
|
||||
break;
|
||||
case 401:
|
||||
case 403:
|
||||
exception = new AuthorizationException(message, exception);
|
||||
break;
|
||||
case 404:
|
||||
if (!command.getCurrentRequest().getMethod().equals("DELETE")) {
|
||||
exception = new ResourceNotFoundException(message, exception);
|
||||
}
|
||||
break;
|
||||
case 409:
|
||||
exception = new IllegalStateException(message, exception);
|
||||
break;
|
||||
}
|
||||
command.setException(exception);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.handlers;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import org.jclouds.googlecomputeengine.domain.InstanceTemplate;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.MapBinder;
|
||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class InstanceBinder implements MapBinder {
|
||||
|
||||
@Inject
|
||||
private BindToJsonPayload jsonBinder;
|
||||
|
||||
@Inject
|
||||
@Named("machineTypes")
|
||||
Function<String, URI> machineTypesToURI;
|
||||
|
||||
@Inject
|
||||
@Named("zones")
|
||||
Function<String, URI> zonesToURI;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Map<String, Object> postParams) {
|
||||
InstanceTemplate template = (InstanceTemplate) checkNotNull(postParams.get("template"), "template");
|
||||
template.name(checkNotNull(postParams.get("name"), "name").toString());
|
||||
template.zone(zonesToURI.apply((String) checkNotNull(postParams.get("zone"), "zone")));
|
||||
|
||||
if (template.getMachineTypeName() != null) {
|
||||
template.machineType(machineTypesToURI.apply(template.getMachineTypeName()));
|
||||
}
|
||||
template.zone((String) null);
|
||||
template.machineType((String) null);
|
||||
return bindToRequest(request, template);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
|
||||
return jsonBinder.bindToRequest(request, input);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.handlers;
|
||||
|
||||
import org.jclouds.googlecomputeengine.config.GoogleComputeEngineParserModule;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.rest.Binder;
|
||||
import org.jclouds.rest.binders.BindToJsonPayload;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class MetadataBinder implements Binder {
|
||||
|
||||
@Inject
|
||||
private BindToJsonPayload jsonBinder;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <R extends HttpRequest> R bindToRequest(R request, Object input) {
|
||||
Map<String, String> metadataEntries = (Map<String, String>) checkNotNull(input, "input metadata");
|
||||
return jsonBinder.bindToRequest(request, new GoogleComputeEngineParserModule.Metadata(metadataEntries));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.options;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jclouds.googlecomputeengine.domain.Firewall;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Options to create a firewall.
|
||||
*
|
||||
* @see Firewall
|
||||
* @author David Alves
|
||||
*/
|
||||
public class FirewallOptions {
|
||||
|
||||
private String name;
|
||||
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<Firewall.Rule> allowed = ImmutableSet.builder();
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getAllowed()
|
||||
*/
|
||||
public Set<Firewall.Rule> getAllowed() {
|
||||
return allowed.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getAllowed()
|
||||
*/
|
||||
public FirewallOptions addAllowedRule(Firewall.Rule allowedRule) {
|
||||
this.allowed.add(allowedRule);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getAllowed()
|
||||
*/
|
||||
public FirewallOptions allowedRules(Set<Firewall.Rule> allowedRules) {
|
||||
this.allowed = ImmutableSet.builder();
|
||||
this.allowed.addAll(allowedRules);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getName()
|
||||
*/
|
||||
public FirewallOptions name(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getName()
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getNetwork()
|
||||
*/
|
||||
public FirewallOptions network(URI network) {
|
||||
this.network = network;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getNetwork()
|
||||
*/
|
||||
public URI getNetwork() {
|
||||
return network;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getSourceRanges()
|
||||
*/
|
||||
public Set<String> getSourceRanges() {
|
||||
return sourceRanges.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getSourceRanges()
|
||||
*/
|
||||
public FirewallOptions addSourceRange(String sourceRange) {
|
||||
this.sourceRanges.add(sourceRange);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getSourceRanges()
|
||||
*/
|
||||
public FirewallOptions sourceRanges(Set<String> sourceRanges) {
|
||||
this.sourceRanges = ImmutableSet.builder();
|
||||
this.sourceRanges.addAll(sourceRanges);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getSourceTags()
|
||||
*/
|
||||
public Set<String> getSourceTags() {
|
||||
return sourceTags.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getSourceTags()
|
||||
*/
|
||||
public FirewallOptions addSourceTag(String sourceTag) {
|
||||
this.sourceTags.add(sourceTag);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getSourceTags()
|
||||
*/
|
||||
public FirewallOptions sourceTags(Set<String> sourceTags) {
|
||||
this.sourceTags = ImmutableSet.builder();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getTargetTags()
|
||||
*/
|
||||
public Set<String> getTargetTags() {
|
||||
return targetTags.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getTargetTags()
|
||||
*/
|
||||
public FirewallOptions addTargetTag(String targetTag) {
|
||||
this.targetTags.add(targetTag);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.jclouds.googlecomputeengine.domain.Firewall#getTargetTags()
|
||||
*/
|
||||
public FirewallOptions targetTags(Set<String> targetTags) {
|
||||
this.targetTags = ImmutableSet.builder();
|
||||
this.targetTags.addAll(targetTags);
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.options;
|
||||
|
||||
import org.jclouds.http.options.BaseHttpRequestOptions;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Allows to optionally specify a filter, max results and a page token for <code>listFirstPage()</code> REST methods.
|
||||
*
|
||||
* @author David Alves
|
||||
* @see <a href="https://developers.google.com/compute/docs/reference/v1beta13/operations/listFirstPage"/>
|
||||
*/
|
||||
public class ListOptions extends BaseHttpRequestOptions {
|
||||
|
||||
/**
|
||||
* Optional. Filter expression for filtering listed resources, in the form filter={expression}. Your {expression}
|
||||
* must contain the following:
|
||||
* <p/>
|
||||
* {@code <field_name> <comparison_string> <literal_string>}
|
||||
* <ul>
|
||||
* <li>{@code <field_name>}: The name of the field you want to compare. The field name must be valid for the
|
||||
* type of resource being filtered. Only atomic field types are supported (string, number,
|
||||
* boolean). Array and object fields are not currently supported.</li>
|
||||
* <li>{@code <comparison_string>}: The comparison string, either eq (equals) or ne (not equals).</li>
|
||||
* <li>{@code <literal_string>}: The literal string value to filter to. The literal value must be valid
|
||||
* for the type of field (string, number, boolean). For string fields, the literal value is interpreted as a
|
||||
* regular expression using RE2 syntax. The literal value must match the entire field. For example,
|
||||
* when filtering instances, name eq my_instance won't work, but name eq .*my_instance will work.</li>
|
||||
* </ul>
|
||||
* <p/>
|
||||
* For example:
|
||||
* <p/>
|
||||
* {@code filter=status ne RUNNING}
|
||||
* <p/>
|
||||
* The above filter returns only results whose status field does not equal RUNNING. You can also enclose your
|
||||
* literal string in single, double, or no quotes. For example, all three of the following would be valid
|
||||
* expressions:
|
||||
* <p/>
|
||||
* {@code filter=status ne "RUNNING"}<br/>
|
||||
* {@code filter=status ne 'RUNNING'}<br/>
|
||||
* {@code filter=status ne RUNNING}<br/>
|
||||
* <p/>
|
||||
* Complex regular expressions can also be used, like the following:
|
||||
* {@code name eq '."my_instance_[0-9]+'}
|
||||
*/
|
||||
public ListOptions filter(String filter) {
|
||||
this.queryParameters.put("filter", checkNotNull(filter, "filter"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets Maximum count of results to be returned. Maximum and default value is 100. Acceptable values are 0 to
|
||||
* 100, inclusive. (Default: 100)
|
||||
*/
|
||||
public ListOptions maxResults(Integer maxResults) {
|
||||
this.queryParameters.put("maxResults", checkNotNull(maxResults, "maxResults") + "");
|
||||
return this;
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
/**
|
||||
* @see ListOptions#filter(String)
|
||||
*/
|
||||
public ListOptions filter(String filter) {
|
||||
return new ListOptions().filter(filter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ListOptions#maxResults(Integer)
|
||||
*/
|
||||
public ListOptions maxResults(Integer maxResults) {
|
||||
return new ListOptions().maxResults(maxResults);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.predicates;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.inject.Inject;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.config.UserProject;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Tests that an Operation is done, returning the completed Operation when it is.
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
public class OperationDonePredicate implements Predicate<AtomicReference<Operation>> {
|
||||
|
||||
private final GoogleComputeEngineApi api;
|
||||
private final Supplier<String> project;
|
||||
|
||||
@Inject
|
||||
OperationDonePredicate(GoogleComputeEngineApi api, @UserProject Supplier<String> project) {
|
||||
this.api = api;
|
||||
this.project = project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(AtomicReference<Operation> input) {
|
||||
checkNotNull(input, "input");
|
||||
Operation current = api.getOperationApiForProject(project.get()).get(input.get().getName());
|
||||
switch (current.getStatus()) {
|
||||
case DONE:
|
||||
input.set(current);
|
||||
return true;
|
||||
case PENDING:
|
||||
case RUNNING:
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
org.jclouds.googlecomputeengine.GoogleComputeEngineApiMetadata
|
|
@ -0,0 +1,41 @@
|
|||
/**
|
||||
* 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.googlecomputeengine;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import org.jclouds.View;
|
||||
import org.jclouds.apis.internal.BaseApiMetadataTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* Tests that GoogleComputeApiMetadata is properly registered in ServiceLoader
|
||||
* <p/>
|
||||
* <pre>
|
||||
* META-INF/services/org.jclouds.apis.ApiMetadata
|
||||
* </pre>
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "GoogleComputeApiMetadataTest")
|
||||
public class GoogleComputeEngineApiMetadataTest extends BaseApiMetadataTest {
|
||||
public GoogleComputeEngineApiMetadataTest() {
|
||||
super(new GoogleComputeEngineApiMetadata(), ImmutableSet.<TypeToken<? extends View>>of());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* 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.googlecomputeengine;
|
||||
|
||||
import org.jclouds.oauth.v2.internal.BaseOAuthAuthenticatedApiLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "live")
|
||||
public class GoogleComputeEngineAuthenticatedRestContextLiveTest extends BaseOAuthAuthenticatedApiLiveTest<GoogleComputeEngineApi> {
|
||||
|
||||
public GoogleComputeEngineAuthenticatedRestContextLiveTest() {
|
||||
provider = "google-compute-engine";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getScopes() {
|
||||
return GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* 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.googlecomputeengine;
|
||||
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.Image;
|
||||
import org.jclouds.googlecomputeengine.features.ImageApi;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiExpectTest;
|
||||
import org.jclouds.googlecomputeengine.options.ListOptions;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.testng.Assert.assertSame;
|
||||
|
||||
/**
|
||||
* A test specifically for the paging system. The code used is common to all list() methods so we're using Images
|
||||
* but it could be anything else.
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class PageSystemExpectTest extends BaseGoogleComputeEngineApiExpectTest {
|
||||
|
||||
public void testGetSinglePage() {
|
||||
HttpRequest list = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/images")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/image_list_single_page.json")).build();
|
||||
|
||||
ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, list, operationResponse).getImageApiForProject("myproject");
|
||||
|
||||
PagedIterable<Image> images = imageApi.list();
|
||||
|
||||
// expect one page
|
||||
assertSame(images.size(), 1);
|
||||
// with three images
|
||||
assertSame(images.concat().size(), 3);
|
||||
}
|
||||
|
||||
public void testGetMultiplePages() {
|
||||
HttpRequest list1 = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/images?maxResults=3")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpRequest list2 = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/images?pageToken" +
|
||||
"=CgVJTUFHRRIbZ29vZ2xlLmNlbnRvcy02LTItdjIwMTIwNjIx&maxResults=3")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpRequest list3 = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/images?pageToken" +
|
||||
"=CgVJTUFHRRIbZ29vZ2xlLmdjZWwtMTAtMDQtdjIwMTIxMTA2&maxResults=3")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse list1response = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/image_list_multiple_page_1.json")).build();
|
||||
|
||||
HttpResponse list2Response = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/image_list_multiple_page_2.json")).build();
|
||||
|
||||
HttpResponse list3Response = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/image_list_single_page.json")).build();
|
||||
|
||||
|
||||
ImageApi imageApi = orderedRequestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, list1, list1response, list2, list2Response, list3, list3Response)
|
||||
.getImageApiForProject("myproject");
|
||||
|
||||
PagedIterable<Image> images = imageApi.list(new ListOptions.Builder().maxResults(3));
|
||||
|
||||
int imageCounter = 0;
|
||||
for (IterableWithMarker<Image> page : images) {
|
||||
for (Image image : page) {
|
||||
imageCounter++;
|
||||
}
|
||||
}
|
||||
assertSame(imageCounter, 9);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,415 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.RunNodesException;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.googlecomputeengine.compute.options.GoogleComputeEngineTemplateOptions;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance;
|
||||
import org.jclouds.googlecomputeengine.features.InstanceApiExpectTest;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineServiceExpectTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.util.Strings2;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.features.FirewallApiExpectTest.GET_FIREWALL_REQUEST;
|
||||
import static org.jclouds.googlecomputeengine.features.ImageApiExpectTest.LIST_PROJECT_IMAGES_REQUEST;
|
||||
import static org.jclouds.googlecomputeengine.features.ImageApiExpectTest.LIST_PROJECT_IMAGES_RESPONSE;
|
||||
import static org.jclouds.googlecomputeengine.features.InstanceApiExpectTest.LIST_INSTANCES_REQUEST;
|
||||
import static org.jclouds.googlecomputeengine.features.InstanceApiExpectTest.LIST_INSTANCES_RESPONSE;
|
||||
import static org.jclouds.googlecomputeengine.features.MachineTypeApiExpectTest.LIST_MACHINE_TYPES_REQUEST;
|
||||
import static org.jclouds.googlecomputeengine.features.MachineTypeApiExpectTest.LIST_MACHINE_TYPES_RESPONSE;
|
||||
import static org.jclouds.googlecomputeengine.features.NetworkApiExpectTest.GET_NETWORK_REQUEST;
|
||||
import static org.jclouds.googlecomputeengine.features.OperationApiExpectTest.GET_OPERATION_REQUEST;
|
||||
import static org.jclouds.googlecomputeengine.features.OperationApiExpectTest.GET_OPERATION_RESPONSE;
|
||||
import static org.jclouds.googlecomputeengine.features.ZoneApiExpectTest.LIST_ZONES_REQ;
|
||||
import static org.jclouds.googlecomputeengine.features.ZoneApiExpectTest.LIST_ZONES_RESPONSE;
|
||||
import static org.jclouds.util.Strings2.toStringAndClose;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class GoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngineServiceExpectTest {
|
||||
|
||||
public static final HttpRequest LIST_GOOGLE_IMAGES_REQUEST = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/google/images")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
public static final HttpResponse LIST_GOOGLE_IMAGES_RESPONSE = HttpResponse.builder().statusCode(200)
|
||||
.payload(staticPayloadFromResource("/image_list_single_page.json")).build();
|
||||
|
||||
private HttpRequest INSERT_NETWORK_REQUEST = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/networks")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromStringWithContentType("{\"name\":\"jclouds-test\",\"IPv4Range\":\"10.0.0.0/8\"}",
|
||||
MediaType.APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
private HttpRequest INSERT_FIREWALL_REQUEST = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/firewalls")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromStringWithContentType("{\"name\":\"jclouds-test\",\"network\":\"https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/networks/jclouds-test\"," +
|
||||
"\"sourceRanges\":[\"10.0.0.0/8\",\"0.0.0.0/0\"],\"allowed\":[{\"IPProtocol\":\"tcp\"," +
|
||||
"\"ports\":[\"22\"]}," +
|
||||
"{\"IPProtocol\":\"udp\",\"ports\":[\"22\"]}]}",
|
||||
MediaType.APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
private HttpResponse GET_NETWORK_RESPONSE = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromStringWithContentType("{\n" +
|
||||
" \"kind\": \"compute#network\",\n" +
|
||||
" \"id\": \"13024414170909937976\",\n" +
|
||||
" \"creationTimestamp\": \"2012-10-24T20:13:19.967\",\n" +
|
||||
" \"selfLink\": \"https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/networks/jclouds-test\",\n" +
|
||||
" \"name\": \"jclouds-test\",\n" +
|
||||
" \"description\": \"test network\",\n" +
|
||||
" \"IPv4Range\": \"10.0.0.0/8\",\n" +
|
||||
" \"gatewayIPv4\": \"10.0.0.1\"\n" +
|
||||
"}", MediaType.APPLICATION_JSON)).build();
|
||||
|
||||
private HttpResponse SUCESSFULL_OPERATION_RESPONSE = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
|
||||
private HttpResponse getInstanceResponseForInstanceAndNetworkAndStatus(String instanceName, String networkName,
|
||||
String status) throws
|
||||
IOException {
|
||||
return HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromStringWithContentType(
|
||||
replaceInstanceNameNetworkAndStatusOnResource("/instance_get.json",
|
||||
instanceName, networkName, status),
|
||||
"application/json")).build();
|
||||
}
|
||||
|
||||
private HttpResponse getListInstancesResponseForSingleInstanceAndNetworkAndStatus(String instanceName,
|
||||
String networkName,
|
||||
String status) {
|
||||
return HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromStringWithContentType(
|
||||
replaceInstanceNameNetworkAndStatusOnResource("/instance_list.json",
|
||||
instanceName, networkName, status),
|
||||
"application/json")).build();
|
||||
}
|
||||
|
||||
private String replaceInstanceNameNetworkAndStatusOnResource(String resourceName, String instanceName,
|
||||
String networkName, String status) {
|
||||
try {
|
||||
return Strings2.toStringAndClose(this.getClass().getResourceAsStream(resourceName)).replace("test-0",
|
||||
instanceName).replace("default", networkName).replace("RUNNING", status);
|
||||
} catch (IOException e) {
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
|
||||
private HttpRequest createInstanceRequestForInstance(String instanceName, String networkName, String publicKey) {
|
||||
return HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/instances")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromStringWithContentType("{\"name\":\"" + instanceName + "\"," +
|
||||
"\"machineType\":\"https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/machineTypes/n1-standard-1\"," +
|
||||
"\"zone\":\"https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/zones/us-central1-a\"," +
|
||||
"\"image\":\"https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/google/images/gcel-12-04-v20121106\"," +
|
||||
"\"tags\":[],\"serviceAccounts\":[]," +
|
||||
"\"networkInterfaces\":[{\"network\":\"https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/networks/" + networkName + "\"," +
|
||||
"\"accessConfigs\":[{\"type\":\"ONE_TO_ONE_NAT\"}]}]," +
|
||||
"\"metadata\":{\"kind\":\"compute#metadata\",\"items\":[{\"key\":\"sshKeys\"," +
|
||||
"\"value\":\"jclouds:" +
|
||||
publicKey + " jclouds@localhost\"}]}}",
|
||||
MediaType.APPLICATION_JSON)).build();
|
||||
}
|
||||
|
||||
private HttpRequest getInstanceRequestForInstance(String instanceName) {
|
||||
return HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances/" + instanceName)
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Properties setupProperties() {
|
||||
Properties overrides = super.setupProperties();
|
||||
overrides.put("google-compute-engine.identity", "myproject");
|
||||
try {
|
||||
overrides.put("google-compute-engine.credential", toStringAndClose(getClass().getResourceAsStream("/testpk.pem")));
|
||||
} catch (IOException e) {
|
||||
Throwables.propagate(e);
|
||||
}
|
||||
return overrides;
|
||||
}
|
||||
|
||||
@Test(enabled = false)
|
||||
public void testThrowsAuthorizationException() throws Exception {
|
||||
|
||||
Properties properties = new Properties();
|
||||
properties.setProperty("oauth.identity", "MOMMA");
|
||||
properties.setProperty("oauth.credential", "MiA");
|
||||
|
||||
ComputeService client = requestsSendResponses(ImmutableMap.<HttpRequest, HttpResponse>of(), createModule(),
|
||||
properties);
|
||||
Template template = client.templateBuilder().build();
|
||||
Template toMatch = client.templateBuilder().imageId(template.getImage().getId()).build();
|
||||
assertEquals(toMatch.getImage(), template.getImage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTemplateMatch() throws Exception {
|
||||
ImmutableMap<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.
|
||||
<HttpRequest, HttpResponse>builder()
|
||||
.put(requestForScopes(COMPUTE_READONLY_SCOPE), TOKEN_RESPONSE)
|
||||
.put(LIST_ZONES_REQ, LIST_ZONES_RESPONSE)
|
||||
.put(LIST_PROJECT_IMAGES_REQUEST, LIST_PROJECT_IMAGES_RESPONSE)
|
||||
.put(LIST_GOOGLE_IMAGES_REQUEST, LIST_GOOGLE_IMAGES_RESPONSE)
|
||||
.put(LIST_MACHINE_TYPES_REQUEST, LIST_MACHINE_TYPES_RESPONSE)
|
||||
.build();
|
||||
|
||||
ComputeService client = requestsSendResponses(requestResponseMap);
|
||||
Template template = client.templateBuilder().build();
|
||||
Template toMatch = client.templateBuilder().imageId(template.getImage().getId()).build();
|
||||
assertEquals(toMatch.getImage(), template.getImage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNetworksAndFirewallDeletedWhenAllGroupNodesAreTerminated() throws IOException {
|
||||
|
||||
HttpRequest deleteNodeRequest = HttpRequest.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances/test-delete-networks")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpRequest deleteFirewallRequest = HttpRequest.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/firewalls/jclouds-test-delete")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpRequest deleteNetworkReqquest = HttpRequest.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/networks/jclouds-test-delete")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
List<HttpRequest> orderedRequests = ImmutableList.<HttpRequest>builder()
|
||||
.add(requestForScopes(COMPUTE_READONLY_SCOPE))
|
||||
.add(getInstanceRequestForInstance("test-delete-networks"))
|
||||
.add(LIST_PROJECT_IMAGES_REQUEST)
|
||||
.add(LIST_GOOGLE_IMAGES_REQUEST)
|
||||
.add(LIST_ZONES_REQ)
|
||||
.add(LIST_MACHINE_TYPES_REQUEST)
|
||||
.add(requestForScopes(COMPUTE_SCOPE))
|
||||
.add(deleteNodeRequest)
|
||||
.add(GET_OPERATION_REQUEST)
|
||||
.add(getInstanceRequestForInstance("test-delete-networks"))
|
||||
.add(LIST_PROJECT_IMAGES_REQUEST)
|
||||
.add(LIST_GOOGLE_IMAGES_REQUEST)
|
||||
.add(LIST_ZONES_REQ)
|
||||
.add(LIST_MACHINE_TYPES_REQUEST)
|
||||
.add(LIST_INSTANCES_REQUEST)
|
||||
.add(LIST_PROJECT_IMAGES_REQUEST)
|
||||
.add(LIST_GOOGLE_IMAGES_REQUEST)
|
||||
.add(LIST_ZONES_REQ)
|
||||
.add(LIST_MACHINE_TYPES_REQUEST)
|
||||
.add(deleteFirewallRequest)
|
||||
.add(GET_OPERATION_REQUEST)
|
||||
.add(deleteNetworkReqquest)
|
||||
.add(GET_OPERATION_REQUEST)
|
||||
.build();
|
||||
|
||||
|
||||
List<HttpResponse> orderedResponses = ImmutableList.<HttpResponse>builder()
|
||||
.add(TOKEN_RESPONSE)
|
||||
.add(getInstanceResponseForInstanceAndNetworkAndStatus("test-delete-networks", "test-network", Instance
|
||||
.Status.RUNNING.name()))
|
||||
.add(LIST_PROJECT_IMAGES_RESPONSE)
|
||||
.add(LIST_GOOGLE_IMAGES_RESPONSE)
|
||||
.add(LIST_ZONES_RESPONSE)
|
||||
.add(LIST_MACHINE_TYPES_RESPONSE)
|
||||
.add(TOKEN_RESPONSE)
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(GET_OPERATION_RESPONSE)
|
||||
.add(getInstanceResponseForInstanceAndNetworkAndStatus("test-delete-networks", "test-network", Instance
|
||||
.Status.TERMINATED.name()))
|
||||
.add(LIST_PROJECT_IMAGES_RESPONSE)
|
||||
.add(LIST_GOOGLE_IMAGES_RESPONSE)
|
||||
.add(LIST_ZONES_RESPONSE)
|
||||
.add(LIST_MACHINE_TYPES_RESPONSE)
|
||||
.add(getListInstancesResponseForSingleInstanceAndNetworkAndStatus("test-delete-networks",
|
||||
"test-network", Instance
|
||||
.Status.TERMINATED.name()))
|
||||
.add(LIST_PROJECT_IMAGES_RESPONSE)
|
||||
.add(LIST_GOOGLE_IMAGES_RESPONSE)
|
||||
.add(LIST_ZONES_RESPONSE)
|
||||
.add(LIST_MACHINE_TYPES_RESPONSE)
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(GET_OPERATION_RESPONSE)
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(GET_OPERATION_RESPONSE)
|
||||
.build();
|
||||
|
||||
ComputeService client = orderedRequestsSendResponses(orderedRequests, orderedResponses);
|
||||
client.destroyNode("test-delete-networks");
|
||||
|
||||
}
|
||||
|
||||
public void testListLocationsWhenResponseIs2xx() throws Exception {
|
||||
|
||||
ImmutableMap<HttpRequest, HttpResponse> requestResponseMap = ImmutableMap.
|
||||
<HttpRequest, HttpResponse>builder()
|
||||
.put(requestForScopes(COMPUTE_READONLY_SCOPE), TOKEN_RESPONSE)
|
||||
.put(LIST_ZONES_REQ, LIST_ZONES_RESPONSE)
|
||||
.put(LIST_INSTANCES_REQUEST, LIST_INSTANCES_RESPONSE)
|
||||
.put(LIST_PROJECT_IMAGES_REQUEST, LIST_PROJECT_IMAGES_RESPONSE)
|
||||
.put(LIST_GOOGLE_IMAGES_REQUEST, LIST_GOOGLE_IMAGES_RESPONSE)
|
||||
.put(LIST_MACHINE_TYPES_REQUEST, LIST_MACHINE_TYPES_RESPONSE)
|
||||
.build();
|
||||
|
||||
ComputeService apiWhenServersExist = requestsSendResponses(requestResponseMap);
|
||||
|
||||
Set<? extends Location> locations = apiWhenServersExist.listAssignableLocations();
|
||||
|
||||
assertNotNull(locations);
|
||||
assertEquals(locations.size(), 2);
|
||||
assertEquals(locations.iterator().next().getId(), "us-central1-a");
|
||||
|
||||
assertNotNull(apiWhenServersExist.listNodes());
|
||||
assertEquals(apiWhenServersExist.listNodes().size(), 1);
|
||||
assertEquals(apiWhenServersExist.listNodes().iterator().next().getId(), "test-0");
|
||||
assertEquals(apiWhenServersExist.listNodes().iterator().next().getName(), "test-0");
|
||||
}
|
||||
|
||||
@Test(dependsOnMethods = "testListLocationsWhenResponseIs2xx")
|
||||
public void testCreateNodeWhenNetworkNorFirewallExistDoesNotExist() throws RunNodesException, IOException {
|
||||
|
||||
|
||||
String payload = Strings2.toStringAndClose(InstanceApiExpectTest.class.getResourceAsStream("/instance_get.json"));
|
||||
payload = payload.replace("test-0", "test-1");
|
||||
|
||||
HttpResponse getInstanceResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromStringWithContentType(payload, "application/json")).build();
|
||||
|
||||
List<HttpRequest> orderedRequests = ImmutableList.<HttpRequest>builder()
|
||||
.add(requestForScopes(COMPUTE_READONLY_SCOPE))
|
||||
.add(LIST_ZONES_REQ)
|
||||
.add(LIST_PROJECT_IMAGES_REQUEST)
|
||||
.add(LIST_GOOGLE_IMAGES_REQUEST)
|
||||
.add(LIST_MACHINE_TYPES_REQUEST)
|
||||
.add(GET_NETWORK_REQUEST)
|
||||
.add(requestForScopes(COMPUTE_SCOPE))
|
||||
.add(INSERT_NETWORK_REQUEST)
|
||||
.add(GET_OPERATION_REQUEST)
|
||||
.add(GET_NETWORK_REQUEST)
|
||||
.add(GET_FIREWALL_REQUEST)
|
||||
.add(INSERT_FIREWALL_REQUEST)
|
||||
.add(GET_OPERATION_REQUEST)
|
||||
.add(LIST_INSTANCES_REQUEST)
|
||||
.add(LIST_PROJECT_IMAGES_REQUEST)
|
||||
.add(LIST_GOOGLE_IMAGES_REQUEST)
|
||||
.add(LIST_ZONES_REQ)
|
||||
.add(LIST_MACHINE_TYPES_REQUEST)
|
||||
.add(createInstanceRequestForInstance("test-1", "jclouds-test", openSshKey))
|
||||
.add(GET_OPERATION_REQUEST)
|
||||
.add(getInstanceRequestForInstance("test-1"))
|
||||
.add(LIST_PROJECT_IMAGES_REQUEST)
|
||||
.add(LIST_GOOGLE_IMAGES_REQUEST)
|
||||
.add(LIST_ZONES_REQ)
|
||||
.add(LIST_MACHINE_TYPES_REQUEST)
|
||||
.build();
|
||||
|
||||
List<HttpResponse> orderedResponses = ImmutableList.<HttpResponse>builder()
|
||||
.add(TOKEN_RESPONSE)
|
||||
.add(LIST_ZONES_RESPONSE)
|
||||
.add(LIST_PROJECT_IMAGES_RESPONSE)
|
||||
.add(LIST_GOOGLE_IMAGES_RESPONSE)
|
||||
.add(LIST_MACHINE_TYPES_RESPONSE)
|
||||
.add(HttpResponse.builder().statusCode(404).build())
|
||||
.add(TOKEN_RESPONSE)
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(GET_OPERATION_RESPONSE)
|
||||
.add(GET_NETWORK_RESPONSE)
|
||||
.add(HttpResponse.builder().statusCode(404).build())
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(GET_OPERATION_RESPONSE)
|
||||
.add(LIST_INSTANCES_RESPONSE)
|
||||
.add(LIST_PROJECT_IMAGES_RESPONSE)
|
||||
.add(LIST_GOOGLE_IMAGES_RESPONSE)
|
||||
.add(LIST_ZONES_RESPONSE)
|
||||
.add(LIST_MACHINE_TYPES_RESPONSE)
|
||||
.add(SUCESSFULL_OPERATION_RESPONSE)
|
||||
.add(GET_OPERATION_RESPONSE)
|
||||
.add(getInstanceResponse)
|
||||
.add(LIST_PROJECT_IMAGES_RESPONSE)
|
||||
.add(LIST_GOOGLE_IMAGES_RESPONSE)
|
||||
.add(LIST_ZONES_RESPONSE)
|
||||
.add(LIST_MACHINE_TYPES_RESPONSE)
|
||||
.build();
|
||||
|
||||
|
||||
ComputeService computeService = orderedRequestsSendResponses(orderedRequests, orderedResponses);
|
||||
|
||||
GoogleComputeEngineTemplateOptions options = computeService.templateOptions().as(GoogleComputeEngineTemplateOptions.class);
|
||||
|
||||
getOnlyElement(computeService.createNodesInGroup("test", 1, options));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute;
|
||||
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.internal.BaseComputeServiceLiveTest;
|
||||
import org.jclouds.sshj.config.SshjSshClientModule;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "live", singleThreaded = true)
|
||||
public class GoogleComputeEngineServiceLiveTest extends BaseComputeServiceLiveTest {
|
||||
|
||||
public GoogleComputeEngineServiceLiveTest() {
|
||||
provider = "google-compute-engine";
|
||||
}
|
||||
|
||||
/**
|
||||
* Nodes may have additional metadata entries (particularly they may have an "sshKeys" entry)
|
||||
*/
|
||||
protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap<String, String> userMetadata) {
|
||||
assertTrue(node.getUserMetadata().keySet().containsAll(userMetadata.keySet()));
|
||||
}
|
||||
|
||||
// do not run until the auth exception problem is figured out.
|
||||
@Test(enabled = false)
|
||||
@Override
|
||||
public void testCorrectAuthException() throws Exception {
|
||||
}
|
||||
|
||||
// reboot is not supported by GCE
|
||||
@Test(enabled = true, dependsOnMethods = "testGet")
|
||||
public void testReboot() throws Exception {
|
||||
}
|
||||
|
||||
// suspend/Resume is not supported by GCE
|
||||
@Test(enabled = true, dependsOnMethods = "testReboot")
|
||||
public void testSuspendResume() throws Exception {
|
||||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
|
||||
public void testListNodesByIds() throws Exception {
|
||||
super.testGetNodesWithDetails();
|
||||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
|
||||
@Override
|
||||
public void testGetNodesWithDetails() throws Exception {
|
||||
super.testGetNodesWithDetails();
|
||||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = "testSuspendResume")
|
||||
@Override
|
||||
public void testListNodes() throws Exception {
|
||||
super.testListNodes();
|
||||
}
|
||||
|
||||
@Test(enabled = true, dependsOnMethods = { "testListNodes", "testGetNodesWithDetails", "testListNodesByIds" })
|
||||
@Override
|
||||
public void testDestroyNodes() {
|
||||
super.testDestroyNodes();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Module getSshModule() {
|
||||
return new SshjSshClientModule();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute.functions;
|
||||
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.googlecomputeengine.domain.Image;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertSame;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class GoogleComputeEngineImageToImageTest {
|
||||
|
||||
Image.Builder imageBuilder = Image.builder()
|
||||
.id("1234")
|
||||
.selfLink(URI.create("http://test.com"))
|
||||
.sourceType("RAW")
|
||||
.description("")
|
||||
.rawDisk(Image.RawDisk.builder().source("").containerType("TAR").build());
|
||||
|
||||
public void testArbitratyImageName() {
|
||||
GoogleComputeEngineImageToImage imageToImage = new GoogleComputeEngineImageToImage();
|
||||
Image image = imageBuilder.name("arbitratyname").build();
|
||||
org.jclouds.compute.domain.Image transformed = imageToImage.apply(image);
|
||||
assertEquals(transformed.getName(), image.getName());
|
||||
assertEquals(transformed.getId(), image.getName());
|
||||
assertEquals(transformed.getProviderId(), image.getId());
|
||||
assertSame(transformed.getOperatingSystem().getFamily(), OsFamily.LINUX);
|
||||
}
|
||||
|
||||
public void testWellFormedImageName() {
|
||||
GoogleComputeEngineImageToImage imageToImage = new GoogleComputeEngineImageToImage();
|
||||
Image image = imageBuilder.name("ubuntu-12-04-v123123").build();
|
||||
org.jclouds.compute.domain.Image transformed = imageToImage.apply(image);
|
||||
assertEquals(transformed.getName(), image.getName());
|
||||
assertEquals(transformed.getId(), image.getName());
|
||||
assertEquals(transformed.getProviderId(), image.getId());
|
||||
assertSame(transformed.getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||
assertEquals(transformed.getOperatingSystem().getVersion(), "12.04");
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.compute.functions;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.easymock.EasyMock;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.internal.NodeMetadataImpl;
|
||||
import org.jclouds.googlecomputeengine.compute.predicates.AllNodesInGroupTerminated;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.testng.Assert.assertSame;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class OrphanedGroupsFromDeadNodesTest {
|
||||
|
||||
private static class IdAndGroupOnlyNodeMetadata extends NodeMetadataImpl {
|
||||
|
||||
public IdAndGroupOnlyNodeMetadata(String id, String group, Status status) {
|
||||
super(null, null, id, null, null, ImmutableMap.<String, String>of(), ImmutableSet.<String>of(), group, null,
|
||||
null, null, status, null, 0, ImmutableSet.<String>of(), ImmutableSet.<String>of(), null, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDetectsAllOrphanedGroupsWhenAllNodesTerminated() {
|
||||
|
||||
Set<? extends NodeMetadata> deadNodesGroup1 = (Set) ImmutableSet.builder()
|
||||
.add(new IdAndGroupOnlyNodeMetadata("a", "1", NodeMetadata.Status.TERMINATED)).build();
|
||||
|
||||
Set<? extends NodeMetadata> deadNodesGroup2 = (Set) ImmutableSet.builder()
|
||||
.add(new IdAndGroupOnlyNodeMetadata("b", "2", NodeMetadata.Status.TERMINATED)).build();
|
||||
|
||||
Set<? extends NodeMetadata> allDeadNodes = Sets.union(deadNodesGroup1, deadNodesGroup2);
|
||||
|
||||
ComputeService mock = createMock(ComputeService.class);
|
||||
expect(mock.listNodesDetailsMatching(EasyMock.<Predicate<ComputeMetadata>>anyObject()))
|
||||
.andReturn((Set) deadNodesGroup1).once();
|
||||
expect(mock.listNodesDetailsMatching(EasyMock.<Predicate<ComputeMetadata>>anyObject()))
|
||||
.andReturn((Set) deadNodesGroup2).once();
|
||||
|
||||
replay(mock);
|
||||
|
||||
OrphanedGroupsFromDeadNodes orphanedGroupsFromDeadNodes = new OrphanedGroupsFromDeadNodes(new
|
||||
AllNodesInGroupTerminated(mock));
|
||||
|
||||
Set<String> orphanedGroups = orphanedGroupsFromDeadNodes.apply(allDeadNodes);
|
||||
|
||||
assertSame(orphanedGroups.size(), 2);
|
||||
assertTrue(orphanedGroups.contains("1"));
|
||||
assertTrue(orphanedGroups.contains("2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetectsAllOrphanedGroupsWhenSomeNodesTerminatedAndOtherMissing() {
|
||||
|
||||
Set<? extends NodeMetadata> deadNodesGroup1 = (Set) ImmutableSet.builder()
|
||||
.add(new IdAndGroupOnlyNodeMetadata("a", "1", NodeMetadata.Status.TERMINATED)).build();
|
||||
|
||||
Set<? extends NodeMetadata> deadNodesGroup2 = (Set) ImmutableSet.builder()
|
||||
.add(new IdAndGroupOnlyNodeMetadata("b", "2", NodeMetadata.Status.TERMINATED)).build();
|
||||
|
||||
Set<? extends NodeMetadata> allDeadNodes = Sets.union(deadNodesGroup1, deadNodesGroup2);
|
||||
|
||||
ComputeService mock = createMock(ComputeService.class);
|
||||
expect(mock.listNodesDetailsMatching(EasyMock.<Predicate<ComputeMetadata>>anyObject()))
|
||||
.andReturn((Set) deadNodesGroup1).once();
|
||||
expect(mock.listNodesDetailsMatching(EasyMock.<Predicate<ComputeMetadata>>anyObject()))
|
||||
.andReturn((Set) ImmutableSet.of()).once();
|
||||
|
||||
replay(mock);
|
||||
|
||||
OrphanedGroupsFromDeadNodes orphanedGroupsFromDeadNodes = new OrphanedGroupsFromDeadNodes(new
|
||||
AllNodesInGroupTerminated(mock));
|
||||
|
||||
Set<String> orphanedGroups = orphanedGroupsFromDeadNodes.apply(allDeadNodes);
|
||||
|
||||
assertSame(orphanedGroups.size(), 2);
|
||||
assertTrue(orphanedGroups.contains("1"));
|
||||
assertTrue(orphanedGroups.contains("2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDetectsAllOrphanedGroupsWhenSomeNodesAreAlive() {
|
||||
|
||||
Set<? extends NodeMetadata> deadNodesGroup1 = (Set) ImmutableSet.builder()
|
||||
.add(new IdAndGroupOnlyNodeMetadata("a", "1", NodeMetadata.Status.TERMINATED)).build();
|
||||
|
||||
Set<? extends NodeMetadata> deadNodesGroup2 = (Set) ImmutableSet.builder()
|
||||
.add(new IdAndGroupOnlyNodeMetadata("b", "2", NodeMetadata.Status.RUNNING)).build();
|
||||
|
||||
Set<? extends NodeMetadata> allDeadNodes = Sets.union(deadNodesGroup1, deadNodesGroup2);
|
||||
|
||||
ComputeService mock = createMock(ComputeService.class);
|
||||
expect(mock.listNodesDetailsMatching(EasyMock.<Predicate<ComputeMetadata>>anyObject()))
|
||||
.andReturn((Set) deadNodesGroup1).once();
|
||||
expect(mock.listNodesDetailsMatching(EasyMock.<Predicate<ComputeMetadata>>anyObject()))
|
||||
.andReturn((Set) deadNodesGroup2).once();
|
||||
|
||||
replay(mock);
|
||||
|
||||
OrphanedGroupsFromDeadNodes orphanedGroupsFromDeadNodes = new OrphanedGroupsFromDeadNodes(new
|
||||
AllNodesInGroupTerminated(mock));
|
||||
|
||||
Set<String> orphanedGroups = orphanedGroupsFromDeadNodes.apply(allDeadNodes);
|
||||
|
||||
assertSame(orphanedGroups.size(), 1);
|
||||
assertTrue(orphanedGroups.contains("1"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiExpectTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseDiskListTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseDiskTest;
|
||||
import org.jclouds.googlecomputeengine.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.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
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 DiskApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
|
||||
|
||||
public void testGetDiskResponseIs2xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/disks/testimage1")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/disk_get.json")).build();
|
||||
|
||||
DiskApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getDiskApiForProject("myproject");
|
||||
|
||||
assertEquals(api.get("testimage1"),
|
||||
new ParseDiskTest().expected());
|
||||
}
|
||||
|
||||
public void testGetDiskResponseIs4xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/disks/testimage1")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
DiskApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getDiskApiForProject("myproject");
|
||||
|
||||
assertNull(api.get("testimage1"));
|
||||
}
|
||||
|
||||
public void testInsertDiskResponseIs2xx() {
|
||||
HttpRequest insert = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/disks")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromResourceWithContentType("/disk_insert.json", MediaType.APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
HttpResponse insertDiskResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
DiskApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, insert,
|
||||
insertDiskResponse).getDiskApiForProject("myproject");
|
||||
|
||||
assertEquals(api.createInZone("testimage1", 1, URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/zones/us-central1-a"))
|
||||
, new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testDeleteDiskResponseIs2xx() {
|
||||
HttpRequest delete = HttpRequest
|
||||
.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/disks/testimage1")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse deleteResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
DiskApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, delete, deleteResponse).getDiskApiForProject("myproject");
|
||||
|
||||
assertEquals(api.delete("testimage1"),
|
||||
new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testDeleteDiskResponseIs4xx() {
|
||||
HttpRequest delete = HttpRequest
|
||||
.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/disks/testimage1")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse deleteResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
DiskApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, delete, deleteResponse).getDiskApiForProject("myproject");
|
||||
|
||||
assertNull(api.delete("testimage1"));
|
||||
}
|
||||
|
||||
public void testListDisksResponseIs2xx() {
|
||||
HttpRequest list = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/disks")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/disk_list.json")).build();
|
||||
|
||||
DiskApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, list, operationResponse).getDiskApiForProject("myproject");
|
||||
|
||||
assertEquals(api.listFirstPage().toString(),
|
||||
new ParseDiskListTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testListDisksResponseIs4xx() {
|
||||
HttpRequest list = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/disks")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
DiskApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, list, operationResponse).getDiskApiForProject("myproject");
|
||||
|
||||
assertTrue(api.list().concat().isEmpty());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.Disk;
|
||||
import org.jclouds.googlecomputeengine.domain.Project;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
|
||||
import org.jclouds.googlecomputeengine.options.ListOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class DiskApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
|
||||
|
||||
private static final String DISK_NAME = "disk-api-live-test-disk";
|
||||
private static final int TIME_WAIT = 10;
|
||||
|
||||
private URI zoneUrl;
|
||||
private int sizeGb = 1;
|
||||
|
||||
private DiskApi api() {
|
||||
return api.getDiskApiForProject(userProject.get());
|
||||
}
|
||||
|
||||
@Test(groups = "live")
|
||||
public void testInsertDisk() {
|
||||
Project project = api.getProjectApi().get(userProject.get());
|
||||
zoneUrl = getDefaultZoneUrl(project.getName());
|
||||
assertOperationDoneSucessfully(api().createInZone(DISK_NAME, sizeGb, zoneUrl), TIME_WAIT);
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testInsertDisk")
|
||||
public void testGetDisk() {
|
||||
|
||||
Disk disk = api().get(DISK_NAME);
|
||||
assertNotNull(disk);
|
||||
assertDiskEquals(disk);
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testGetDisk")
|
||||
public void testListDisk() {
|
||||
|
||||
PagedIterable<Disk> disks = api().list(new ListOptions.Builder()
|
||||
.filter("name eq " + DISK_NAME));
|
||||
|
||||
List<Disk> disksAsList = Lists.newArrayList(disks.concat());
|
||||
|
||||
assertEquals(disksAsList.size(), 1);
|
||||
|
||||
assertDiskEquals(Iterables.getOnlyElement(disksAsList));
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testListDisk")
|
||||
public void testDeleteDisk() {
|
||||
|
||||
assertOperationDoneSucessfully(api().delete(DISK_NAME), TIME_WAIT);
|
||||
}
|
||||
|
||||
private void assertDiskEquals(Disk result) {
|
||||
assertEquals(result.getName(), DISK_NAME);
|
||||
assertEquals(result.getSizeGb(), sizeGb);
|
||||
assertEquals(result.getZone(), zoneUrl);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jclouds.googlecomputeengine.domain.Firewall;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiExpectTest;
|
||||
import org.jclouds.googlecomputeengine.options.FirewallOptions;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseFirewallListTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseFirewallTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseOperationTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.google.common.base.Joiner.on;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static java.lang.String.format;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.domain.Firewall.Rule.IPProtocol;
|
||||
import static org.jclouds.io.Payloads.newStringPayload;
|
||||
import static org.jclouds.util.Strings2.toStringAndClose;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
import static org.testng.AssertJUnit.assertNull;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class FirewallApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
|
||||
|
||||
public static final HttpRequest GET_FIREWALL_REQUEST = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/firewalls/jclouds-test")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
public static HttpResponse GET_FIREWALL_RESPONSE = HttpResponse.builder().statusCode(200)
|
||||
.payload(staticPayloadFromResource("/firewall_get.json")).build();
|
||||
|
||||
public void testGetFirewallResponseIs2xx() throws Exception {
|
||||
|
||||
FirewallApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, GET_FIREWALL_REQUEST, GET_FIREWALL_RESPONSE).getFirewallApiForProject("myproject");
|
||||
|
||||
assertEquals(api.get("jclouds-test"), new ParseFirewallTest().expected());
|
||||
}
|
||||
|
||||
|
||||
public static Payload firewallPayloadFirewallOfName(String firewallName,
|
||||
String networkName,
|
||||
Set<String> sourceRanges,
|
||||
Set<String> sourceTags,
|
||||
Set<String> targetTags,
|
||||
Set<String> portRanges) throws IOException {
|
||||
Function<String, String> addQuotes = new Function<String, String>() {
|
||||
@Override
|
||||
public String apply(String input) {
|
||||
return "\"" + input + "\"";
|
||||
}
|
||||
};
|
||||
|
||||
String ports = on(",").skipNulls().join(transform(portRanges, addQuotes));
|
||||
|
||||
Payload payload = newStringPayload(
|
||||
format(toStringAndClose(FirewallApiExpectTest.class.getResourceAsStream("/firewall_insert.json")),
|
||||
firewallName,
|
||||
networkName,
|
||||
on(",").skipNulls().join(transform(sourceRanges, addQuotes)),
|
||||
on(",").skipNulls().join(transform(sourceTags, addQuotes)),
|
||||
on(",").skipNulls().join(transform(targetTags, addQuotes)),
|
||||
ports,
|
||||
ports));
|
||||
payload.getContentMetadata().setContentType(MediaType.APPLICATION_JSON);
|
||||
return payload;
|
||||
}
|
||||
|
||||
|
||||
public void testGetFirewallResponseIs4xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/firewalls/jclouds-test")
|
||||
.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("myproject");
|
||||
|
||||
assertNull(api.get("jclouds-test"));
|
||||
}
|
||||
|
||||
public void testInsertFirewallResponseIs2xx() throws IOException {
|
||||
|
||||
HttpRequest request = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/firewalls")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(firewallPayloadFirewallOfName(
|
||||
"myfw",
|
||||
"default",
|
||||
ImmutableSet.<String>of("10.0.1.0/32"),
|
||||
ImmutableSet.<String>of("tag1"),
|
||||
ImmutableSet.<String>of("tag2"),
|
||||
ImmutableSet.<String>of("22", "23-24")))
|
||||
.build();
|
||||
|
||||
HttpResponse insertFirewallResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
FirewallApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, request, insertFirewallResponse).getFirewallApiForProject("myproject");
|
||||
|
||||
assertEquals(api.createInNetwork("myfw", URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/networks/default"),
|
||||
new FirewallOptions()
|
||||
.addAllowedRule(Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(22)
|
||||
.addPortRange(23, 24).build())
|
||||
.addSourceTag("tag1")
|
||||
.addSourceRange("10.0.1.0/32")
|
||||
.addTargetTag("tag2")), new ParseOperationTest().expected());
|
||||
|
||||
}
|
||||
|
||||
public void testUpdateFirewallResponseIs2xx() throws IOException {
|
||||
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(firewallPayloadFirewallOfName(
|
||||
"myfw",
|
||||
"default",
|
||||
ImmutableSet.<String>of("10.0.1.0/32"),
|
||||
ImmutableSet.<String>of("tag1"),
|
||||
ImmutableSet.<String>of("tag2"),
|
||||
ImmutableSet.<String>of("22", "23-24")))
|
||||
.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",
|
||||
new FirewallOptions()
|
||||
.name("myfw")
|
||||
.network(URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/networks/default"))
|
||||
.addAllowedRule(Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(22)
|
||||
.addPortRange(23, 24).build())
|
||||
.addSourceTag("tag1")
|
||||
.addSourceRange("10.0.1.0/32")
|
||||
.addTargetTag("tag2")), new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testPatchFirewallResponseIs2xx() throws IOException {
|
||||
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(firewallPayloadFirewallOfName(
|
||||
"myfw",
|
||||
"default",
|
||||
ImmutableSet.<String>of("10.0.1.0/32"),
|
||||
ImmutableSet.<String>of("tag1"),
|
||||
ImmutableSet.<String>of("tag2"),
|
||||
ImmutableSet.<String>of("22", "23-24")))
|
||||
.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",
|
||||
new FirewallOptions()
|
||||
.name("myfw")
|
||||
.network(URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/networks/default"))
|
||||
.addAllowedRule(Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(22)
|
||||
.addPortRange(23, 24).build())
|
||||
.addSourceTag("tag1")
|
||||
.addSourceRange("10.0.1.0/32")
|
||||
.addTargetTag("tag2")), 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,168 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.Firewall;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
|
||||
import org.jclouds.googlecomputeengine.options.FirewallOptions;
|
||||
import org.jclouds.googlecomputeengine.options.ListOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||
import static org.jclouds.googlecomputeengine.domain.Firewall.Rule.IPProtocol;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class FirewallApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
|
||||
|
||||
private static final String FIREWALL_NAME = "firewall-api-live-test-firewall";
|
||||
private static final String FIREWALL_NETWORK_NAME = "firewall-api-live-test-network";
|
||||
private static final String IPV4_RANGE = "10.0.0.0/8";
|
||||
private static final int TIME_WAIT = 30;
|
||||
|
||||
private FirewallApi api() {
|
||||
return api.getFirewallApiForProject(userProject.get());
|
||||
}
|
||||
|
||||
@Test(groups = "live")
|
||||
public void testInsertFirewall() {
|
||||
|
||||
// need to create the network first
|
||||
assertOperationDoneSucessfully(api.getNetworkApiForProject(userProject.get()).createInIPv4Range
|
||||
(FIREWALL_NETWORK_NAME, IPV4_RANGE), TIME_WAIT);
|
||||
|
||||
FirewallOptions firewall = new FirewallOptions()
|
||||
.addAllowedRule(
|
||||
Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(22).build())
|
||||
.addSourceRange("10.0.0.0/8")
|
||||
.addSourceTag("tag1")
|
||||
.addTargetTag("tag2");
|
||||
|
||||
assertOperationDoneSucessfully(api().createInNetwork(FIREWALL_NAME, getNetworkUrl(userProject.get(),
|
||||
FIREWALL_NETWORK_NAME), firewall), TIME_WAIT);
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testInsertFirewall")
|
||||
public void testUpdateFirewall() {
|
||||
|
||||
FirewallOptions firewall = new FirewallOptions()
|
||||
.name(FIREWALL_NAME)
|
||||
.network(getNetworkUrl(userProject.get(),FIREWALL_NETWORK_NAME))
|
||||
.addSourceRange("10.0.0.0/8")
|
||||
.addSourceTag("tag1")
|
||||
.addTargetTag("tag2")
|
||||
.allowedRules(ImmutableSet.of(
|
||||
Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(23)
|
||||
.build()));
|
||||
|
||||
|
||||
assertOperationDoneSucessfully(api().update(FIREWALL_NAME, firewall), TIME_WAIT);
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testUpdateFirewall")
|
||||
public void testPatchFirewall() {
|
||||
|
||||
FirewallOptions firewall = new FirewallOptions()
|
||||
.name(FIREWALL_NAME)
|
||||
.network(getNetworkUrl(userProject.get(),FIREWALL_NETWORK_NAME))
|
||||
.allowedRules(ImmutableSet.of(
|
||||
Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(22)
|
||||
.build(),
|
||||
Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(23)
|
||||
.build()))
|
||||
.addSourceRange("10.0.0.0/8")
|
||||
.addSourceTag("tag1")
|
||||
.addTargetTag("tag2");
|
||||
|
||||
assertOperationDoneSucessfully(api().update(FIREWALL_NAME, firewall), TIME_WAIT);
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testPatchFirewall")
|
||||
public void testGetFirewall() {
|
||||
|
||||
FirewallOptions patchedFirewall = new FirewallOptions()
|
||||
.name(FIREWALL_NAME)
|
||||
.network(getNetworkUrl(userProject.get(), FIREWALL_NETWORK_NAME))
|
||||
.allowedRules(ImmutableSet.of(
|
||||
Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(22)
|
||||
.build(),
|
||||
Firewall.Rule.builder()
|
||||
.IPProtocol(IPProtocol.TCP)
|
||||
.addPort(23)
|
||||
.build()))
|
||||
.addSourceRange("10.0.0.0/8")
|
||||
.addSourceTag("tag1")
|
||||
.addTargetTag("tag2");
|
||||
|
||||
Firewall firewall = api().get(FIREWALL_NAME);
|
||||
assertNotNull(firewall);
|
||||
assertFirewallEquals(firewall, patchedFirewall);
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testListFirewall")
|
||||
public void testDeleteFirewall() {
|
||||
|
||||
assertOperationDoneSucessfully(api().delete(FIREWALL_NAME), TIME_WAIT);
|
||||
assertOperationDoneSucessfully(api.getNetworkApiForProject(userProject.get()).delete
|
||||
(FIREWALL_NETWORK_NAME), TIME_WAIT);
|
||||
}
|
||||
|
||||
private void assertFirewallEquals(Firewall result, FirewallOptions 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,144 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiExpectTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseImageListTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseImageTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseOperationTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
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 ImageApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
|
||||
|
||||
public static final HttpRequest LIST_PROJECT_IMAGES_REQUEST = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/images")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
public static final HttpResponse LIST_PROJECT_IMAGES_RESPONSE = HttpResponse.builder().statusCode(200)
|
||||
.payload(staticPayloadFromResource("/image_list.json")).build();
|
||||
|
||||
public void testGetImageResponseIs2xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/google/images/centos-6-2-v20120326")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/image_get.json")).build();
|
||||
|
||||
ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getImageApiForProject("google");
|
||||
|
||||
assertEquals(imageApi.get("centos-6-2-v20120326"),
|
||||
new ParseImageTest().expected());
|
||||
}
|
||||
|
||||
public void testGetImageResponseIs4xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/google/images/centos-6-2-v20120326")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getImageApiForProject("google");
|
||||
|
||||
assertNull(imageApi.get("centos-6-2-v20120326"));
|
||||
}
|
||||
|
||||
public void testDeleteImageResponseIs2xx() {
|
||||
HttpRequest delete = HttpRequest
|
||||
.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/images/centos-6-2-v20120326")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse deleteResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, delete, deleteResponse).getImageApiForProject("myproject");
|
||||
|
||||
assertEquals(imageApi.delete("centos-6-2-v20120326"),
|
||||
new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testDeleteImageResponseIs4xx() {
|
||||
HttpRequest delete = HttpRequest
|
||||
.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/images/centos-6-2-v20120326")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse deleteResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, delete, deleteResponse).getImageApiForProject("myproject");
|
||||
|
||||
assertNull(imageApi.delete("centos-6-2-v20120326"));
|
||||
}
|
||||
|
||||
public void testListImagesResponseIs2xx() {
|
||||
|
||||
ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, LIST_PROJECT_IMAGES_REQUEST, LIST_PROJECT_IMAGES_RESPONSE).getImageApiForProject
|
||||
("myproject");
|
||||
|
||||
assertEquals(imageApi.listFirstPage().toString(),
|
||||
new ParseImageListTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testListImagesResponseIs4xx() {
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
ImageApi imageApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, LIST_PROJECT_IMAGES_REQUEST, operationResponse).getImageApiForProject("myproject");
|
||||
|
||||
assertTrue(imageApi.list().concat().isEmpty());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.Image;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
|
||||
import org.jclouds.googlecomputeengine.options.ListOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertSame;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* TODO figure out how to test insert and delete as this requires an image .tar.gz to be present in GCS
|
||||
*
|
||||
* @author David Alves
|
||||
*/
|
||||
public class ImageApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
|
||||
|
||||
private Image image;
|
||||
|
||||
private ImageApi api() {
|
||||
return api.getImageApiForProject("google");
|
||||
}
|
||||
|
||||
@Test(groups = "live")
|
||||
public void testListImage() {
|
||||
|
||||
PagedIterable<Image> images = api().list(new ListOptions.Builder().maxResults(1));
|
||||
|
||||
Iterator<IterableWithMarker<Image>> pageIterator = images.iterator();
|
||||
assertTrue(pageIterator.hasNext());
|
||||
|
||||
IterableWithMarker<Image> singlePageIterator = pageIterator.next();
|
||||
List<Image> imageAsList = Lists.newArrayList(singlePageIterator);
|
||||
|
||||
assertSame(imageAsList.size(), 1);
|
||||
|
||||
this.image = Iterables.getOnlyElement(imageAsList);
|
||||
}
|
||||
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testListImage")
|
||||
public void testGetImage() {
|
||||
Image image = api().get(this.image.getName());
|
||||
assertNotNull(image);
|
||||
assertImageEquals(image, this.image);
|
||||
}
|
||||
|
||||
private void assertImageEquals(Image result, Image expected) {
|
||||
assertEquals(result.getName(), expected.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,230 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import org.jclouds.googlecomputeengine.domain.Instance;
|
||||
import org.jclouds.googlecomputeengine.domain.InstanceTemplate;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiExpectTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseInstanceListTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseInstanceSerialOutputTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseInstanceTest;
|
||||
import org.jclouds.googlecomputeengine.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 java.net.URI.create;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
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 InstanceApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
|
||||
|
||||
public static final HttpRequest GET_INSTANCE_REQUEST = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances/test-1")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
|
||||
public static final HttpResponse GET_INSTANCE_RESPONSE = HttpResponse.builder().statusCode(200)
|
||||
.payload(staticPayloadFromResource("/instance_get.json")).build();
|
||||
|
||||
public static final HttpRequest LIST_INSTANCES_REQUEST = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
public static final HttpResponse LIST_INSTANCES_RESPONSE = HttpResponse.builder().statusCode(200)
|
||||
.payload(staticPayloadFromResource("/instance_list.json")).build();
|
||||
|
||||
public static final HttpResponse CREATE_INSTANCE_RESPONSE = HttpResponse.builder().statusCode(200)
|
||||
.payload(staticPayloadFromResource("/operation.json")).build();
|
||||
|
||||
|
||||
public void testGetInstanceResponseIs2xx() throws Exception {
|
||||
|
||||
InstanceApi api = requestsSendResponses(
|
||||
requestForScopes(COMPUTE_READONLY_SCOPE), TOKEN_RESPONSE,
|
||||
GET_INSTANCE_REQUEST, GET_INSTANCE_RESPONSE).getInstanceApiForProject("myproject");
|
||||
|
||||
assertEquals(api.get("test-1"), new ParseInstanceTest().expected());
|
||||
}
|
||||
|
||||
public void testGetInstanceResponseIs4xx() throws Exception {
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, GET_INSTANCE_REQUEST, operationResponse).getInstanceApiForProject("myproject");
|
||||
|
||||
assertNull(api.get("test-1"));
|
||||
}
|
||||
|
||||
public void testGetInstanceSerialPortOutput() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances/test-1/serialPort")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/instance_serial_port.json")).build();
|
||||
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getInstanceApiForProject("myproject");
|
||||
|
||||
assertEquals(api.getSerialPortOutput("test-1"), new ParseInstanceSerialOutputTest().expected());
|
||||
}
|
||||
|
||||
public void testInsertInstanceResponseIs2xxNoOptions() {
|
||||
HttpRequest insert = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/instances")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromResourceWithContentType("/instance_insert_simple.json", MediaType.APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, insert,
|
||||
CREATE_INSTANCE_RESPONSE).getInstanceApiForProject("myproject");
|
||||
|
||||
InstanceTemplate options = InstanceTemplate.builder().forMachineType("n1-standard-1")
|
||||
.addNetworkInterface(URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/networks/default"));
|
||||
|
||||
assertEquals(api.createInZone("test-1", options, "us-central1-a"), new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testInsertInstanceResponseIs2xxAllOptions() {
|
||||
HttpRequest insert = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/instances")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromResourceWithContentType("/instance_insert.json", MediaType.APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
HttpResponse insertInstanceResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, insert, insertInstanceResponse).getInstanceApiForProject("myproject");
|
||||
|
||||
InstanceTemplate options = InstanceTemplate.builder().forMachineType("n1-standard-1")
|
||||
.addNetworkInterface(URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/networks/default"), Instance.NetworkInterface.AccessConfig.Type.ONE_TO_ONE_NAT)
|
||||
.description("desc")
|
||||
.image(URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/google/images/gcel-12-04-v20121106"))
|
||||
.addDisk(InstanceTemplate.PersistentDisk.Mode.READ_WRITE,
|
||||
create("https://www.googleapis.com/compute/v1beta13/projects/myproject/disks/test"))
|
||||
.addTag("aTag")
|
||||
.addServiceAccount(Instance.ServiceAccount.builder().email("default").addScopes("myscope").build())
|
||||
.addMetadata("aKey", "aValue");
|
||||
|
||||
assertEquals(api.createInZone("test-0", options, "us-central1-a"),
|
||||
new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testDeleteInstanceResponseIs2xx() {
|
||||
HttpRequest delete = HttpRequest
|
||||
.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances/test-1")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse deleteResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, delete, deleteResponse).getInstanceApiForProject("myproject");
|
||||
|
||||
assertEquals(api.delete("test-1"),
|
||||
new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testDeleteInstanceResponseIs4xx() {
|
||||
HttpRequest delete = HttpRequest
|
||||
.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances/test-1")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse deleteResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, delete, deleteResponse).getInstanceApiForProject("myproject");
|
||||
|
||||
assertNull(api.delete("test-1"));
|
||||
}
|
||||
|
||||
public void testListInstancesResponseIs2xx() {
|
||||
|
||||
InstanceApi api = requestsSendResponses(
|
||||
requestForScopes(COMPUTE_READONLY_SCOPE), TOKEN_RESPONSE,
|
||||
LIST_INSTANCES_REQUEST, LIST_INSTANCES_RESPONSE).getInstanceApiForProject("myproject");
|
||||
|
||||
assertEquals(api.listFirstPage().toString(),
|
||||
new ParseInstanceListTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testListInstancesResponseIs4xx() {
|
||||
HttpRequest list = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/instances")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
InstanceApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, list, operationResponse).getInstanceApiForProject("myproject");
|
||||
|
||||
assertTrue(api.list().concat().isEmpty());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.domain.Instance;
|
||||
import org.jclouds.googlecomputeengine.domain.InstanceTemplate;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
|
||||
import org.jclouds.googlecomputeengine.options.ListOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class InstanceApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
|
||||
|
||||
private static final String INSTANCE_NETWORK_NAME = "instance-api-live-test-network";
|
||||
private static final String INSTANCE_NAME = "instance-api-live-test-instance";
|
||||
private static final String DISK_NAME = "instance-live-test-disk";
|
||||
private static final String IPV4_RANGE = "10.0.0.0/8";
|
||||
private static final int TIME_WAIT = 600;
|
||||
|
||||
private InstanceTemplate instance;
|
||||
|
||||
@Override
|
||||
protected GoogleComputeEngineApi create(Properties props, Iterable<Module> modules) {
|
||||
GoogleComputeEngineApi api = super.create(props, modules);
|
||||
instance = InstanceTemplate.builder()
|
||||
.forMachineType(getDefaultMachineTypekUrl(userProject.get()))
|
||||
.addNetworkInterface(getNetworkUrl(userProject.get(), INSTANCE_NETWORK_NAME),
|
||||
Instance.NetworkInterface.AccessConfig.Type.ONE_TO_ONE_NAT)
|
||||
.addMetadata("mykey", "myvalue")
|
||||
.addTag("atag")
|
||||
.description("a description")
|
||||
.addDisk(InstanceTemplate.PersistentDisk.Mode.READ_WRITE, getDiskUrl(userProject.get(), DISK_NAME))
|
||||
.zone(getDefaultZoneUrl(userProject.get()));
|
||||
return api;
|
||||
}
|
||||
|
||||
private InstanceApi api() {
|
||||
return api.getInstanceApiForProject(userProject.get());
|
||||
}
|
||||
|
||||
@Test(groups = "live")
|
||||
public void testInsertInstance() {
|
||||
|
||||
// need to create the network first
|
||||
assertOperationDoneSucessfully(api.getNetworkApiForProject(userProject.get()).createInIPv4Range
|
||||
(INSTANCE_NETWORK_NAME, IPV4_RANGE), TIME_WAIT);
|
||||
|
||||
assertOperationDoneSucessfully(api.getDiskApiForProject(userProject.get()).createInZone
|
||||
("instance-live-test-disk", 1, getDefaultZoneUrl(userProject.get())), TIME_WAIT);
|
||||
|
||||
assertOperationDoneSucessfully(api().createInZone(INSTANCE_NAME, instance, DEFAULT_ZONE_NAME), TIME_WAIT);
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testInsertInstance")
|
||||
public void testGetInstance() {
|
||||
|
||||
Instance instance = api().get(INSTANCE_NAME);
|
||||
assertNotNull(instance);
|
||||
assertInstanceEquals(instance, this.instance);
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testInsertInstance")
|
||||
public void testListInstance() {
|
||||
|
||||
PagedIterable<Instance> instances = api().list(new ListOptions.Builder()
|
||||
.filter("name eq " + INSTANCE_NAME));
|
||||
|
||||
List<Instance> instancesAsList = Lists.newArrayList(instances.concat());
|
||||
|
||||
assertEquals(instancesAsList.size(), 1);
|
||||
|
||||
assertInstanceEquals(Iterables.getOnlyElement(instancesAsList), instance);
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testListInstance")
|
||||
public void testDeleteInstance() {
|
||||
|
||||
assertOperationDoneSucessfully(api().delete(INSTANCE_NAME), TIME_WAIT);
|
||||
assertOperationDoneSucessfully(api.getDiskApiForProject(userProject.get()).delete(DISK_NAME),
|
||||
TIME_WAIT);
|
||||
assertOperationDoneSucessfully(api.getNetworkApiForProject(userProject.get()).delete
|
||||
(INSTANCE_NETWORK_NAME), TIME_WAIT);
|
||||
}
|
||||
|
||||
private void assertInstanceEquals(Instance result, InstanceTemplate expected) {
|
||||
assertEquals(result.getName(), expected.getName());
|
||||
assertEquals(result.getTags(), expected.getTags());
|
||||
assertEquals(result.getMetadata(), expected.getMetadata());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiExpectTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseKernelListTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseKernelTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class KernelApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
|
||||
|
||||
public void testGetKernelResponseIs2xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/kernels/12941177846308850718")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/kernel.json")).build();
|
||||
|
||||
KernelApi kernelApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getKernelApiForProject("myproject");
|
||||
|
||||
assertEquals(kernelApi.get("12941177846308850718"),
|
||||
new ParseKernelTest().expected());
|
||||
}
|
||||
|
||||
public void testGetKernelResponseIs4xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/kernels/12941177846308850718")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
KernelApi kernelApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getKernelApiForProject("myproject");
|
||||
|
||||
assertNull(kernelApi.get("12941177846308850718"));
|
||||
}
|
||||
|
||||
public void testListKernelNoOptionsResponseIs2xx() throws Exception {
|
||||
HttpRequest list = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/kernels")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/kernel_list.json")).build();
|
||||
|
||||
KernelApi kernelApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, list, operationResponse).getKernelApiForProject("myproject");
|
||||
|
||||
assertEquals(kernelApi.listFirstPage().toString(),
|
||||
new ParseKernelListTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testListKernelsResponseIs4xx() {
|
||||
HttpRequest list = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/kernels")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
KernelApi kernelApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, list, operationResponse).getKernelApiForProject("myproject");
|
||||
|
||||
assertTrue(kernelApi.list().concat().isEmpty());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.Kernel;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
|
||||
import org.jclouds.googlecomputeengine.options.ListOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertSame;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class KernelApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
|
||||
|
||||
private Kernel kernel;
|
||||
|
||||
private KernelApi api() {
|
||||
return api.getKernelApiForProject("google");
|
||||
}
|
||||
|
||||
@Test(groups = "live")
|
||||
public void testListKernel() {
|
||||
|
||||
PagedIterable<Kernel> kernels = api().list(new ListOptions.Builder()
|
||||
.maxResults(1));
|
||||
|
||||
Iterator<IterableWithMarker<Kernel>> pageIterator = kernels.iterator();
|
||||
assertTrue(pageIterator.hasNext());
|
||||
|
||||
IterableWithMarker<Kernel> singlePageIterator = pageIterator.next();
|
||||
List<Kernel> kernelAsList = Lists.newArrayList(singlePageIterator);
|
||||
|
||||
assertSame(kernelAsList.size(), 1);
|
||||
|
||||
this.kernel = Iterables.getOnlyElement(kernelAsList);
|
||||
}
|
||||
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testListKernel")
|
||||
public void testGetKernel() {
|
||||
Kernel kernel = api().get(this.kernel.getName());
|
||||
assertNotNull(kernel);
|
||||
assertKernelEquals(kernel, this.kernel);
|
||||
}
|
||||
|
||||
private void assertKernelEquals(Kernel result, Kernel expected) {
|
||||
assertEquals(result.getName(), expected.getName());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiExpectTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseMachineTypeListTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseMachineTypeTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class MachineTypeApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
|
||||
|
||||
public static final HttpRequest LIST_MACHINE_TYPES_REQUEST = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/machineTypes")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
public static final HttpResponse LIST_MACHINE_TYPES_RESPONSE = HttpResponse.builder()
|
||||
.statusCode(200)
|
||||
.payload(staticPayloadFromResource("/machinetype_list.json"))
|
||||
.build();
|
||||
|
||||
public void testGetMachineTypeResponseIs2xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/machineTypes/n1-standard-1")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/machinetype.json")).build();
|
||||
|
||||
MachineTypeApi machineTypeApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getMachineTypeApiForProject("myproject");
|
||||
|
||||
assertEquals(machineTypeApi.get("n1-standard-1"),
|
||||
new ParseMachineTypeTest().expected());
|
||||
}
|
||||
|
||||
public void testGetMachineTypeResponseIs4xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/machineTypes/n1-standard-1")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
MachineTypeApi machineTypeApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getMachineTypeApiForProject("myproject");
|
||||
|
||||
assertNull(machineTypeApi.get("n1-standard-1"));
|
||||
}
|
||||
|
||||
public void testListMachineTypeNoOptionsResponseIs2xx() throws Exception {
|
||||
|
||||
MachineTypeApi machineTypeApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, LIST_MACHINE_TYPES_REQUEST, LIST_MACHINE_TYPES_RESPONSE).getMachineTypeApiForProject
|
||||
("myproject");
|
||||
|
||||
assertEquals(machineTypeApi.listFirstPage().toString(),
|
||||
new ParseMachineTypeListTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testLisOperationWithPaginationOptionsResponseIs4xx() {
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
MachineTypeApi machineTypeApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, LIST_MACHINE_TYPES_REQUEST, operationResponse).getMachineTypeApiForProject("myproject");
|
||||
|
||||
assertTrue(machineTypeApi.list().concat().isEmpty());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.MachineType;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
|
||||
import org.jclouds.googlecomputeengine.options.ListOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertSame;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class MachineTypeApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
|
||||
|
||||
private MachineType machineType;
|
||||
|
||||
private MachineTypeApi api() {
|
||||
return api.getMachineTypeApiForProject(userProject.get());
|
||||
}
|
||||
|
||||
@Test(groups = "live")
|
||||
public void testListMachineType() {
|
||||
|
||||
PagedIterable<MachineType> machineTypes = api().list(new ListOptions.Builder()
|
||||
.maxResults(1));
|
||||
|
||||
Iterator<IterableWithMarker<MachineType>> pageIterator = machineTypes.iterator();
|
||||
assertTrue(pageIterator.hasNext());
|
||||
|
||||
IterableWithMarker<MachineType> singlePageIterator = pageIterator.next();
|
||||
List<MachineType> machineTypeAsList = Lists.newArrayList(singlePageIterator);
|
||||
|
||||
assertSame(machineTypeAsList.size(), 1);
|
||||
|
||||
this.machineType = Iterables.getOnlyElement(machineTypeAsList);
|
||||
}
|
||||
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testListMachineType")
|
||||
public void testGetMachineType() {
|
||||
MachineType machineType = api().get(this.machineType.getName());
|
||||
assertNotNull(machineType);
|
||||
assertMachineTypeEquals(machineType, this.machineType);
|
||||
}
|
||||
|
||||
private void assertMachineTypeEquals(MachineType result, MachineType expected) {
|
||||
assertEquals(result.getName(), expected.getName());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiExpectTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseNetworkListTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseNetworkTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseOperationTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
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 NetworkApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
|
||||
|
||||
public static final HttpRequest GET_NETWORK_REQUEST = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/networks/jclouds-test")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
public static final HttpResponse GET_NETWORK_RESPONSE = HttpResponse.builder().statusCode(200)
|
||||
.payload(staticPayloadFromResource("/network_get.json")).build();
|
||||
|
||||
public void testGetNetworkResponseIs2xx() throws Exception {
|
||||
|
||||
NetworkApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, GET_NETWORK_REQUEST, GET_NETWORK_RESPONSE).getNetworkApiForProject("myproject");
|
||||
|
||||
assertEquals(api.get("jclouds-test"),
|
||||
new ParseNetworkTest().expected());
|
||||
}
|
||||
|
||||
public void testGetNetworkResponseIs4xx() throws Exception {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/networks/jclouds-test")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
NetworkApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getNetworkApiForProject("myproject");
|
||||
|
||||
assertNull(api.get("jclouds-test"));
|
||||
}
|
||||
|
||||
public void testInsertNetworkResponseIs2xx() {
|
||||
HttpRequest insert = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint("https://www.googleapis.com/compute/v1beta13/projects/myproject/networks")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromResourceWithContentType("/network_insert.json", MediaType.APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
HttpResponse insertNetworkResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
NetworkApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, insert,
|
||||
insertNetworkResponse).getNetworkApiForProject("myproject");
|
||||
|
||||
assertEquals(api.createInIPv4Range("test-network", "10.0.0.0/8"), new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testDeleteNetworkResponseIs2xx() {
|
||||
HttpRequest delete = HttpRequest
|
||||
.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/networks/jclouds-test")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse deleteResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
NetworkApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, delete, deleteResponse).getNetworkApiForProject("myproject");
|
||||
|
||||
assertEquals(api.delete("jclouds-test"),
|
||||
new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testDeleteNetworkResponseIs4xx() {
|
||||
HttpRequest delete = HttpRequest
|
||||
.builder()
|
||||
.method("DELETE")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/networks/jclouds-test")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse deleteResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
NetworkApi api = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, delete, deleteResponse).getNetworkApiForProject("myproject");
|
||||
|
||||
assertNull(api.delete("jclouds-test"));
|
||||
}
|
||||
|
||||
public void testListNetworksResponseIs2xx() {
|
||||
HttpRequest list = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/networks")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/network_list.json")).build();
|
||||
|
||||
NetworkApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, list, operationResponse).getNetworkApiForProject("myproject");
|
||||
|
||||
assertEquals(api.listFirstPage().toString(),
|
||||
new ParseNetworkListTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testListNetworksResponseIs4xx() {
|
||||
HttpRequest list = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/networks")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
NetworkApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, list, operationResponse).getNetworkApiForProject("myproject");
|
||||
|
||||
assertTrue(api.list().concat().isEmpty());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.Network;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
|
||||
import org.jclouds.googlecomputeengine.options.ListOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class NetworkApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
|
||||
|
||||
private static final String NETWORK_NAME = "network-api-live-test-network";
|
||||
private static final String IPV4_RANGE = "10.0.0.0/8";
|
||||
private static final int TIME_WAIT = 10;
|
||||
|
||||
private NetworkApi api() {
|
||||
return api.getNetworkApiForProject(userProject.get());
|
||||
}
|
||||
|
||||
@Test(groups = "live")
|
||||
public void testInsertNetwork() {
|
||||
|
||||
assertOperationDoneSucessfully(api().createInIPv4Range(NETWORK_NAME, IPV4_RANGE), TIME_WAIT);
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testInsertNetwork")
|
||||
public void testGetNetwork() {
|
||||
|
||||
Network network = api().get(NETWORK_NAME);
|
||||
assertNotNull(network);
|
||||
assertNetworkEquals(network);
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testGetNetwork")
|
||||
public void testListNetwork() {
|
||||
|
||||
PagedIterable<Network> networks = api().list(new ListOptions.Builder()
|
||||
.filter("name eq " + NETWORK_NAME));
|
||||
|
||||
List<Network> networksAsList = Lists.newArrayList(networks.concat());
|
||||
|
||||
assertEquals(networksAsList.size(), 1);
|
||||
|
||||
assertNetworkEquals(Iterables.getOnlyElement(networksAsList));
|
||||
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testListNetwork")
|
||||
public void testDeleteNetwork() {
|
||||
|
||||
assertOperationDoneSucessfully(api().delete(NETWORK_NAME), TIME_WAIT);
|
||||
}
|
||||
|
||||
private void assertNetworkEquals(Network result) {
|
||||
assertEquals(result.getName(), NETWORK_NAME);
|
||||
assertEquals(result.getIPv4Range(), IPV4_RANGE);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiExpectTest;
|
||||
import org.jclouds.googlecomputeengine.options.ListOptions;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseOperationListTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseOperationTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_SCOPE;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class OperationApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
|
||||
|
||||
private static final String OPERATIONS_URL_PREFIX = "https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/operations";
|
||||
|
||||
public static final HttpRequest GET_OPERATION_REQUEST = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(OPERATIONS_URL_PREFIX + "/operation-1354084865060-4cf88735faeb8-bbbb12cb")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
public static final HttpResponse GET_OPERATION_RESPONSE = HttpResponse.builder().statusCode(200)
|
||||
.payload(staticPayloadFromResource("/operation.json")).build();
|
||||
|
||||
public void testGetOperationResponseIs2xx() throws Exception {
|
||||
|
||||
OperationApi operationApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, GET_OPERATION_REQUEST, GET_OPERATION_RESPONSE).getOperationApiForProject("myproject");
|
||||
|
||||
assertEquals(operationApi.get("operation-1354084865060-4cf88735faeb8-bbbb12cb"),
|
||||
new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
public void testGetOperationResponseIs4xx() throws Exception {
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
OperationApi operationApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, GET_OPERATION_REQUEST, operationResponse).getOperationApiForProject("myproject");
|
||||
|
||||
assertNull(operationApi.get("operation-1354084865060-4cf88735faeb8-bbbb12cb"));
|
||||
}
|
||||
|
||||
public void testDeleteOperationResponseIs2xx() throws Exception {
|
||||
HttpRequest delete = HttpRequest
|
||||
.builder()
|
||||
.method("DELETE")
|
||||
.endpoint(OPERATIONS_URL_PREFIX + "/operation-1352178598164-4cdcc9d031510-4aa46279")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(204).build();
|
||||
|
||||
OperationApi operationApi = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, delete, operationResponse).getOperationApiForProject("myproject");
|
||||
|
||||
operationApi.delete("operation-1352178598164-4cdcc9d031510-4aa46279");
|
||||
}
|
||||
|
||||
public void testDeleteOperationResponseIs4xx() throws Exception {
|
||||
HttpRequest delete = HttpRequest
|
||||
.builder()
|
||||
.method("DELETE")
|
||||
.endpoint(OPERATIONS_URL_PREFIX + "/operation-1352178598164-4cdcc9d031510-4aa46279")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
OperationApi operationApi = requestsSendResponses(requestForScopes(COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, delete, operationResponse).getOperationApiForProject("myproject");
|
||||
|
||||
operationApi.delete("operation-1352178598164-4cdcc9d031510-4aa46279");
|
||||
}
|
||||
|
||||
public void testLisOperationWithNoOptionsResponseIs2xx() {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(OPERATIONS_URL_PREFIX)
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation_list.json")).build();
|
||||
|
||||
OperationApi operationApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getOperationApiForProject("myproject");
|
||||
|
||||
assertEquals(operationApi.listFirstPage().toString(),
|
||||
new ParseOperationListTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testListOperationWithPaginationOptionsResponseIs2xx() {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(OPERATIONS_URL_PREFIX +
|
||||
"?pageToken=CglPUEVSQVRJT04SOzU5MDQyMTQ4Nzg1Mi5vcG" +
|
||||
"VyYXRpb24tMTM1MjI0NDI1ODAzMC00Y2RkYmU2YTJkNmIwLWVkMzIyMzQz&" +
|
||||
"filter=" +
|
||||
"status%20eq%20done&" +
|
||||
"maxResults=3")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation_list.json")).build();
|
||||
|
||||
OperationApi operationApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getOperationApiForProject("myproject");
|
||||
|
||||
assertEquals(operationApi.listAtMarker("CglPUEVSQVRJT04SOzU5MDQyMTQ4Nzg1Mi5vcGVyYXRpb24tMTM1Mj" +
|
||||
"I0NDI1ODAzMC00Y2RkYmU2YTJkNmIwLWVkMzIyMzQz",
|
||||
new ListOptions.Builder().filter("status eq done").maxResults(3)).toString(),
|
||||
new ParseOperationListTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testListOperationWithPaginationOptionsResponseIs4xx() {
|
||||
HttpRequest get = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(OPERATIONS_URL_PREFIX)
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
OperationApi operationApi = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, get, operationResponse).getOperationApiForProject("myproject");
|
||||
|
||||
assertTrue(operationApi.list().concat().isEmpty());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Iterables;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
|
||||
import org.jclouds.googlecomputeengine.options.ListOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.features.ProjectApiLiveTest.addItemToMetadata;
|
||||
import static org.jclouds.googlecomputeengine.features.ProjectApiLiveTest.deleteItemFromMetadata;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class OperationApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
|
||||
|
||||
private static final String METADATA_ITEM_KEY = "operationLiveTestTestProp";
|
||||
private static final String METADATA_ITEM_VALUE = "operationLiveTestTestValue";
|
||||
private Operation addOperation;
|
||||
private Operation deleteOperation;
|
||||
|
||||
private OperationApi api() {
|
||||
return api.getOperationApiForProject(userProject.get());
|
||||
}
|
||||
|
||||
|
||||
@Test(groups = "live")
|
||||
public void testCreateOperations() {
|
||||
//create some operations by adding and deleting metadata items
|
||||
// this will make sure there is stuff to listFirstPage
|
||||
addOperation = assertOperationDoneSucessfully(addItemToMetadata(api.getProjectApi(),
|
||||
userProject.get(), METADATA_ITEM_KEY, METADATA_ITEM_VALUE), 20);
|
||||
deleteOperation = assertOperationDoneSucessfully(deleteItemFromMetadata(api
|
||||
.getProjectApi(), userProject.get(), METADATA_ITEM_KEY), 20);
|
||||
|
||||
assertNotNull(addOperation);
|
||||
assertNotNull(deleteOperation);
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testCreateOperations")
|
||||
public void testGetOperation() {
|
||||
Operation operation = api().get(addOperation.getName());
|
||||
assertNotNull(operation);
|
||||
assertOperationEquals(operation, this.addOperation);
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testCreateOperations")
|
||||
public void testListOperationsWithFiltersAndPagination() {
|
||||
PagedIterable<Operation> operations = api().list(new ListOptions.Builder()
|
||||
.filter("operationType eq setMetadata")
|
||||
.maxResults(1));
|
||||
|
||||
// make sure that in spite of having only one result per page we get at least two results
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
operations.firstMatch(new Predicate<IterableWithMarker<Operation>>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(IterableWithMarker<Operation> input) {
|
||||
counter.addAndGet(Iterables.size(input));
|
||||
return counter.get() == 2;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void assertOperationEquals(Operation result, Operation expected) {
|
||||
assertEquals(result.getName(), expected.getName());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineConstants;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiExpectTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseMetadataTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseOperationTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseProjectTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ProjectApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
|
||||
|
||||
public static final String PROJECTS_URL_PREFIX = "https://www.googleapis.com/compute/v1beta13/projects";
|
||||
|
||||
public void testGetProjectResponseIs2xx() throws Exception {
|
||||
HttpRequest getProjectRequest = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(PROJECTS_URL_PREFIX + "/myproject")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse getProjectResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/project.json")).build();
|
||||
|
||||
ProjectApi api = requestsSendResponses(requestForScopes(GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, getProjectRequest,
|
||||
getProjectResponse).getProjectApi();
|
||||
|
||||
assertEquals(api.get("myproject"), new ParseProjectTest().expected());
|
||||
}
|
||||
|
||||
public void testGetProjectResponseIs4xx() throws Exception {
|
||||
HttpRequest getProjectRequest = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(PROJECTS_URL_PREFIX + "/myproject")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
HttpResponse getProjectResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
ProjectApi api = requestsSendResponses(requestForScopes(GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, getProjectRequest,
|
||||
getProjectResponse).getProjectApi();
|
||||
|
||||
assertNull(api.get("myproject"));
|
||||
}
|
||||
|
||||
public void testSetCommonInstanceMetadata() {
|
||||
HttpRequest setMetadata = HttpRequest
|
||||
.builder()
|
||||
.method("POST")
|
||||
.endpoint(PROJECTS_URL_PREFIX + "/myproject/setCommonInstanceMetadata")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN)
|
||||
.payload(payloadFromResourceWithContentType("/metadata.json", MediaType.APPLICATION_JSON))
|
||||
.build();
|
||||
|
||||
HttpResponse setMetadataResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/operation.json")).build();
|
||||
|
||||
ProjectApi api = requestsSendResponses(requestForScopes(GoogleComputeEngineConstants.COMPUTE_SCOPE),
|
||||
TOKEN_RESPONSE, setMetadata,
|
||||
setMetadataResponse).getProjectApi();
|
||||
|
||||
assertEquals(api.setCommonInstanceMetadata("myproject", new ParseMetadataTest().expected()),
|
||||
new ParseOperationTest().expected());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
import org.jclouds.googlecomputeengine.domain.Project;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static com.google.common.base.Predicates.equalTo;
|
||||
import static com.google.common.base.Predicates.not;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertFalse;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertSame;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class ProjectApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
|
||||
|
||||
private static final String METADATA_ITEM_KEY = "projectLiveTestTestProp";
|
||||
private static final String METADATA_ITEM_VALUE = "projectLiveTestTestValue";
|
||||
|
||||
private ProjectApi projectApi() {
|
||||
return api.getProjectApi();
|
||||
}
|
||||
|
||||
private Project project;
|
||||
private int initialMetadataSize;
|
||||
|
||||
@Test(groups = "live")
|
||||
public void testGetProjectWhenExists() {
|
||||
this.project = projectApi().get(userProject.get());
|
||||
assertNotNull(project);
|
||||
assertNotNull(project.getId());
|
||||
assertNotNull(project.getName());
|
||||
}
|
||||
|
||||
@Test(groups = "live")
|
||||
public void testGetProjectWhenNotExists() {
|
||||
Project project = projectApi().get("momma");
|
||||
assertNull(project);
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testGetProjectWhenExists")
|
||||
public void addItemToMetadata() {
|
||||
this.initialMetadataSize = project.getCommonInstanceMetadata().size();
|
||||
assertOperationDoneSucessfully(addItemToMetadata(projectApi(), userProject.get(), METADATA_ITEM_KEY,
|
||||
METADATA_ITEM_VALUE), 20);
|
||||
this.project = projectApi().get(userProject.get());
|
||||
assertNotNull(project);
|
||||
assertTrue(this.project.getCommonInstanceMetadata().containsKey(METADATA_ITEM_KEY),
|
||||
this.project.toString());
|
||||
assertEquals(this.project.getCommonInstanceMetadata().get(METADATA_ITEM_KEY),
|
||||
METADATA_ITEM_VALUE);
|
||||
}
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "addItemToMetadata")
|
||||
public void testDeleteItemFromMetadata() {
|
||||
assertOperationDoneSucessfully(deleteItemFromMetadata(projectApi(), userProject.get(), METADATA_ITEM_KEY), 20);
|
||||
this.project = projectApi().get(userProject.get());
|
||||
assertNotNull(project);
|
||||
assertFalse(project.getCommonInstanceMetadata().containsKey(METADATA_ITEM_KEY));
|
||||
assertSame(this.project.getCommonInstanceMetadata().size(), initialMetadataSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item to the Project's metadata
|
||||
* <p/>
|
||||
* Beyond it's use here it is also used as a cheap way of generating Operations to both test the OperationApi and
|
||||
* the pagination system.
|
||||
*/
|
||||
public static Operation addItemToMetadata(ProjectApi projectApi, String projectName, String key, String value) {
|
||||
Project project = projectApi.get(projectName);
|
||||
assertNotNull(project);
|
||||
ImmutableMap.Builder<String, String> metadataBuilder = ImmutableMap.builder();
|
||||
metadataBuilder.putAll(project.getCommonInstanceMetadata());
|
||||
metadataBuilder.put(key, value);
|
||||
return projectApi.setCommonInstanceMetadata(projectName, metadataBuilder.build());
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes an item from the Project's metadata
|
||||
* <p/>
|
||||
* Beyond it's use here it is also used as a cheap way of generating Operation's to both test the OperationApi and
|
||||
* the pagination system.
|
||||
*/
|
||||
public static Operation deleteItemFromMetadata(ProjectApi projectApi, String projectName, String key) {
|
||||
Project project = projectApi.get(projectName);
|
||||
assertNotNull(project);
|
||||
ImmutableMap.Builder<String, String> metadataBuilder = ImmutableMap.builder();
|
||||
metadataBuilder.putAll(Maps.filterKeys(project.getCommonInstanceMetadata(), not(equalTo(key))));
|
||||
return projectApi.setCommonInstanceMetadata(projectName, metadataBuilder.build());
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiExpectTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseZoneListTest;
|
||||
import org.jclouds.googlecomputeengine.parse.ParseZoneTest;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.jclouds.googlecomputeengine.GoogleComputeEngineConstants.COMPUTE_READONLY_SCOPE;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNull;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
@Test(groups = "unit")
|
||||
public class ZoneApiExpectTest extends BaseGoogleComputeEngineApiExpectTest {
|
||||
|
||||
public static final String ZONES_URL_PREFIX = "https://www.googleapis.com/compute/v1beta13/projects/myproject/zones";
|
||||
|
||||
public static final HttpRequest GET_ZONE_REQ = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(ZONES_URL_PREFIX + "/us-central1-a")
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
public static final HttpRequest LIST_ZONES_REQ = HttpRequest
|
||||
.builder()
|
||||
.method("GET")
|
||||
.endpoint(ZONES_URL_PREFIX)
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Authorization", "Bearer " + TOKEN).build();
|
||||
|
||||
public static final HttpResponse LIST_ZONES_RESPONSE = HttpResponse.builder().statusCode(200)
|
||||
.payload(staticPayloadFromResource("/zone_list.json")).build();
|
||||
|
||||
|
||||
public void testGetZoneResponseIs2xx() throws Exception {
|
||||
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(payloadFromResource("/zone_get.json")).build();
|
||||
|
||||
ZoneApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, GET_ZONE_REQ, operationResponse).getZoneApiForProject("myproject");
|
||||
|
||||
assertEquals(api.get("us-central1-a"),
|
||||
new ParseZoneTest().expected());
|
||||
}
|
||||
|
||||
public void testGetZoneResponseIs4xx() throws Exception {
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
ZoneApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, GET_ZONE_REQ, operationResponse).getZoneApiForProject("myproject");
|
||||
|
||||
assertNull(api.get("us-central1-a"));
|
||||
}
|
||||
|
||||
public void testListZoneNoOptionsResponseIs2xx() throws Exception {
|
||||
|
||||
ZoneApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, LIST_ZONES_REQ, LIST_ZONES_RESPONSE).getZoneApiForProject("myproject");
|
||||
|
||||
assertEquals(api.listFirstPage().toString(),
|
||||
new ParseZoneListTest().expected().toString());
|
||||
}
|
||||
|
||||
public void testListZoneWithPaginationOptionsResponseIs4xx() {
|
||||
|
||||
HttpResponse operationResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
ZoneApi api = requestsSendResponses(requestForScopes(COMPUTE_READONLY_SCOPE),
|
||||
TOKEN_RESPONSE, LIST_ZONES_REQ, operationResponse).getZoneApiForProject("myproject");
|
||||
|
||||
assertTrue(api.list().concat().isEmpty());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.features;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jclouds.collect.IterableWithMarker;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.googlecomputeengine.domain.Zone;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineApiLiveTest;
|
||||
import org.jclouds.googlecomputeengine.options.ListOptions;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
import static org.testng.Assert.assertSame;
|
||||
import static org.testng.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class ZoneApiLiveTest extends BaseGoogleComputeEngineApiLiveTest {
|
||||
|
||||
private Zone zone;
|
||||
|
||||
private ZoneApi api() {
|
||||
return api.getZoneApiForProject(userProject.get());
|
||||
}
|
||||
|
||||
@Test(groups = "live")
|
||||
public void testListZone() {
|
||||
|
||||
PagedIterable<Zone> zones = api().list(new ListOptions.Builder()
|
||||
.maxResults(1));
|
||||
|
||||
Iterator<IterableWithMarker<Zone>> pageIterator = zones.iterator();
|
||||
assertTrue(pageIterator.hasNext());
|
||||
|
||||
IterableWithMarker<Zone> singlePageIterator = pageIterator.next();
|
||||
List<Zone> zoneAsList = Lists.newArrayList(singlePageIterator);
|
||||
|
||||
assertSame(zoneAsList.size(), 1);
|
||||
|
||||
this.zone = Iterables.getOnlyElement(zoneAsList);
|
||||
}
|
||||
|
||||
|
||||
@Test(groups = "live", dependsOnMethods = "testListZone")
|
||||
public void testGetZone() {
|
||||
Zone zone = api().get(this.zone.getName());
|
||||
assertNotNull(zone);
|
||||
assertZoneEquals(zone, this.zone);
|
||||
}
|
||||
|
||||
private void assertZoneEquals(Zone result, Zone expected) {
|
||||
assertEquals(result.getName(), expected.getName());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/**
|
||||
* 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.googlecomputeengine.handlers;
|
||||
|
||||
import org.easymock.IArgumentMatcher;
|
||||
import org.jclouds.http.HttpCommand;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.reportMatcher;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "GoogleComputeErrorHandlerTest")
|
||||
public class GoogleComputeEngineErrorHandlerTest {
|
||||
|
||||
@Test
|
||||
public void test409MakesIllegalStateException() {
|
||||
assertCodeMakes(
|
||||
"POST",
|
||||
URI.create("https://www.googleapis.com/compute/v1beta13"),
|
||||
409,
|
||||
"HTTP/1.1 409 Conflict",
|
||||
"\"{\"code\":\"InvalidState\",\"message\":\"An incompatible transition has already been queued for this" +
|
||||
" resource\"}\"",
|
||||
IllegalStateException.class);
|
||||
}
|
||||
|
||||
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String content,
|
||||
Class<? extends Exception> expected) {
|
||||
assertCodeMakes(method, uri, statusCode, message, "application/json", content, expected);
|
||||
}
|
||||
|
||||
private void assertCodeMakes(String method, URI uri, int statusCode, String message, String contentType,
|
||||
String content, Class<? extends Exception> expected) {
|
||||
|
||||
GoogleComputeEngineErrorHandler function = new GoogleComputeEngineErrorHandler();
|
||||
|
||||
HttpCommand command = createMock(HttpCommand.class);
|
||||
HttpRequest request = HttpRequest.builder().method(method).endpoint(uri).build();
|
||||
HttpResponse response = HttpResponse.builder().statusCode(statusCode).message(message).payload(content).build();
|
||||
response.getPayload().getContentMetadata().setContentType(contentType);
|
||||
|
||||
expect(command.getCurrentRequest()).andReturn(request).atLeastOnce();
|
||||
command.setException(classEq(expected));
|
||||
|
||||
replay(command);
|
||||
|
||||
function.handleError(command, response);
|
||||
|
||||
verify(command);
|
||||
}
|
||||
|
||||
public static Exception classEq(final Class<? extends Exception> in) {
|
||||
reportMatcher(new IArgumentMatcher() {
|
||||
|
||||
@Override
|
||||
public void appendTo(StringBuffer buffer) {
|
||||
buffer.append("classEq(");
|
||||
buffer.append(in);
|
||||
buffer.append(")");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Object arg) {
|
||||
return arg.getClass() == in;
|
||||
}
|
||||
|
||||
});
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* 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.googlecomputeengine.internal;
|
||||
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BaseGoogleComputeEngineApiExpectTest extends BaseGoogleComputeEngineExpectTest<GoogleComputeEngineApi> {
|
||||
|
||||
@Override
|
||||
protected Properties setupProperties() {
|
||||
Properties properties = super.setupProperties();
|
||||
properties.put("google-compute-engine.identity", "myproject");
|
||||
return properties;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/**
|
||||
* 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.googlecomputeengine.internal;
|
||||
|
||||
import static java.util.concurrent.TimeUnit.SECONDS;
|
||||
import static org.jclouds.util.Predicates2.retry;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.AssertJUnit.assertTrue;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.jclouds.apis.BaseApiLiveTest;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApi;
|
||||
import org.jclouds.googlecomputeengine.config.UserProject;
|
||||
import org.jclouds.googlecomputeengine.domain.Operation;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class BaseGoogleComputeEngineApiLiveTest extends BaseApiLiveTest<GoogleComputeEngineApi> {
|
||||
|
||||
protected static final String API_URL_PREFIX = "https://www.googleapis.com/compute/v1beta13/projects/";
|
||||
protected static final String ZONE_API_URL_SUFFIX = "/zones/";
|
||||
protected static final String DEFAULT_ZONE_NAME = "us-central1-a";
|
||||
|
||||
protected static final String NETWORK_API_URL_SUFFIX = "/networks/";
|
||||
protected static final String DEFAULT_NETWORK_NAME = "live-test-network";
|
||||
|
||||
protected static final String MACHINE_TYPE_API_URL_SUFFIX = "/machineTypes/";
|
||||
protected static final String DEFAULT_MACHINE_TYPE_NAME = "n1-standard-1";
|
||||
|
||||
protected static final String GOOGLE_PROJECT = "google";
|
||||
|
||||
protected Supplier<String> userProject;
|
||||
protected Predicate<AtomicReference<Operation>> operationDonePredicate;
|
||||
|
||||
|
||||
public BaseGoogleComputeEngineApiLiveTest() {
|
||||
provider = "google-compute-engine";
|
||||
}
|
||||
|
||||
protected GoogleComputeEngineApi create(Properties props, Iterable<Module> modules) {
|
||||
Injector injector = newBuilder().modules(modules).overrides(props).buildInjector();
|
||||
userProject = injector.getInstance(Key.get(new TypeLiteral<Supplier<String>>() {
|
||||
}, UserProject.class));
|
||||
operationDonePredicate = injector.getInstance(Key.get(new TypeLiteral<Predicate<AtomicReference<Operation>>>() {
|
||||
}));
|
||||
return injector.getInstance(GoogleComputeEngineApi.class);
|
||||
}
|
||||
|
||||
protected Operation assertOperationDoneSucessfully(Operation operation, long maxWaitSeconds) {
|
||||
operation = waitOperationDone(operation, maxWaitSeconds);
|
||||
assertEquals(operation.getStatus(), Operation.Status.DONE);
|
||||
assertTrue(operation.getErrors().isEmpty());
|
||||
return operation;
|
||||
}
|
||||
|
||||
protected Operation waitOperationDone(Operation operation, long maxWaitSeconds) {
|
||||
return waitOperationDone(operationDonePredicate, operation, maxWaitSeconds);
|
||||
}
|
||||
|
||||
protected URI getDefaultZoneUrl(String project) {
|
||||
return getZoneUrl(project, DEFAULT_ZONE_NAME);
|
||||
}
|
||||
|
||||
protected URI getZoneUrl(String project, String zone) {
|
||||
return URI.create(API_URL_PREFIX + project + ZONE_API_URL_SUFFIX + zone);
|
||||
}
|
||||
|
||||
protected URI getDefaultNetworkUrl(String project) {
|
||||
return getNetworkUrl(project, DEFAULT_NETWORK_NAME);
|
||||
}
|
||||
|
||||
protected URI getNetworkUrl(String project, String network) {
|
||||
return URI.create(API_URL_PREFIX + project + NETWORK_API_URL_SUFFIX + network);
|
||||
}
|
||||
|
||||
protected URI getDefaultMachineTypekUrl(String project) {
|
||||
return gettMachineTypeUrl(project, DEFAULT_MACHINE_TYPE_NAME);
|
||||
}
|
||||
|
||||
protected URI gettMachineTypeUrl(String project, String machineType) {
|
||||
return URI.create(API_URL_PREFIX + project + MACHINE_TYPE_API_URL_SUFFIX + machineType);
|
||||
}
|
||||
|
||||
protected URI getDiskUrl(String project, String diskName) {
|
||||
return URI.create(API_URL_PREFIX + project + "/disks/" + diskName);
|
||||
}
|
||||
|
||||
protected static Operation waitOperationDone(Predicate<AtomicReference<Operation>> operationDonePredicate,
|
||||
Operation operation, long maxWaitSeconds) {
|
||||
AtomicReference<Operation> operationReference = new AtomicReference<Operation>(operation);
|
||||
retry(operationDonePredicate, maxWaitSeconds, 1, SECONDS).apply(operationReference);
|
||||
return operationReference.get();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
/**
|
||||
* 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.googlecomputeengine.internal;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Ticker;
|
||||
import com.google.inject.Binder;
|
||||
import com.google.inject.Module;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.collect.PagedIterable;
|
||||
import org.jclouds.collect.PagedIterables;
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.io.Payload;
|
||||
import org.jclouds.oauth.v2.OAuthConstants;
|
||||
import org.jclouds.rest.internal.BaseRestApiExpectTest;
|
||||
import org.jclouds.ssh.SshKeys;
|
||||
import org.jclouds.util.Strings2;
|
||||
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static com.google.common.base.Charsets.UTF_8;
|
||||
import static com.google.common.base.Throwables.propagate;
|
||||
import static com.google.common.io.BaseEncoding.base64Url;
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.expectLastCall;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.jclouds.crypto.Pems.privateKeySpec;
|
||||
import static org.jclouds.crypto.Pems.publicKeySpec;
|
||||
import static org.jclouds.crypto.PemsTest.PRIVATE_KEY;
|
||||
import static org.jclouds.crypto.PemsTest.PUBLIC_KEY;
|
||||
import static org.jclouds.io.Payloads.newStringPayload;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class BaseGoogleComputeEngineExpectTest<T> extends BaseRestApiExpectTest<T> {
|
||||
|
||||
private static final String header = "{\"alg\":\"none\",\"typ\":\"JWT\"}";
|
||||
|
||||
private static final String CLAIMS_TEMPLATE = "{" +
|
||||
"\"iss\":\"myproject\"," +
|
||||
"\"scope\":\"%s\"," +
|
||||
"\"aud\":\"https://accounts.google.com/o/oauth2/token\"," +
|
||||
"\"exp\":3600," +
|
||||
"\"iat\":0}";
|
||||
|
||||
protected static final String TOKEN = "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M";
|
||||
|
||||
protected static final HttpResponse TOKEN_RESPONSE = HttpResponse.builder().statusCode(200).payload(
|
||||
payloadFromString("{\n" +
|
||||
" \"access_token\" : \"" + TOKEN + "\",\n" +
|
||||
" \"token_type\" : \"Bearer\",\n" +
|
||||
" \"expires_in\" : 3600\n" +
|
||||
"}")).build();
|
||||
|
||||
protected String openSshKey;
|
||||
|
||||
|
||||
public BaseGoogleComputeEngineExpectTest() {
|
||||
provider = "google-compute-engine";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Module createModule() {
|
||||
|
||||
|
||||
return new Module() {
|
||||
@Override
|
||||
public void configure(Binder binder) {
|
||||
// predictable time
|
||||
binder.bind(Ticker.class).toInstance(new Ticker() {
|
||||
@Override
|
||||
public long read() {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
try {
|
||||
KeyFactory keyfactory = KeyFactory.getInstance("RSA");
|
||||
PrivateKey privateKey = keyfactory.generatePrivate(privateKeySpec(newStringPayload
|
||||
(PRIVATE_KEY)));
|
||||
PublicKey publicKey = keyfactory.generatePublic(publicKeySpec(newStringPayload(PUBLIC_KEY)));
|
||||
KeyPair keyPair = new KeyPair(publicKey, privateKey);
|
||||
openSshKey = SshKeys.encodeAsOpenSSH(RSAPublicKey.class.cast(publicKey));
|
||||
final Crypto crypto = createMock(Crypto.class);
|
||||
KeyPairGenerator rsaKeyPairGenerator = createMock(KeyPairGenerator.class);
|
||||
final SecureRandom secureRandom = createMock(SecureRandom.class);
|
||||
expect(crypto.rsaKeyPairGenerator()).andReturn(rsaKeyPairGenerator).anyTimes();
|
||||
rsaKeyPairGenerator.initialize(2048, secureRandom);
|
||||
expectLastCall().anyTimes();
|
||||
expect(rsaKeyPairGenerator.genKeyPair()).andReturn(keyPair).anyTimes();
|
||||
replay(crypto, rsaKeyPairGenerator, secureRandom);
|
||||
binder.bind(Crypto.class).toInstance(crypto);
|
||||
binder.bind(SecureRandom.class).toInstance(secureRandom);
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
propagate(e);
|
||||
} catch (InvalidKeySpecException e) {
|
||||
propagate(e);
|
||||
} catch (IOException e) {
|
||||
propagate(e);
|
||||
}
|
||||
// predictable node names
|
||||
final AtomicInteger suffix = new AtomicInteger();
|
||||
binder.bind(new TypeLiteral<Supplier<String>>() {
|
||||
}).toInstance(new Supplier<String>() {
|
||||
@Override
|
||||
public String get() {
|
||||
return suffix.getAndIncrement() + "";
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Properties setupProperties() {
|
||||
Properties props = super.setupProperties();
|
||||
// use no sig algorithm for expect tests (means no credential is required either)
|
||||
props.put("jclouds.oauth.signature-or-mac-algorithm", OAuthConstants.NO_ALGORITHM);
|
||||
return props;
|
||||
}
|
||||
|
||||
protected HttpRequest requestForScopes(String... scopes) {
|
||||
String claims = String.format(CLAIMS_TEMPLATE, Joiner.on(",").join(scopes));
|
||||
|
||||
String payload = "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&" +
|
||||
// Base64 Encoded Header
|
||||
"assertion=" + base64Url().omitPadding().encode(header.getBytes(UTF_8)) + "." +
|
||||
// Base64 Encoded Claims
|
||||
base64Url().omitPadding().encode(claims.getBytes(UTF_8)) + ".";
|
||||
|
||||
return HttpRequest.builder()
|
||||
.method("POST")
|
||||
.endpoint(URI.create("https://accounts.google.com/o/oauth2/token"))
|
||||
.addHeader("Accept", MediaType.APPLICATION_JSON)
|
||||
.payload(payloadFromStringWithContentType(payload, "application/x-www-form-urlencoded"))
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse tests don't apply @Transform so we need to apply the transformation to PagedIterable on the result of
|
||||
* expected()
|
||||
*/
|
||||
protected <T> PagedIterable<T> toPagedIterable(ListPage<T> list) {
|
||||
return PagedIterables.of(list);
|
||||
}
|
||||
|
||||
protected static Payload staticPayloadFromResource(String resource) {
|
||||
try {
|
||||
return payloadFromString(Strings2.toStringAndClose(BaseGoogleComputeEngineExpectTest.class.getResourceAsStream
|
||||
(resource)));
|
||||
} catch (IOException e) {
|
||||
throw propagate(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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.googlecomputeengine.internal;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
import org.jclouds.googlecomputeengine.config.GoogleComputeEngineParserModule;
|
||||
import org.jclouds.json.BaseItemParserTest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public abstract class BaseGoogleComputeEngineParseTest<T> extends BaseItemParserTest<T> {
|
||||
|
||||
@Override
|
||||
protected Injector injector() {
|
||||
return Guice.createInjector(new GsonModule(), new GoogleComputeEngineParserModule());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.internal;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.Module;
|
||||
import org.jclouds.apis.ApiMetadata;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.googlecomputeengine.GoogleComputeEngineApiMetadata;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public abstract class BaseGoogleComputeEngineServiceContextExpectTest<T> extends BaseGoogleComputeEngineExpectTest<T> implements
|
||||
Function<ComputeServiceContext, T> {
|
||||
|
||||
|
||||
@Override
|
||||
public T createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props) {
|
||||
return apply(createComputeServiceContext(fn, module, props));
|
||||
}
|
||||
|
||||
private ComputeServiceContext createComputeServiceContext(Function<HttpRequest, HttpResponse> fn, Module module,
|
||||
Properties props) {
|
||||
return createInjector(fn, module, props).getInstance(ComputeServiceContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ApiMetadata createApiMetadata() {
|
||||
return new GoogleComputeEngineApiMetadata();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.internal;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
|
||||
/**
|
||||
* @author David Alves
|
||||
*/
|
||||
public class BaseGoogleComputeEngineServiceExpectTest extends BaseGoogleComputeEngineServiceContextExpectTest<ComputeService> {
|
||||
|
||||
@Override
|
||||
public ComputeService apply(ComputeServiceContext input) {
|
||||
return input.getComputeService();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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.googlecomputeengine.parse;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||
import org.jclouds.googlecomputeengine.domain.Disk;
|
||||
import org.jclouds.googlecomputeengine.domain.ListPage;
|
||||
import org.jclouds.googlecomputeengine.domain.Resource;
|
||||
import org.jclouds.googlecomputeengine.internal.BaseGoogleComputeEngineParseTest;
|
||||
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 ParseDiskListTest extends BaseGoogleComputeEngineParseTest<ListPage<Disk>> {
|
||||
|
||||
@Override
|
||||
public String resource() {
|
||||
return "/disk_list.json";
|
||||
}
|
||||
|
||||
@Override
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public ListPage<Disk> expected() {
|
||||
return ListPage.<Disk>builder()
|
||||
.kind(Resource.Kind.DISK_LIST)
|
||||
.id("projects/myproject/disks")
|
||||
.selfLink(URI.create("https://www.googleapis.com/compute/v1beta13/projects/myproject/disks"))
|
||||
.items(ImmutableSet.of(Disk.builder()
|
||||
.id("13050421646334304115")
|
||||
.creationTimestamp(new SimpleDateFormatDateService().iso8601DateParse("2012-11-25T01:38:48.306"))
|
||||
.selfLink(URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/disks/testimage1"))
|
||||
.name("testimage1")
|
||||
.sizeGb(1)
|
||||
.zone(URI.create("https://www.googleapis" +
|
||||
".com/compute/v1beta13/projects/myproject/zones/us-central1-a"))
|
||||
.status("READY")
|
||||
.build())
|
||||
).build();
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue