Initial GCE commit
Project: http://git-wip-us.apache.org/repos/asf/stratos/repo Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/4203d59b Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/4203d59b Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/4203d59b Branch: refs/heads/master Commit: 4203d59b28c38c432c44b4973c55ef91f3f41d82 Parents: ba95cf3 Author: Suriya priya <[email protected]> Authored: Sun Oct 12 23:52:48 2014 -0700 Committer: Nirmal Fernando <[email protected]> Committed: Sun Oct 19 17:47:35 2014 +0200 ---------------------------------------------------------------------- .../org.apache.stratos.cloud.controller/pom.xml | 5 + .../cloud/controller/iaases/GCEIaas.java | 464 +++++++ .../validate/GCEPartitionValidator.java | 54 + .../jclouds/apis/gce/1.8.0-stratos/README.txt | 77 ++ .../jclouds/apis/gce/1.8.0-stratos/pom.xml | 135 ++ .../GoogleComputeEngineApi.java | 185 +++ .../GoogleComputeEngineApiMetadata.java | 104 ++ .../GoogleComputeEngineConstants.java | 81 ++ .../compute/GoogleComputeEngineService.java | 200 +++ .../GoogleComputeEngineServiceAdapter.java | 439 +++++++ ...GoogleComputeEngineServiceContextModule.java | 283 +++++ ...ogleComputeEngineSecurityGroupExtension.java | 338 +++++ .../functions/BuildInstanceMetadata.java | 46 + .../functions/FirewallTagNamingConvention.java | 62 + .../functions/FirewallToIpPermission.java | 87 ++ .../GoogleComputeEngineImageToImage.java | 80 ++ .../functions/InstanceInZoneToNodeMetadata.java | 150 +++ .../functions/MachineTypeInZoneToHardware.java | 100 ++ .../functions/NetworkToSecurityGroup.java | 82 ++ .../functions/OrphanedGroupsFromDeadNodes.java | 57 + .../compute/functions/RegionToLocation.java | 45 + .../compute/functions/ZoneToLocation.java | 45 + .../compute/loaders/FindNetworkOrCreate.java | 62 + .../GoogleComputeEngineTemplateOptions.java | 382 ++++++ .../predicates/AllNodesInGroupTerminated.java | 48 + ...desWithGroupEncodedIntoNameThenAddToSet.java | 183 +++ ...DefaultLoginCredentialsForImageStrategy.java | 69 + ...eNodeCredentialsButOverrideFromTemplate.java | 57 + .../GoogleComputeEngineHttpApiModule.java | 177 +++ .../config/GoogleComputeEngineParserModule.java | 413 ++++++ .../config/OAuthModuleWithoutTypeAdapters.java | 51 + .../googlecomputeengine/config/UserProject.java | 33 + .../domain/AbstractDisk.java | 121 ++ .../googlecomputeengine/domain/Address.java | 177 +++ .../googlecomputeengine/domain/Deprecated.java | 195 +++ .../googlecomputeengine/domain/Disk.java | 123 ++ .../googlecomputeengine/domain/Firewall.java | 379 ++++++ .../googlecomputeengine/domain/Image.java | 286 +++++ .../googlecomputeengine/domain/Instance.java | 1187 ++++++++++++++++++ .../domain/InstanceInZone.java | 52 + .../domain/InstanceTemplate.java | 445 +++++++ .../googlecomputeengine/domain/ListPage.java | 179 +++ .../googlecomputeengine/domain/MachineType.java | 360 ++++++ .../domain/MachineTypeInZone.java | 52 + .../googlecomputeengine/domain/Metadata.java | 139 ++ .../googlecomputeengine/domain/Network.java | 133 ++ .../googlecomputeengine/domain/Operation.java | 556 ++++++++ .../googlecomputeengine/domain/Project.java | 162 +++ .../googlecomputeengine/domain/Quota.java | 152 +++ .../googlecomputeengine/domain/Region.java | 175 +++ .../googlecomputeengine/domain/Resource.java | 283 +++++ .../googlecomputeengine/domain/Route.java | 433 +++++++ .../domain/SlashEncodedIds.java | 83 ++ .../googlecomputeengine/domain/Snapshot.java | 135 ++ .../googlecomputeengine/domain/Zone.java | 334 +++++ .../domain/internal/NetworkAndAddressRange.java | 91 ++ .../features/AddressApi.java | 187 +++ .../googlecomputeengine/features/DiskApi.java | 255 ++++ .../features/FirewallApi.java | 227 ++++ .../features/GlobalOperationApi.java | 158 +++ .../googlecomputeengine/features/ImageApi.java | 167 +++ .../features/InstanceApi.java | 381 ++++++ .../features/MachineTypeApi.java | 143 +++ .../features/NetworkApi.java | 204 +++ .../features/ProjectApi.java | 96 ++ .../googlecomputeengine/features/RegionApi.java | 135 ++ .../features/RegionOperationApi.java | 163 +++ .../googlecomputeengine/features/RouteApi.java | 184 +++ .../features/SnapshotApi.java | 160 +++ .../googlecomputeengine/features/ZoneApi.java | 135 ++ .../features/ZoneOperationApi.java | 163 +++ .../functions/CreateNetworkIfNeeded.java | 100 ++ .../functions/internal/BaseToPagedIterable.java | 66 + .../internal/BaseWithRegionToPagedIterable.java | 72 ++ .../internal/BaseWithZoneToPagedIterable.java | 72 ++ .../functions/internal/PATCH.java | 35 + .../functions/internal/ParseAddresses.java | 67 + .../functions/internal/ParseDisks.java | 67 + .../functions/internal/ParseFirewalls.java | 63 + .../internal/ParseGlobalOperations.java | 63 + .../functions/internal/ParseImages.java | 63 + .../functions/internal/ParseInstances.java | 65 + .../functions/internal/ParseMachineTypes.java | 64 + .../functions/internal/ParseNetworks.java | 63 + .../internal/ParseRegionOperations.java | 65 + .../functions/internal/ParseRegions.java | 63 + .../functions/internal/ParseRoutes.java | 63 + .../functions/internal/ParseSnapshots.java | 66 + .../functions/internal/ParseZoneOperations.java | 65 + .../functions/internal/ParseZones.java | 63 + .../handlers/FirewallBinder.java | 56 + .../GoogleComputeEngineErrorHandler.java | 62 + .../handlers/InstanceBinder.java | 65 + .../handlers/MetadataBinder.java | 60 + .../handlers/RouteBinder.java | 56 + .../options/AttachDiskOptions.java | 128 ++ .../options/DeprecateOptions.java | 126 ++ .../options/FirewallOptions.java | 166 +++ .../options/ListOptions.java | 91 ++ .../options/RouteOptions.java | 202 +++ .../GlobalOperationDonePredicate.java | 59 + .../predicates/InstancePredicates.java | 33 + .../predicates/NetworkFirewallPredicates.java | 121 ++ .../RegionOperationDonePredicate.java | 69 + .../predicates/ZoneOperationDonePredicate.java | 68 + .../java/org/jclouds/oauth/v2/OAuthApi.java | 63 + .../org/jclouds/oauth/v2/OAuthApiMetadata.java | 80 ++ .../org/jclouds/oauth/v2/OAuthConstants.java | 78 ++ .../jclouds/oauth/v2/config/Authentication.java | 35 + .../v2/config/OAuthAuthenticationModule.java | 52 + .../oauth/v2/config/OAuthHttpApiModule.java | 45 + .../jclouds/oauth/v2/config/OAuthModule.java | 86 ++ .../oauth/v2/config/OAuthProperties.java | 43 + .../jclouds/oauth/v2/config/OAuthScopes.java | 40 + .../org/jclouds/oauth/v2/domain/ClaimSet.java | 191 +++ .../org/jclouds/oauth/v2/domain/Header.java | 128 ++ .../oauth/v2/domain/OAuthCredentials.java | 129 ++ .../java/org/jclouds/oauth/v2/domain/Token.java | 149 +++ .../jclouds/oauth/v2/domain/TokenRequest.java | 131 ++ .../oauth/v2/domain/TokenRequestFormat.java | 45 + .../oauth/v2/filters/OAuthAuthenticator.java | 63 + .../oauth/v2/functions/BuildTokenRequest.java | 135 ++ .../jclouds/oauth/v2/functions/FetchToken.java | 41 + .../v2/functions/OAuthCredentialsSupplier.java | 125 ++ .../v2/functions/SignOrProduceMacForToken.java | 119 ++ .../oauth/v2/handlers/OAuthErrorHandler.java | 64 + .../oauth/v2/handlers/OAuthTokenBinder.java | 45 + .../oauth/v2/json/ClaimSetTypeAdapter.java | 59 + .../oauth/v2/json/HeaderTypeAdapter.java | 52 + .../oauth/v2/json/JWTTokenRequestFormat.java | 96 ++ .../services/org.jclouds.apis.ApiMetadata | 19 + .../GoogleComputeEngineApiMetadataTest.java | 38 + ...eEngineAuthenticatedRestContextLiveTest.java | 33 + .../PageSystemExpectTest.java | 114 ++ .../GoogleComputeEngineServiceExpectTest.java | 574 +++++++++ .../GoogleComputeEngineServiceLiveTest.java | 128 ++ ...uteEngineSecurityGroupExtensionLiveTest.java | 28 + .../functions/FirewallToIpPermissionTest.java | 93 ++ .../GoogleComputeEngineImageToImageTest.java | 60 + .../InstanceInZoneToNodeMetadataTest.java | 286 +++++ .../functions/NetworkToSecurityGroupTest.java | 94 ++ .../OrphanedGroupsFromDeadNodesTest.java | 136 ++ .../loaders/FindNetworkOrCreateTest.java | 141 +++ .../features/AddressApiExpectTest.java | 163 +++ .../features/AddressApiLiveTest.java | 71 ++ .../features/DiskApiExpectTest.java | 226 ++++ .../features/DiskApiLiveTest.java | 85 ++ .../features/FirewallApiExpectTest.java | 301 +++++ .../features/FirewallApiLiveTest.java | 163 +++ .../features/GlobalOperationApiExpectTest.java | 158 +++ .../features/GlobalOperationApiLiveTest.java | 91 ++ .../features/ImageApiExpectTest.java | 159 +++ .../features/ImageApiLiveTest.java | 74 ++ .../features/InstanceApiExpectTest.java | 410 ++++++ .../features/InstanceApiLiveTest.java | 240 ++++ .../features/MachineTypeApiExpectTest.java | 113 ++ .../features/MachineTypeApiLiveTest.java | 73 ++ .../features/NetworkApiExpectTest.java | 164 +++ .../features/NetworkApiLiveTest.java | 83 ++ .../features/ProjectApiExpectTest.java | 96 ++ .../features/ProjectApiLiveTest.java | 123 ++ .../features/RegionApiExpectTest.java | 94 ++ .../features/RegionApiLiveTest.java | 74 ++ .../features/RegionOperationApiExpectTest.java | 195 +++ .../features/RegionOperationApiLiveTest.java | 91 ++ .../features/RouteApiExpectTest.java | 175 +++ .../features/RouteApiLiveTest.java | 96 ++ .../features/SnapshotApiExpectTest.java | 94 ++ .../features/SnapshotApiLiveTest.java | 92 ++ .../features/ZoneApiExpectTest.java | 97 ++ .../features/ZoneApiLiveTest.java | 74 ++ .../features/ZoneOperationApiExpectTest.java | 193 +++ .../features/ZoneOperationApiLiveTest.java | 90 ++ .../functions/CreateNetworkIfNeededTest.java | 132 ++ .../GoogleComputeEngineErrorHandlerTest.java | 92 ++ .../BaseGoogleComputeEngineApiExpectTest.java | 31 + .../BaseGoogleComputeEngineApiLiveTest.java | 160 +++ .../BaseGoogleComputeEngineExpectTest.java | 195 +++ .../BaseGoogleComputeEngineParseTest.java | 33 + ...leComputeEngineServiceContextExpectTest.java | 49 + ...aseGoogleComputeEngineServiceExpectTest.java | 28 + .../parse/ParseAddressListTest.java | 61 + .../parse/ParseAddressTest.java | 51 + .../parse/ParseDiskListTest.java | 61 + .../parse/ParseDiskTest.java | 50 + .../parse/ParseFirewallListTest.java | 68 + .../parse/ParseFirewallTest.java | 60 + .../parse/ParseImageListTest.java | 71 ++ .../parse/ParseImageTest.java | 55 + .../parse/ParseInstanceListTest.java | 48 + .../parse/ParseInstanceSerialOutputTest.java | 38 + .../parse/ParseInstanceTest.java | 81 ++ .../parse/ParseMachineTypeListTest.java | 94 ++ .../parse/ParseMachineTypeTest.java | 57 + .../parse/ParseMetadataTest.java | 45 + .../parse/ParseNetworkListTest.java | 49 + .../parse/ParseNetworkTest.java | 48 + .../parse/ParseOperationListTest.java | 46 + .../parse/ParseOperationTest.java | 58 + .../parse/ParseProjectTest.java | 67 + .../parse/ParseQuotaTest.java | 39 + .../parse/ParseRegionListTest.java | 72 ++ .../parse/ParseRegionTest.java | 62 + .../parse/ParseRouteListTest.java | 62 + .../parse/ParseRouteTest.java | 56 + .../parse/ParseSnapshotListTest.java | 64 + .../parse/ParseSnapshotTest.java | 52 + .../parse/ParseZoneListTest.java | 70 ++ .../parse/ParseZoneTest.java | 55 + .../NetworkFirewallPredicatesTest.java | 162 +++ .../jclouds/oauth/v2/OAuthApiMetadataTest.java | 38 + .../org/jclouds/oauth/v2/OAuthTestUtils.java | 75 ++ .../oauth/v2/features/OAuthApiExpectTest.java | 99 ++ .../oauth/v2/features/OAuthApiLiveTest.java | 80 ++ .../functions/OAuthCredentialsFromPKTest.java | 61 + .../functions/OAuthCredentialsSupplierTest.java | 55 + .../oauth/v2/functions/SignerFunctionTest.java | 61 + .../v2/handlers/OAuthErrorHandlerTest.java | 92 ++ .../oauth/v2/internal/Base64UrlSafeTest.java | 40 + .../v2/internal/BaseOAuthApiExpectTest.java | 23 + .../oauth/v2/internal/BaseOAuthApiLiveTest.java | 56 + .../BaseOAuthAuthenticatedApiLiveTest.java | 110 ++ .../oauth/v2/internal/BaseOAuthExpectTest.java | 26 + .../v2/json/JWTTokenRequestFormatTest.java | 69 + .../jclouds/oauth/v2/parse/ParseTokenTest.java | 40 + .../firewall_list.json | 37 + .../network_get.json | 10 + .../src/test/resources/address_get.json | 12 + .../src/test/resources/address_insert.json | 1 + .../src/test/resources/address_list.json | 31 + .../test/resources/disk_create_snapshot.json | 1 + .../src/test/resources/disk_get.json | 10 + .../src/test/resources/disk_insert.json | 1 + .../src/test/resources/disk_list.json | 17 + .../src/test/resources/firewall_get.json | 30 + .../src/test/resources/firewall_insert.json | 1 + .../src/test/resources/firewall_list.json | 58 + .../src/test/resources/global_operation.json | 15 + .../test/resources/global_operation_list.json | 22 + .../src/test/resources/image_get.json | 13 + .../src/test/resources/image_insert.json | 4 + .../src/test/resources/image_list.json | 24 + .../src/test/resources/image_list_empty.json | 6 + .../resources/image_list_multiple_page_1.json | 55 + .../resources/image_list_multiple_page_2.json | 47 + .../test/resources/image_list_single_page.json | 50 + .../resources/instance_add_access_config.json | 11 + .../test/resources/instance_attach_disk.json | 6 + .../src/test/resources/instance_get.json | 62 + .../src/test/resources/instance_insert.json | 1 + .../test/resources/instance_insert_simple.json | 1 + .../src/test/resources/instance_list.json | 69 + .../instance_list_central1b_empty.json | 6 + .../test/resources/instance_serial_port.json | 4 + .../test/resources/instance_set_metadata.json | 10 + .../src/test/resources/logback.xml | 83 ++ .../src/test/resources/machinetype.json | 22 + .../src/test/resources/machinetype_list.json | 57 + .../resources/machinetype_list_central1b.json | 43 + .../machinetype_list_central1b_empty.json | 6 + .../src/test/resources/metadata.json | 1 + .../src/test/resources/network_get.json | 10 + .../src/test/resources/network_insert.json | 1 + .../src/test/resources/network_list.json | 18 + .../src/test/resources/operation.json | 17 + .../src/test/resources/operation_error.json | 26 + .../src/test/resources/operation_list.json | 24 + .../src/test/resources/project.json | 69 + .../1.8.0-stratos/src/test/resources/quota.json | 5 + .../src/test/resources/region_get.json | 60 + .../src/test/resources/region_list.json | 126 ++ .../src/test/resources/region_operation.json | 16 + .../test/resources/region_operation_list.json | 23 + .../src/test/resources/route_get.json | 14 + .../src/test/resources/route_insert.json | 1 + .../src/test/resources/route_list.json | 34 + .../src/test/resources/snapshot_get.json | 13 + .../src/test/resources/snapshot_list.json | 33 + .../src/test/resources/tag_insert.json | 1 + .../1.8.0-stratos/src/test/resources/testpk.pem | 15 + .../src/test/resources/tokenResponse.json | 5 + .../src/test/resources/zone_get.json | 17 + .../src/test/resources/zone_list.json | 41 + .../src/test/resources/zone_list_short.json | 24 + .../src/test/resources/zone_operation.json | 16 + .../test/resources/zone_operation_error.json | 25 + .../src/test/resources/zone_operation_list.json | 23 + dependencies/pom.xml | 1 + .../pom.xml | 6 + tools/puppet3-agent/config-gce.sh | 101 ++ tools/puppet3-agent/init-gce.sh | 146 +++ tools/stratos-installer/conf/setup.conf | 4 + .../all/repository/conf/cloud-controller.xml | 8 + tools/stratos-installer/ec2.sh | 2 + tools/stratos-installer/gce.sh | 67 + tools/stratos-installer/openstack.sh | 2 + tools/stratos-installer/setup.sh | 12 +- tools/stratos-installer/vcloud.sh | 2 + 298 files changed, 29468 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/components/org.apache.stratos.cloud.controller/pom.xml ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/pom.xml b/components/org.apache.stratos.cloud.controller/pom.xml index 59eaa46..c66dd7d 100644 --- a/components/org.apache.stratos.cloud.controller/pom.xml +++ b/components/org.apache.stratos.cloud.controller/pom.xml @@ -253,6 +253,11 @@ <artifactId>vcloud</artifactId> <version>1.8.0-stratos</version> </dependency> + <dependency> + <groupId>org.apache.stratos</groupId> + <artifactId>gce</artifactId> + <version>1.8.0-stratos</version> + </dependency> <dependency> <groupId>com.jamesmurty.utils.wso2</groupId> http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/GCEIaas.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/GCEIaas.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/GCEIaas.java new file mode 100644 index 0000000..78588df --- /dev/null +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/iaases/GCEIaas.java @@ -0,0 +1,464 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.stratos.cloud.controller.iaases; + +import java.io.File; +import java.io.IOException; +import java.util.*; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.cloud.controller.exception.CloudControllerException; +import org.apache.stratos.cloud.controller.interfaces.Iaas; +import org.apache.stratos.cloud.controller.jcloud.ComputeServiceBuilderUtil; +import org.apache.stratos.cloud.controller.pojo.IaasProvider; +import org.apache.stratos.cloud.controller.pojo.NetworkInterface; +import org.apache.stratos.cloud.controller.validate.GCEPartitionValidator; +import org.apache.stratos.cloud.controller.validate.interfaces.PartitionValidator; +import org.apache.stratos.cloud.controller.exception.InvalidHostException; +import org.apache.stratos.cloud.controller.exception.InvalidRegionException; +import org.apache.stratos.cloud.controller.exception.InvalidZoneException; +import org.jclouds.ContextBuilder; +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.compute.options.TemplateOptions; +import org.wso2.carbon.utils.CarbonUtils; +import org.jclouds.domain.Location; +import org.apache.stratos.cloud.controller.util.CloudControllerConstants; +import org.jclouds.collect.IterableWithMarker; +import org.jclouds.googlecomputeengine.GoogleComputeEngineApi; +import org.jclouds.googlecomputeengine.features.DiskApi; +import org.jclouds.googlecomputeengine.features.InstanceApi; +import org.jclouds.googlecomputeengine.features.RegionApi; +import org.jclouds.googlecomputeengine.features.ZoneApi; +import org.jclouds.googlecomputeengine.domain.Disk; +import org.jclouds.googlecomputeengine.domain.Instance; +import org.jclouds.googlecomputeengine.domain.Region; +import org.jclouds.googlecomputeengine.domain.Zone; +import org.jclouds.googlecomputeengine.domain.Operation; +import org.jclouds.googlecomputeengine.options.AttachDiskOptions; +import org.jclouds.googlecomputeengine.options.AttachDiskOptions.DiskType; +import com.google.inject.Key; +import com.google.inject.Injector; +import com.google.inject.TypeLiteral; +import com.google.inject.name.Names; +import static org.jclouds.util.Predicates2.retry; +import static java.util.concurrent.TimeUnit.SECONDS; +import com.google.common.base.Predicate; +import java.util.concurrent.atomic.AtomicReference; +import com.google.common.util.concurrent.Atomics; + +public class GCEIaas extends Iaas { + + + private static final Log log = LogFactory.getLog(GCEIaas.class); + + private static final String PROJECTNAME = "projectName"; + + public GCEIaas(IaasProvider iaasProvider) { + super(iaasProvider); + } + + @Override + public void buildComputeServiceAndTemplate() { + + IaasProvider iaasInfo = getIaasProvider(); + + // builds and sets Compute Service + ComputeServiceBuilderUtil.buildDefaultComputeService(iaasInfo); + + + // builds and sets Template + buildTemplate(); + + } + + public void buildTemplate() { + IaasProvider iaasInfo = getIaasProvider(); + + if (iaasInfo.getComputeService() == null) { + String msg = "Compute service is null for IaaS provider: " + + iaasInfo.getName(); + log.fatal(msg); + throw new CloudControllerException(msg); + } + + log.info("gce buildTemplate"); + + TemplateBuilder templateBuilder = iaasInfo.getComputeService() + .templateBuilder(); + + // set image id specified + templateBuilder.imageId(iaasInfo.getImage()); + + if(!(iaasInfo instanceof IaasProvider)) { + templateBuilder.locationId(iaasInfo.getType()); + } + + String zone = iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE); + if(zone != null) { + Set<? extends Location> locations = iaasInfo.getComputeService().listAssignableLocations(); + for(Location location : locations) { + if(location.getScope().toString().equalsIgnoreCase(CloudControllerConstants.ZONE_ELEMENT) && + location.getId().equals(zone)) { + templateBuilder.locationId(location.getId()); + log.info("ZONE has been set as " + zone + + " with id: " + location.getId()); + break; + } + } + } + + if (iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE) != null) { + // set instance type eg: m1.large + templateBuilder.hardwareId(iaasInfo.getProperty(CloudControllerConstants.INSTANCE_TYPE)); + } + + // build the Template + Template template = templateBuilder.build(); + + if(zone != null) { + if(!template.getLocation().getId().equals(zone)) { + log.warn("couldn't find assignable ZONE of id :" + zone + + " in the IaaS. Hence using the default location as " + template.getLocation().getScope().toString() + + " with the id " + template.getLocation().getId()); + } + } + + // if you wish to auto assign IPs, instance spawning call should be + // blocking, but if you + // wish to assign IPs manually, it can be non-blocking. + // is auto-assign-ip mode or manual-assign-ip mode? - default mode is + // non-blocking + boolean blockUntilRunning = Boolean.parseBoolean(iaasInfo + .getProperty("autoAssignIp")); + template.getOptions().as(TemplateOptions.class) + .blockUntilRunning(blockUntilRunning); + + // this is required in order to avoid creation of additional security + // groups by Jclouds. + template.getOptions().as(TemplateOptions.class) + .inboundPorts(22, 80, 8080, 443, 8243); + + if (zone != null) { + templateBuilder.locationId(zone); + log.debug("setting location to " + zone); + } + + // ability to define tags with Key-value pairs + Map<String, String> keyValuePairTagsMap = new HashMap<String, String>(); + + for (String propertyKey : iaasInfo.getProperties().keySet()){ + if(propertyKey.startsWith(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX)) { + keyValuePairTagsMap.put(propertyKey.substring(CloudControllerConstants.TAGS_AS_KEY_VALUE_PAIRS_PREFIX.length()), + iaasInfo.getProperties().get(propertyKey)); + template.getOptions() + .userMetadata(keyValuePairTagsMap); + } + log.info("usermeta data key:"+ propertyKey + " value: " + iaasInfo.getProperties().get(propertyKey)); + } + + if (iaasInfo.getNetworkInterfaces() != null) { + List<String> networks = new ArrayList<String>(iaasInfo.getNetworkInterfaces().length); + for (NetworkInterface ni:iaasInfo.getNetworkInterfaces()) { + networks.add(ni.getNetworkUuid()); + log.info("using network interface " + ni.getNetworkUuid()); + } + template.getOptions().as(TemplateOptions.class).networks(networks); + log.info("using network interface " + networks); + } + + // set Template + iaasInfo.setTemplate(template); + } + + @Override + public void setDynamicPayload() { + // in vCloud case we need to run a script + IaasProvider iaasInfo = getIaasProvider(); + + if (iaasInfo.getTemplate() == null || iaasInfo.getPayload() == null) { + if (log.isDebugEnabled()) { + log.debug("Payload for GCE not found"); + } + return; + } + + // Payload is a String value + String payload = new String(iaasInfo.getPayload()); + + log.info("setDynamicPayload " + payload); + + Map<String, String> keyValuePairTagsMap = new HashMap<String, String>(); + keyValuePairTagsMap.put("stratos_usermetadata", payload); + iaasInfo.getTemplate().getOptions().userMetadata(keyValuePairTagsMap); + } + + @Override + public boolean createKeyPairFromPublicKey(String region, String keyPairName, String publicKey) { + + // Not applicable for GCE - Not called by stratos cloud controller as well + return false; + } + + @Override + public String associateAddress(NodeMetadata node) { + + // TODO + return ""; + + } + + @Override + public String associatePredefinedAddress(NodeMetadata node, String ip) { + return ""; + } + + @Override + public void releaseAddress(String ip) { + // TODO + } + + @Override + public boolean isValidRegion(String region) throws InvalidRegionException { + IaasProvider iaasInfo = getIaasProvider(); + + if (region == null || iaasInfo == null) { + String msg = "Region or IaaSProvider is null: region: " + region + " - IaaSProvider: " + iaasInfo; + log.error(msg); + throw new InvalidRegionException(msg); + } + + GoogleComputeEngineApi api = getGCEApi(); + RegionApi regionApi = api.getRegionApiForProject(iaasInfo.getProperty(PROJECTNAME)); + + for(IterableWithMarker<Region> page : regionApi.list()) { + for(Region r : page) { + if (region.equalsIgnoreCase(r.getName())) { + log.debug("Found a matching region: " + region); + return true; + } + } + } + + String msg = "Invalid region: " + region +" in the iaas: "+iaasInfo.getType(); + log.error(msg); + throw new InvalidRegionException(msg); + } + + @Override + public boolean isValidZone(String region, String zone) throws InvalidZoneException { + IaasProvider iaasInfo = getIaasProvider(); + + if (zone == null || iaasInfo == null) { + String msg = "Zone or IaaSProvider is null: region: " + region + + " zone: " + zone + " - IaaSProvider: " + iaasInfo; + log.error(msg); + throw new InvalidZoneException(msg); + } + + GoogleComputeEngineApi api = getGCEApi(); + ZoneApi zoneApi = api.getZoneApiForProject(iaasInfo.getProperty(PROJECTNAME)); + + for(IterableWithMarker<Zone> page : zoneApi.list()) { + for(Zone z : page) { + if (zone.equalsIgnoreCase(z.getName())) { + log.debug("Found a matching zone: " + zone); + return true; + } + } + } + + String msg = "Invalid zone: " + zone + " in the region: " + region + " and of the iaas: " + iaasInfo.getType(); + log.error(msg); + throw new InvalidZoneException(msg); + } + + @Override + public boolean isValidHost(String zone, String host) throws InvalidHostException { + IaasProvider iaasInfo = getIaasProvider(); + + // Not called by cloud controller + // there's no such concept in GCE + + String msg = "Invalid host: " + host + " in the zone: " + zone + " and of the iaas: " + iaasInfo.getType(); + log.error(msg); + throw new InvalidHostException(msg); + } + + @Override + public PartitionValidator getPartitionValidator() { + return new GCEPartitionValidator(); + } + + @Override + public String createVolume(int sizeGB, String snapshotId) { + // generate a random diskname + Random rand = new Random(); + String diskName = "stratos-disk-" + rand.nextInt(100000); + DiskApi diskApi = getGCEDiskApi(); + String zone = getZone(); + + log.debug("Creating volume: " + diskName + " in zone: " + zone + " of size: " + sizeGB); + + Operation oper = diskApi.createInZone(diskName, sizeGB, zone); + + oper = waitGCEOperationDone(oper); + if (oper.getStatus() != Operation.Status.DONE) { + log.error("Failed to create volume: " + diskName + " of size: " + sizeGB + + " in zone: " + zone + " operation: " + oper); + return null; + } + + return diskName; + } + + @Override + public String attachVolume(String instanceId, String volumeId, String deviceName) { + DiskApi diskApi = getGCEDiskApi(); + InstanceApi instApi = getGCEInstanceApi(); + String zone = getZone(); + + log.debug("Trying to attach volume: " + volumeId + " to instance: " + instanceId + + " in zone: " + zone + " at devicename: " + deviceName); + + Disk disk = diskApi.getInZone(zone, volumeId); + if (disk == null) { + log.error("Failed to get volume: " + volumeId + " in zone: " + zone); + return null; + } + + log.debug("Found volumeId: " + volumeId + " volume: " + disk); + + Operation oper = instApi.attachDiskInZone(zone, instanceId, + new AttachDiskOptions().type(DiskType.PERSISTENT) + .source(disk.getSelfLink()) + .mode(AttachDiskOptions.DiskMode.READ_WRITE) + .deviceName(deviceName)); + oper = waitGCEOperationDone(oper); + if (oper.getStatus() != Operation.Status.DONE) { + log.error("Failed to attach volume: " + volumeId + " to instance: " + instanceId + + " in zone: " + zone + " at device: " + deviceName + " operation: " + oper); + return null; + } + + return volumeId; + } + + @Override + public void detachVolume(String instanceId, String volumeId) { + DiskApi diskApi = getGCEDiskApi(); + InstanceApi instApi = getGCEInstanceApi(); + String zone = getZone(); + Instance inst = instApi.getInZone(zone, instanceId); + + log.debug("Trying to detach volume: " + volumeId + " from instance: " + instanceId + + " " + inst + " in zone: " + zone); + + if (inst == null) { + log.error("Failed to find instance: " + instanceId + " in zone: " + zone); + return; + } + + for(Instance.AttachedDisk disk : inst.getDisks()) { + Instance.PersistentAttachedDisk persistentDisk = (Instance.PersistentAttachedDisk)disk; + + log.debug("Found disk - src: " + persistentDisk.getSourceDiskName() + + " devicename: " + persistentDisk.getDeviceName()); + + if (persistentDisk.getSourceDiskName().equals(volumeId)) { + Operation oper = instApi.detachDiskInZone(zone, instanceId, persistentDisk.getDeviceName().get()); + oper = waitGCEOperationDone(oper); + if (oper.getStatus() != Operation.Status.DONE) { + log.error("Failed to detach volume: " + volumeId + " to instance: " + instanceId + + " in zone: " + zone + " at device: " + persistentDisk.getDeviceName() + + " result operation: " + oper); + } + return; + } + } + + log.error("Cannot find volume: " + volumeId + " in instance: " + instanceId); + } + + @Override + public void deleteVolume(String volumeId) { + DiskApi diskApi = getGCEDiskApi(); + String zone = getZone(); + + log.debug("Deleting volume: " + volumeId + " in zone: " + zone); + + Operation oper = diskApi.deleteInZone(zone, volumeId); + + oper = waitGCEOperationDone(oper); + if (oper.getStatus() != Operation.Status.DONE) { + log.error("Failed to delete volume: " + volumeId + " in zone: " + zone + + " operation: " + oper); + } + } + + @Override + public String getIaasDevice(String device) { + return device; + } + + private String getZone() { + IaasProvider iaasInfo = getIaasProvider(); + return iaasInfo.getProperty(CloudControllerConstants.AVAILABILITY_ZONE); + } + + private GoogleComputeEngineApi getGCEApi() { + IaasProvider iaasInfo = getIaasProvider(); + ComputeServiceContext context = iaasInfo.getComputeService().getContext(); + GoogleComputeEngineApi api = context.unwrapApi(GoogleComputeEngineApi.class); + + return api; + } + + private DiskApi getGCEDiskApi() { + IaasProvider iaasInfo = getIaasProvider(); + String projectName = iaasInfo.getProperty(PROJECTNAME); + return getGCEApi().getDiskApiForProject(projectName); + } + + private InstanceApi getGCEInstanceApi() { + IaasProvider iaasInfo = getIaasProvider(); + String projectName = iaasInfo.getProperty(PROJECTNAME); + return getGCEApi().getInstanceApiForProject(projectName); + } + + private Operation waitGCEOperationDone(Operation operation) { + int maxWaitTime = 15; // 15 seconds + IaasProvider iaasInfo = getIaasProvider(); + Injector injector = ContextBuilder.newBuilder(iaasInfo.getProvider()) + .credentials(iaasInfo.getIdentity(), iaasInfo.getCredential()) + .buildInjector(); + Predicate<AtomicReference<Operation>> zoneOperationDonePredicate = + injector.getInstance(Key.get(new TypeLiteral<Predicate<AtomicReference<Operation>>>() { + }, Names.named("zone"))); + AtomicReference<Operation> operationReference = Atomics.newReference(operation); + retry(zoneOperationDonePredicate, maxWaitTime, 1, SECONDS).apply(operationReference); + + return operationReference.get(); + } +} + http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/validate/GCEPartitionValidator.java ---------------------------------------------------------------------- diff --git a/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/validate/GCEPartitionValidator.java b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/validate/GCEPartitionValidator.java new file mode 100644 index 0000000..7d07d40 --- /dev/null +++ b/components/org.apache.stratos.cloud.controller/src/main/java/org/apache/stratos/cloud/controller/validate/GCEPartitionValidator.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.stratos.cloud.controller.validate; + +import java.util.Properties; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.stratos.cloud.controller.exception.InvalidPartitionException; +import org.apache.stratos.cloud.controller.interfaces.Iaas; +import org.apache.stratos.cloud.controller.pojo.IaasProvider; +import org.apache.stratos.cloud.controller.validate.interfaces.PartitionValidator; + + +/** + * The VCloud {@link PartitionValidator} implementation. + * + */ +public class GCEPartitionValidator implements PartitionValidator { + + private static final Log log = LogFactory.getLog(VCloudPartitionValidator.class); + private IaasProvider iaasProvider; + private Iaas iaas; + + @Override + public IaasProvider validate(String partitionId, Properties properties) throws InvalidPartitionException { + //TODO: implement real validation logic + return iaasProvider; + + } + + @Override + public void setIaasProvider(IaasProvider iaas) { + this.iaasProvider = iaas; + this.iaas = iaas.getIaas(); + } + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/README.txt ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/gce/1.8.0-stratos/README.txt b/dependencies/jclouds/apis/gce/1.8.0-stratos/README.txt new file mode 100644 index 0000000..a6ca119 --- /dev/null +++ b/dependencies/jclouds/apis/gce/1.8.0-stratos/README.txt @@ -0,0 +1,77 @@ +====== +Stratos GCE provider 1.8.0 +====== + +This code in Stratos is copied from Jclouds GCE [1] +The jclouds GCE code has 2 directories oauth & google-compute-engine +In Stratos, these two directories are mered into one. + +[1] https://github.com/jclouds/jclouds-labs-google/tree/jclouds-labs-google-1.8.0 + + + + +====== +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>[email protected]</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 + http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/pom.xml ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/gce/1.8.0-stratos/pom.xml b/dependencies/jclouds/apis/gce/1.8.0-stratos/pom.xml new file mode 100644 index 0000000..7874da1 --- /dev/null +++ b/dependencies/jclouds/apis/gce/1.8.0-stratos/pom.xml @@ -0,0 +1,135 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +--> +<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.apache.jclouds.labs</groupId> + <artifactId>jclouds-labs-google</artifactId> + <version>1.8.0</version> + </parent> + + <!-- TODO: when out of labs, switch to org.jclouds.provider --> + <groupId>org.apache.stratos</groupId> + <artifactId>gce</artifactId> + <version>1.8.0-stratos</version> + <name>jclouds Google Compute Engine provider</name> + <description>jclouds components to access GoogleCompute</description> + <packaging>bundle</packaging> + + <properties> + <jclouds.version>1.8.0</jclouds.version> + <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>v1</test.google-compute-engine.api-version> + <test.google-compute-engine.build-version /> + <test.google-compute-engine.template>imageId=debian-7-wheezy-v20131120,locationId=us-central1-a,minRam=2048</test.google-compute-engine.template> + <jclouds.osgi.export>org.jclouds.googlecomputeengine*;version="${project.version}"</jclouds.osgi.export> + <jclouds.osgi.import> + org.jclouds.compute.internal;version="${jclouds.version}", + org.jclouds.rest.internal;version="${jclouds.version}", + org.jclouds*;version="${jclouds.version}", + * + </jclouds.osgi.import> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.jclouds</groupId> + <artifactId>jclouds-core</artifactId> + <version>${jclouds.version}</version> + </dependency> + <dependency> + <groupId>org.apache.jclouds</groupId> + <artifactId>jclouds-compute</artifactId> + <version>${jclouds.version}</version> + </dependency> + <dependency> + <groupId>org.apache.jclouds</groupId> + <artifactId>jclouds-compute</artifactId> + <version>${jclouds.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.jclouds</groupId> + <artifactId>jclouds-core</artifactId> + <version>${jclouds.version}</version> + <type>test-jar</type> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.jclouds.driver</groupId> + <artifactId>jclouds-slf4j</artifactId> + <version>${jclouds.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.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> + <test.google-compute-engine.template>${test.google-compute-engine.template}</test.google-compute-engine.template> + </systemPropertyVariables> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> +</project> http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java new file mode 100644 index 0000000..6440d91 --- /dev/null +++ b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApi.java @@ -0,0 +1,185 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.googlecomputeengine; + +import java.io.Closeable; + +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; + +import org.jclouds.googlecomputeengine.features.AddressApi; +import org.jclouds.googlecomputeengine.features.DiskApi; +import org.jclouds.googlecomputeengine.features.FirewallApi; +import org.jclouds.googlecomputeengine.features.GlobalOperationApi; +import org.jclouds.googlecomputeengine.features.ImageApi; +import org.jclouds.googlecomputeengine.features.InstanceApi; +import org.jclouds.googlecomputeengine.features.MachineTypeApi; +import org.jclouds.googlecomputeengine.features.NetworkApi; +import org.jclouds.googlecomputeengine.features.ProjectApi; +import org.jclouds.googlecomputeengine.features.RegionApi; +import org.jclouds.googlecomputeengine.features.RegionOperationApi; +import org.jclouds.googlecomputeengine.features.RouteApi; +import org.jclouds.googlecomputeengine.features.SnapshotApi; +import org.jclouds.googlecomputeengine.features.ZoneApi; +import org.jclouds.googlecomputeengine.features.ZoneOperationApi; +import org.jclouds.rest.annotations.Delegate; + +import com.google.common.annotations.Beta; + + +/** + * Provides access to GoogleCompute. + * <p/> + * + * @see <a href="https://developers.google.com/compute/docs/reference/v1">api doc</a> + */ +@Beta +public interface GoogleComputeEngineApi extends Closeable { + + /** + * Provides access to Address features + * + * @param projectName the name of the project + */ + @Delegate + @Path("/projects/{project}") + AddressApi getAddressApiForProject(@PathParam("project") String projectName); + + /** + * 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 Global Operation features + * + * @param projectName the name of the project + */ + @Delegate + @Path("/projects/{project}") + GlobalOperationApi getGlobalOperationApiForProject(@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 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 Project features + */ + @Delegate + ProjectApi getProjectApi(); + + /** + * Provides access to Region features + * + * @param projectName the name of the project + */ + @Delegate + @Path("/projects/{project}") + RegionApi getRegionApiForProject(@PathParam("project") String projectName); + + /** + * Provides access to Region Operation features + * + * @param projectName the name of the project + */ + @Delegate + @Path("/projects/{project}") + RegionOperationApi getRegionOperationApiForProject(@PathParam("project") String projectName); + + /** + * Provides access to Route features + * + * @param projectName the name of the project + */ + @Delegate + @Path("/projects/{project}") + RouteApi getRouteApiForProject(@PathParam("project") String projectName); + + /** + * Provides access to Snapshot features + * + * @param projectName the name of the project + */ + @Delegate + @Path("/projects/{project}") + SnapshotApi getSnapshotApiForProject(@PathParam("project") String projectName); + + /** + * Provides access to Zone features + * + * @param projectName the name of the project + */ + @Delegate + @Path("/projects/{project}") + ZoneApi getZoneApiForProject(@PathParam("project") String projectName); + + /** + * Provides access to Zone Operation features + * + * @param projectName the name of the project + */ + @Delegate + @Path("/projects/{project}") + ZoneOperationApi getZoneOperationApiForProject(@PathParam("project") String projectName); + +} http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java new file mode 100644 index 0000000..1527529 --- /dev/null +++ b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineApiMetadata.java @@ -0,0 +1,104 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.googlecomputeengine; + +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.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 v1 API + */ +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("v1") + .defaultEndpoint("https://www.googleapis.com/compute/v1") + .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; + } + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java new file mode 100644 index 0000000..d20ff98 --- /dev/null +++ b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/GoogleComputeEngineConstants.java @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.googlecomputeengine; + +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; + +import com.google.common.annotations.Beta; + +public final class 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 CENTOS_PROJECT = "centos-cloud"; + + public static final String DEBIAN_PROJECT = "debian-cloud"; + + 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"; + + public static final String STORAGE_READONLY_SCOPE = "https://www.googleapis.com/auth/devstorage.read_only"; + + public static final String STORAGE_WRITEONLY_SCOPE = "https://www.googleapis.com/auth/devstorage.write_only"; + + + /** + * 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(); + + + /** + * The key we look for in instance metadata for the URI for the image the instance was created from. + */ + public static final String GCE_IMAGE_METADATA_KEY = "jclouds-image"; + + /** + * Metadata key to check for whether we should delete an instance's boot disk when we delete the instance. + */ + public static final String GCE_DELETE_BOOT_DISK_METADATA_KEY = "jclouds-delete-boot-disk"; + + /** + * The suffix we append to auto-created boot disk names. + */ + public static final String GCE_BOOT_DISK_SUFFIX = "boot-disk"; + + private GoogleComputeEngineConstants() { + throw new AssertionError("intentionally unimplemented"); + } +} http://git-wip-us.apache.org/repos/asf/stratos/blob/4203d59b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java ---------------------------------------------------------------------- diff --git a/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java new file mode 100644 index 0000000..3c140eb --- /dev/null +++ b/dependencies/jclouds/apis/gce/1.8.0-stratos/src/main/java/org/jclouds/googlecomputeengine/compute/GoogleComputeEngineService.java @@ -0,0 +1,200 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jclouds.googlecomputeengine.compute; + +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; + +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; + +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.extensions.SecurityGroupExtension; +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.Firewall; +import org.jclouds.googlecomputeengine.domain.Network; +import org.jclouds.googlecomputeengine.domain.Operation; +import org.jclouds.googlecomputeengine.features.FirewallApi; +import org.jclouds.http.HttpResponse; +import org.jclouds.scriptbuilder.functions.InitAdminAccess; + +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.Sets; +import com.google.common.util.concurrent.Atomics; +import com.google.common.util.concurrent.ListeningExecutorService; + +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, + Optional<SecurityGroupExtension> securityGroupExtension, + Function<Set<? extends NodeMetadata>, Set<String>> findOrphanedGroups, + GroupNamingConvention.Factory namingConvention, + GoogleComputeEngineApi api, + @UserProject Supplier<String> project, + @Named("global") 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, securityGroupExtension); + 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(final String groupName) { + String resourceName = namingConvention.create().sharedNameForGroup(groupName); + final Network network = api.getNetworkApiForProject(project.get()).get(resourceName); + FirewallApi firewallApi = api.getFirewallApiForProject(project.get()); + Predicate<Firewall> firewallBelongsToNetwork = new Predicate<Firewall>() { + @Override + public boolean apply(Firewall input) { + return input != null && input.getNetwork().equals(network.getSelfLink()); + } + }; + + Set<AtomicReference<Operation>> operations = Sets.newHashSet(); + for (Firewall firewall : firewallApi.list().concat().filter(firewallBelongsToNetwork)) { + operations.add(new AtomicReference<Operation>(firewallApi.delete(firewall.getName()))); + } + + for (AtomicReference<Operation> operation : operations) { + retry(operationDonePredicate, operationCompleteCheckTimeout, operationCompleteCheckInterval, + MILLISECONDS).apply(operation); + + if (operation.get().getHttpError().isPresent()) { + HttpResponse response = operation.get().getHttpError().get(); + logger.warn("delete orphaned firewall %s failed. Http Error Code: %d HttpError: %s", + operation.get().getTargetId(), response.getStatusCode(), response.getMessage()); + } + } + + AtomicReference<Operation> operation = Atomics.newReference(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()); + } +}
