From 19ff2eb89b9414e095a2fed1a41459e63a804000 Mon Sep 17 00:00:00 2001 From: Adrian Cole Date: Tue, 31 Jan 2012 01:31:21 -0800 Subject: [PATCH] implemented first cut of glesys computeservice --- .../jclouds/glesys/GleSYSContextBuilder.java | 10 +- .../compute/GleSYSComputeServiceAdapter.java | 219 ++++++++++++++++++ .../GleSYSComputeServiceContextModule.java | 112 +++++++++ .../functions/DatacenterToLocation.java | 52 +++++ .../functions/FindLocationForServerSpec.java | 48 ++++ .../compute/functions/OSTemplateToImage.java | 57 +++++ ...arseOsFamilyVersion64BitFromImageName.java | 74 ++++++ .../ServerDetailsToNodeMetadata.java | 150 ++++++++++++ .../functions/ServerSpecToHardware.java | 59 +++++ .../options/GleSYSTemplateOptions.java | 201 ++++++++++++++++ ...GleSYSComputeServiceAdapterExpectTest.java | 46 ++++ .../compute/GleSYSComputeServiceLiveTest.java | 60 +++++ .../compute/GleSYSExperimentExpectTest.java | 49 ++++ .../compute/GleSYSExperimentLiveTest.java | 59 +++++ .../GleSYSTemplateBuilderLiveTest.java | 97 ++++++++ ...OsFamilyVersion64BitFromImageNameTest.java | 80 +++++++ .../functions/ServerSpecToHardwareTest.java | 39 ++++ .../BaseGleSYSComputeServiceExpectTest.java | 92 ++++++++ .../options/GleSYSTemplateOptionsTest.java | 64 +++++ .../features/ServerClientExpectTest.java | 14 +- .../glesys/features/ServerClientLiveTest.java | 34 +-- .../internal/BaseGleSYSClientLiveTest.java | 24 +- .../glesys/src/test/resources/osmatches.json | 48 ++++ 23 files changed, 1650 insertions(+), 38 deletions(-) create mode 100644 sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java create mode 100644 sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/config/GleSYSComputeServiceContextModule.java create mode 100644 sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/DatacenterToLocation.java create mode 100644 sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/FindLocationForServerSpec.java create mode 100644 sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/OSTemplateToImage.java create mode 100644 sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/ParseOsFamilyVersion64BitFromImageName.java create mode 100644 sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/ServerDetailsToNodeMetadata.java create mode 100644 sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/ServerSpecToHardware.java create mode 100644 sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptions.java create mode 100644 sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapterExpectTest.java create mode 100644 sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSComputeServiceLiveTest.java create mode 100644 sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSExperimentExpectTest.java create mode 100644 sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSExperimentLiveTest.java create mode 100644 sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSTemplateBuilderLiveTest.java create mode 100644 sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/functions/ParseOsFamilyVersion64BitFromImageNameTest.java create mode 100644 sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/functions/ServerSpecToHardwareTest.java create mode 100644 sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/internal/BaseGleSYSComputeServiceExpectTest.java create mode 100644 sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptionsTest.java create mode 100644 sandbox-providers/glesys/src/test/resources/osmatches.json diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/GleSYSContextBuilder.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/GleSYSContextBuilder.java index 8d6bf6b1af..1b093e8388 100644 --- a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/GleSYSContextBuilder.java +++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/GleSYSContextBuilder.java @@ -21,8 +21,9 @@ package org.jclouds.glesys; import java.util.List; import java.util.Properties; +import org.jclouds.compute.ComputeServiceContextBuilder; +import org.jclouds.glesys.compute.config.GleSYSComputeServiceContextModule; import org.jclouds.glesys.config.GleSYSRestClientModule; -import org.jclouds.rest.RestContextBuilder; import com.google.inject.Module; @@ -30,12 +31,17 @@ import com.google.inject.Module; * * @author Adrian Cole */ -public class GleSYSContextBuilder extends RestContextBuilder { +public class GleSYSContextBuilder extends ComputeServiceContextBuilder { public GleSYSContextBuilder(Properties props) { super(GleSYSClient.class, GleSYSAsyncClient.class, props); } + @Override + protected void addContextModule(List modules) { + modules.add(new GleSYSComputeServiceContextModule()); + } + @Override protected void addClientModule(List modules) { modules.add(new GleSYSRestClientModule()); diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java new file mode 100644 index 0000000000..b4683f0c89 --- /dev/null +++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapter.java @@ -0,0 +1,219 @@ +/** + * 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.glesys.compute; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.Set; +import java.util.Map.Entry; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; +import javax.inject.Singleton; + +import org.jclouds.collect.FindResourceInSet; +import org.jclouds.collect.Memoized; +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.ComputeServiceAdapter; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.HardwareBuilder; +import org.jclouds.compute.domain.Processor; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.Volume; +import org.jclouds.compute.domain.internal.VolumeImpl; +import org.jclouds.compute.predicates.ImagePredicates; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.domain.Location; +import org.jclouds.domain.LoginCredentials; +import org.jclouds.glesys.GleSYSClient; +import org.jclouds.glesys.compute.options.GleSYSTemplateOptions; +import org.jclouds.glesys.domain.AllowedArgumentsForCreateServer; +import org.jclouds.glesys.domain.OSTemplate; +import org.jclouds.glesys.domain.ServerDetails; +import org.jclouds.glesys.domain.ServerSpec; +import org.jclouds.glesys.options.CreateServerOptions; +import org.jclouds.glesys.options.DestroyServerOptions; +import org.jclouds.location.predicates.LocationPredicates; +import org.jclouds.logging.Logger; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Iterables; + +/** + * defines the connection between the {@link GleSYSClient} implementation and the jclouds + * {@link ComputeService} + * + */ +@Singleton +public class GleSYSComputeServiceAdapter implements ComputeServiceAdapter { + + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + protected Logger logger = Logger.NULL; + + private final GleSYSClient client; + private final Supplier> locations; + private final Provider passwordProvider; + + @Inject + public GleSYSComputeServiceAdapter(GleSYSClient client, @Memoized Supplier> locations, + @Named("PASSWORD") Provider passwordProvider) { + this.client = checkNotNull(client, "client"); + this.locations = checkNotNull(locations, "locations"); + this.passwordProvider = checkNotNull(passwordProvider, "passwordProvider"); + } + + @Override + public NodeAndInitialCredentials createNodeWithGroupEncodedIntoName(String group, String name, + Template template) { + checkNotNull(template, "template was null"); + checkNotNull(template.getOptions(), "template options was null"); + checkArgument(template.getOptions().getClass().isAssignableFrom(GleSYSTemplateOptions.class), + "options class %s should have been assignable from GleSYSTemplateOptions", template.getOptions() + .getClass()); + + GleSYSTemplateOptions templateOptions = template.getOptions().as(GleSYSTemplateOptions.class); + + CreateServerOptions createServerOptions = new CreateServerOptions(); + createServerOptions.ip(templateOptions.getIp()); + + createServerOptions.description(name); // TODO: add to templateOptions and set if present + + ServerSpec.Builder builder = ServerSpec.builder(); + builder.datacenter(template.getLocation().getId()); + builder.platform(template.getHardware().getHypervisor()); + builder.diskSizeGB(Math.round(template.getHardware().getVolumes().get(0).getSize())); + builder.cpuCores((int) template.getHardware().getProcessors().get(0).getCores()); + builder.transferGB(50);// TODO: add to template options with default value + ServerSpec spec = builder.build(); + + String password = passwordProvider.get(); // TODO: add to templateOptions and set if present + + logger.debug(">> creating new Server spec(%s) name(%s) options(%s)", spec, name, createServerOptions); + ServerDetails result = client.getServerClient().createServerWithHostnameAndRootPassword(spec, name, password, + createServerOptions); + logger.trace("<< ServerDetails(%s)", result.getId()); + + return new NodeAndInitialCredentials(result, result.getId() + "", LoginCredentials.builder() + .password(password).build()); + } + + @Singleton + public static class FindLocationForServerSpec extends FindResourceInSet { + + @Inject + public FindLocationForServerSpec(@Memoized Supplier> location) { + super(location); + } + + @Override + public boolean matches(ServerSpec from, Location input) { + return input.getId().equals(from.getDatacenter()); + } + } + + @Override + public Iterable listHardwareProfiles() { + Set locationsSet = locations.get(); + ImmutableSet.Builder hardwareToReturn = ImmutableSet. builder(); + + // do this loop after dupes are filtered, else OOM + Set images = listImages(); + + for (Entry platformToArgs : client.getServerClient() + .getAllowedArgumentsForCreateServerByPlatform().entrySet()) + for (String datacenter : platformToArgs.getValue().getDataCenters()) + for (int diskSizeGB : platformToArgs.getValue().getDiskSizesInGB()) + for (int cpuCores : platformToArgs.getValue().getCpuCoreOptions()) + for (int memorySizeMB : platformToArgs.getValue().getMemorySizesInMB()) { + ImmutableSet.Builder templatesSupportedBuilder = ImmutableSet. builder(); + for (OSTemplate template : images) { + if (diskSizeGB >= template.getMinDiskSize() && memorySizeMB >= template.getMinMemSize()) + templatesSupportedBuilder.add(template.getName()); + } + ImmutableSet templatesSupported = templatesSupportedBuilder.build(); + if (templatesSupported.size() > 0) + hardwareToReturn.add(new HardwareBuilder().ids( + String.format("datacenter(%s)platform(%s)cpuCores(%d)memorySizeMB(%d)diskSizeGB(%d)", + datacenter, platformToArgs.getKey(), cpuCores, cpuCores, diskSizeGB)).ram( + memorySizeMB).processors(ImmutableList.of(new Processor(cpuCores, 1.0))).volumes( + ImmutableList. of(new VolumeImpl((float) diskSizeGB, true, true))).hypervisor( + platformToArgs.getKey()).location( + Iterables.find(locationsSet, LocationPredicates.idEquals(datacenter))).supportsImage( + ImagePredicates.idIn(templatesSupported)).build()); + } + + return hardwareToReturn.build(); + } + + @Override + public Set listImages() { + return client.getServerClient().listTemplates(); + } + + @Override + public Iterable listNodes() { + return ImmutableSet.of(); + } + + @Override + public Set listLocations() { + return ImmutableSet.copyOf(Iterables.concat(Iterables.transform(client.getServerClient() + .getAllowedArgumentsForCreateServerByPlatform().values(), + new Function>() { + + @Override + public Set apply(AllowedArgumentsForCreateServer arg0) { + return arg0.getDataCenters(); + } + + }))); + } + + @Override + public ServerDetails getNode(String id) { + return client.getServerClient().getServerDetails(id); + } + + @Override + public void destroyNode(String id) { + client.getServerClient().destroyServer(id, DestroyServerOptions.Builder.discardIp()); + } + + @Override + public void rebootNode(String id) { + client.getServerClient().rebootServer(id); + } + + @Override + public void resumeNode(String id) { + client.getServerClient().startServer(id); + } + + @Override + public void suspendNode(String id) { + client.getServerClient().stopServer(id); + } +} \ No newline at end of file diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/config/GleSYSComputeServiceContextModule.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/config/GleSYSComputeServiceContextModule.java new file mode 100644 index 0000000000..696d38e3b1 --- /dev/null +++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/config/GleSYSComputeServiceContextModule.java @@ -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.glesys.compute.config; + +import java.security.SecureRandom; + +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Provider; +import javax.inject.Singleton; + +import org.jclouds.compute.ComputeServiceAdapter; +import org.jclouds.compute.config.ComputeServiceAdapterContextModule; +import org.jclouds.compute.domain.Hardware; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.OsFamily; +import org.jclouds.compute.domain.OsFamilyVersion64Bit; +import org.jclouds.compute.domain.TemplateBuilder; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.domain.Location; +import org.jclouds.functions.IdentityFunction; +import org.jclouds.glesys.GleSYSAsyncClient; +import org.jclouds.glesys.GleSYSClient; +import org.jclouds.glesys.compute.GleSYSComputeServiceAdapter; +import org.jclouds.glesys.compute.functions.DatacenterToLocation; +import org.jclouds.glesys.compute.functions.OSTemplateToImage; +import org.jclouds.glesys.compute.functions.ParseOsFamilyVersion64BitFromImageName; +import org.jclouds.glesys.compute.functions.ServerDetailsToNodeMetadata; +import org.jclouds.glesys.compute.options.GleSYSTemplateOptions; +import org.jclouds.glesys.domain.OSTemplate; +import org.jclouds.glesys.domain.ServerDetails; +import org.jclouds.location.suppliers.OnlyLocationOrFirstZone; + +import com.google.common.base.Function; +import com.google.common.base.Supplier; +import com.google.inject.Injector; +import com.google.inject.Scopes; +import com.google.inject.TypeLiteral; +import com.google.inject.name.Names; + +/** + * + * @author Adrian Cole + */ +public class GleSYSComputeServiceContextModule + extends + ComputeServiceAdapterContextModule { + + public GleSYSComputeServiceContextModule() { + super(GleSYSClient.class, GleSYSAsyncClient.class); + } + + @SuppressWarnings("unchecked") + @Override + protected void configure() { + super.configure(); + bind(new TypeLiteral>() { + }).to(GleSYSComputeServiceAdapter.class); + bind(new TypeLiteral>() { + }).to(ServerDetailsToNodeMetadata.class); + bind(new TypeLiteral>() { + }).to(OSTemplateToImage.class); + bind(new TypeLiteral>() { + }).to((Class) IdentityFunction.class); + bind(new TypeLiteral>() { + }).to(DatacenterToLocation.class); + bind(new TypeLiteral>() { + }).to(ParseOsFamilyVersion64BitFromImageName.class); + bind(new TypeLiteral>() { + }).to(OnlyLocationOrFirstZone.class); + bind(TemplateOptions.class).to(GleSYSTemplateOptions.class); + bind(String.class).annotatedWith(Names.named("PASSWORD")).toProvider(PasswordProvider.class).in(Scopes.SINGLETON); + } + + // 128MB is perhaps too little ram + @Override + protected TemplateBuilder provideTemplate(Injector injector, TemplateBuilder template) { + return template.minRam(512).osFamily(OsFamily.UBUNTU).osVersionMatches("1[10].[10][04]").os64Bit(true); + } + + @Named("PASSWORD") + @Singleton + public static class PasswordProvider implements Provider { + private final SecureRandom random; + + @Inject + protected PasswordProvider() { + this.random = new SecureRandom(); + } + + @Override + public String get() { + return random.nextLong() + ""; + } + } +} \ No newline at end of file diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/DatacenterToLocation.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/DatacenterToLocation.java new file mode 100644 index 0000000000..701335b71e --- /dev/null +++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/DatacenterToLocation.java @@ -0,0 +1,52 @@ +/** + * 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.glesys.compute.functions; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.inject.Inject; + +import org.jclouds.domain.Location; +import org.jclouds.domain.LocationBuilder; +import org.jclouds.domain.LocationScope; +import org.jclouds.location.suppliers.JustProvider; + +import com.google.common.base.Function; +import com.google.common.collect.Iterables; + +/** + * Converts an ServerSpec into a Location. + */ +public class DatacenterToLocation implements Function { + private final JustProvider provider; + + // allow us to lazy discover the provider of a resource + @Inject + public DatacenterToLocation(JustProvider provider) { + this.provider = checkNotNull(provider, "provider"); + } + + @Override + public Location apply(String datacenter) { + return new LocationBuilder().scope(LocationScope.ZONE).description(datacenter).id(datacenter) + // TODO: iso3166Codes + .parent(Iterables.getOnlyElement(provider.get())).build(); + } + +} diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/FindLocationForServerSpec.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/FindLocationForServerSpec.java new file mode 100644 index 0000000000..f2c51cb009 --- /dev/null +++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/FindLocationForServerSpec.java @@ -0,0 +1,48 @@ +/** + * 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.glesys.compute.functions; + +import java.util.Set; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.collect.FindResourceInSet; +import org.jclouds.collect.Memoized; +import org.jclouds.domain.Location; +import org.jclouds.glesys.domain.ServerSpec; + +import com.google.common.base.Supplier; + +/** + * @author Adrian Cole + */ +@Singleton +public class FindLocationForServerSpec extends FindResourceInSet { + + @Inject + public FindLocationForServerSpec(@Memoized Supplier> location) { + super(location); + } + + @Override + public boolean matches(ServerSpec from, Location input) { + return input.getId().equals(from.getDatacenter()); + } +} \ No newline at end of file diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/OSTemplateToImage.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/OSTemplateToImage.java new file mode 100644 index 0000000000..8552bfd615 --- /dev/null +++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/OSTemplateToImage.java @@ -0,0 +1,57 @@ +/** + * 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 + * templateific language governing permissions and limitations + * under the License. + */ +package org.jclouds.glesys.compute.functions; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.ImageBuilder; +import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.domain.OsFamilyVersion64Bit; +import org.jclouds.compute.domain.OperatingSystem.Builder; +import org.jclouds.glesys.domain.OSTemplate; + +import com.google.common.base.Function; + +/** + * @author Adrian Cole + */ +@Singleton +public class OSTemplateToImage implements Function { + private final Function imageParser; + + @Inject + public OSTemplateToImage(Function imageParser) { + this.imageParser = imageParser; + } + + @Override + public Image apply(OSTemplate template) { + checkNotNull(template, "template"); + OsFamilyVersion64Bit parsed = imageParser.apply(template.getName()); + Builder builder = OperatingSystem.builder(); + builder.name(template.getName()).description(template.getName()).is64Bit(parsed.is64Bit).version(parsed.version) + .family(parsed.family); + return new ImageBuilder().ids(template.getName()).description(template.getName()) + .operatingSystem(builder.build()).build(); + } +} diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/ParseOsFamilyVersion64BitFromImageName.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/ParseOsFamilyVersion64BitFromImageName.java new file mode 100644 index 0000000000..847d5d825d --- /dev/null +++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/ParseOsFamilyVersion64BitFromImageName.java @@ -0,0 +1,74 @@ +/** + * 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.glesys.compute.functions; + +import static com.google.common.base.Predicates.containsPattern; + +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.inject.Inject; +import javax.inject.Singleton; + +import org.jclouds.compute.domain.OsFamily; +import org.jclouds.compute.domain.OsFamilyVersion64Bit; +import org.jclouds.compute.util.ComputeServiceUtils; + +import com.google.common.base.Function; + +/** + * Defaults to version null and 64bit, if the operating system is unrecognized and the pattern + * "32bit" isn't in the string. + * + * @author Adrian Cole + * + */ +@Singleton +public class ParseOsFamilyVersion64BitFromImageName implements Function { + private final Map> osVersionMap; + + @Inject + public ParseOsFamilyVersion64BitFromImageName(Map> osVersionMap) { + this.osVersionMap = osVersionMap; + } + + // ex Debian 6.0 64-bit + // ex. Ubuntu 10.04 LTS 32-bit + public static final Pattern PATTERN = Pattern.compile("([^ ]+).* ([0-9.]+)( [36][24]-bit)?$"); + + @Override + public OsFamilyVersion64Bit apply(String input) { + boolean is64Bit = containsPattern("64-bit").apply(input); + + Matcher matcher = PATTERN.matcher(input); + if (matcher.find()) { + OsFamily fam = OsFamily.fromValue(matcher.group(1).toLowerCase()); + switch (fam) { + case UNRECOGNIZED: + return new OsFamilyVersion64Bit(OsFamily.UNRECOGNIZED, null, is64Bit); + } + return new OsFamilyVersion64Bit(fam, ComputeServiceUtils.parseVersionOrReturnEmptyString(fam, matcher + .group(2), osVersionMap), is64Bit); + } else { + return new OsFamilyVersion64Bit(OsFamily.UNRECOGNIZED, null, is64Bit); + } + + } +} \ No newline at end of file diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/ServerDetailsToNodeMetadata.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/ServerDetailsToNodeMetadata.java new file mode 100644 index 0000000000..2d315839b3 --- /dev/null +++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/ServerDetailsToNodeMetadata.java @@ -0,0 +1,150 @@ +/** + * 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.glesys.compute.functions; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName; + +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; + +import javax.annotation.Resource; +import javax.inject.Inject; +import javax.inject.Named; +import javax.inject.Singleton; + +import org.jclouds.collect.FindResourceInSet; +import org.jclouds.collect.Memoized; +import org.jclouds.compute.domain.HardwareBuilder; +import org.jclouds.compute.domain.Image; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.NodeMetadataBuilder; +import org.jclouds.compute.domain.NodeState; +import org.jclouds.compute.domain.OperatingSystem; +import org.jclouds.compute.domain.Processor; +import org.jclouds.compute.domain.Volume; +import org.jclouds.compute.domain.internal.VolumeImpl; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.domain.Location; +import org.jclouds.glesys.GleSYSClient; +import org.jclouds.glesys.domain.Ip; +import org.jclouds.glesys.domain.ServerDetails; +import org.jclouds.glesys.options.ServerStatusOptions; +import org.jclouds.logging.Logger; +import org.jclouds.util.InetAddresses2.IsPrivateIPAddress; + +import com.google.common.base.Function; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.base.Supplier; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Iterables; + +/** + * @author Adrian Cole + */ +@Singleton +public class ServerDetailsToNodeMetadata implements Function { + @Resource + @Named(ComputeServiceConstants.COMPUTE_LOGGER) + protected Logger logger = Logger.NULL; + public static final Map serverStateToNodeState = ImmutableMap + . builder().put(ServerDetails.State.STOPPED, NodeState.SUSPENDED).put( + ServerDetails.State.RUNNING, NodeState.RUNNING).put(ServerDetails.State.UNRECOGNIZED, + NodeState.UNRECOGNIZED).build(); + + protected final Supplier> images; + protected final GleSYSClient client; + protected final FindLocationForServerDetails findLocationForServerDetails; + + private static class FindImageForServer implements Predicate { + private final ServerDetails instance; + + private FindImageForServer(ServerDetails instance) { + this.instance = instance; + } + + @Override + public boolean apply(Image input) { + return input.getProviderId().equals(instance.getTemplateName()); + } + } + + @Inject + ServerDetailsToNodeMetadata(GleSYSClient client, FindLocationForServerDetails findLocationForServerDetails, + @Memoized Supplier> images) { + this.client = checkNotNull(client, "client"); + this.findLocationForServerDetails = checkNotNull(findLocationForServerDetails, "findLocationForServerDetails"); + this.images = checkNotNull(images, "images"); + } + + @Override + public NodeMetadata apply(ServerDetails from) { + NodeMetadataBuilder builder = new NodeMetadataBuilder(); + builder.ids(from.getId() + ""); + builder.name(from.getHostname()); + builder.hostname(from.getHostname()); + builder.location(findLocationForServerDetails.apply(from)); + builder.group(parseGroupFromName(from.getHostname())); + builder.imageId(from.getTemplateName() + ""); + builder.operatingSystem(parseOperatingSystem(from)); + builder.hardware(new HardwareBuilder().ids(from.getId() + "").ram(from.getMemorySizeMB()).processors( + ImmutableList.of(new Processor(from.getCpuCores(), 1.0))).volumes( + ImmutableList. of(new VolumeImpl((float) from.getDiskSizeGB(), true, true))).hypervisor( + from.getPlatform()).build()); + builder.state(serverStateToNodeState.get(client.getServerClient().getServerStatus(from.getId(), + ServerStatusOptions.Builder.state()).getState())); + Iterable addresses = Iterables.transform(from.getIps(), new Function() { + + @Override + public String apply(Ip arg0) { + return arg0.getIp(); + } + + }); + builder.publicAddresses(Iterables.filter(addresses, Predicates.not(IsPrivateIPAddress.INSTANCE))); + builder.privateAddresses(Iterables.filter(addresses, IsPrivateIPAddress.INSTANCE)); + return builder.build(); + } + + protected OperatingSystem parseOperatingSystem(ServerDetails from) { + try { + return Iterables.find(images.get(), new FindImageForServer(from)).getOperatingSystem(); + } catch (NoSuchElementException e) { + logger.warn("could not find a matching image for server %s", from); + } + return null; + } + + @Singleton + public static class FindLocationForServerDetails extends FindResourceInSet { + + @Inject + public FindLocationForServerDetails(@Memoized Supplier> location) { + super(location); + } + + @Override + public boolean matches(ServerDetails from, Location input) { + return input.getId().equals(from.getDatacenter()); + } + } +} diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/ServerSpecToHardware.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/ServerSpecToHardware.java new file mode 100644 index 0000000000..8b882c42f0 --- /dev/null +++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/functions/ServerSpecToHardware.java @@ -0,0 +1,59 @@ +/** + * 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.glesys.compute.functions; + +import static com.google.common.base.Preconditions.checkNotNull; + +import javax.inject.Inject; +import javax.inject.Singleton; + +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.compute.predicates.ImagePredicates; +import org.jclouds.glesys.domain.ServerSpec; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; + +/** + * + * @author Adrian Cole + */ +@Singleton +public class ServerSpecToHardware implements Function { + + private final FindLocationForServerSpec findLocationForServerSpec; + + @Inject + ServerSpecToHardware(FindLocationForServerSpec findLocationForServerSpec) { + this.findLocationForServerSpec = checkNotNull(findLocationForServerSpec, "findLocationForServerSpec"); + } + + @Override + public Hardware apply(ServerSpec spec) { + return new HardwareBuilder().ids(spec.toString()).ram(spec.getMemorySizeMB()).processors( + ImmutableList.of(new Processor(spec.getCpuCores(), 1.0))).volumes( + ImmutableList. of(new VolumeImpl((float) spec.getDiskSizeGB(), true, true))).hypervisor( + spec.getPlatform()).location(findLocationForServerSpec.apply(spec)).supportsImage( + ImagePredicates.idEquals(spec.getTemplateName())).build(); + } +} diff --git a/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptions.java b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptions.java new file mode 100644 index 0000000000..1fd817fe51 --- /dev/null +++ b/sandbox-providers/glesys/src/main/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptions.java @@ -0,0 +1,201 @@ +/** + * 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.glesys.compute.options; + +import static com.google.common.base.Preconditions.checkArgument; + +import java.util.Map; + +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.options.TemplateOptions; +import org.jclouds.glesys.features.ServerClient; +import org.jclouds.io.Payload; + +import com.google.common.net.InetAddresses; + +/** + * Contains options supported by the + * {@link ComputeService#createNodesInGroup(String, int, TemplateOptions)} and + * {@link ComputeService#createNodesInGroup(String, int, TemplateOptions)} operations on the + * gogrid provider. + * + *

Usage

The recommended way to instantiate a {@link GleSYSTemplateOptions} object is to + * statically import {@code GleSYSTemplateOptions.*} and invoke a static creation method followed by + * an instance mutator (if needed): + *

+ * + *

+ * import static org.jclouds.compute.options.GleSYSTemplateOptions.Builder.*;
+ * ComputeService client = // get connection
+ * templateBuilder.options(inboundPorts(22, 80, 8080, 443));
+ * Set<? extends NodeMetadata> set = client.createNodesInGroup(tag, 2, templateBuilder.build());
+ * 
+ * + * @author Adrian Cole + */ +public class GleSYSTemplateOptions extends TemplateOptions implements Cloneable { + + protected String ip; + + @Override + public GleSYSTemplateOptions clone() { + GleSYSTemplateOptions options = new GleSYSTemplateOptions(); + copyTo(options); + return options; + } + + @Override + public void copyTo(TemplateOptions to) { + super.copyTo(to); + if (to instanceof GleSYSTemplateOptions) { + GleSYSTemplateOptions eTo = GleSYSTemplateOptions.class.cast(to); + eTo.ip(ip); + } + } + + /** + * + * @see ServerClient#createServerWithHostnameAndRootPassword + * @see InetAddresses#isInetAddress + */ + public TemplateOptions ip(String ip) { + if (ip != null) + checkArgument(InetAddresses.isInetAddress(ip), "ip %s is not valid", ip); + this.ip = ip; + return this; + } + + public String getIp() { + return ip; + } + + public static final GleSYSTemplateOptions NONE = new GleSYSTemplateOptions(); + + public static class Builder { + + /** + * @see #ip + */ + public static GleSYSTemplateOptions ip(String ip) { + GleSYSTemplateOptions options = new GleSYSTemplateOptions(); + return GleSYSTemplateOptions.class.cast(options.ip(ip)); + } + + // methods that only facilitate returning the correct object type + + /** + * @see TemplateOptions#inboundPorts(int...) + */ + public static GleSYSTemplateOptions inboundPorts(int... ports) { + GleSYSTemplateOptions options = new GleSYSTemplateOptions(); + return GleSYSTemplateOptions.class.cast(options.inboundPorts(ports)); + } + + /** + * @see TemplateOptions#blockOnPort(int, int) + */ + public static GleSYSTemplateOptions blockOnPort(int port, int seconds) { + GleSYSTemplateOptions options = new GleSYSTemplateOptions(); + return GleSYSTemplateOptions.class.cast(options.blockOnPort(port, seconds)); + } + + /** + * @see TemplateOptions#runScript(Payload) + */ + public static GleSYSTemplateOptions runScript(Payload script) { + GleSYSTemplateOptions options = new GleSYSTemplateOptions(); + return GleSYSTemplateOptions.class.cast(options.runScript(script)); + } + + /** + * @see TemplateOptions#userMetadata(Map) + */ + public static GleSYSTemplateOptions userMetadata(Map userMetadata) { + GleSYSTemplateOptions options = new GleSYSTemplateOptions(); + return GleSYSTemplateOptions.class.cast(options.userMetadata(userMetadata)); + } + + /** + * @see TemplateOptions#userMetadata(String, String) + */ + public static GleSYSTemplateOptions userMetadata(String key, String value) { + GleSYSTemplateOptions options = new GleSYSTemplateOptions(); + return GleSYSTemplateOptions.class.cast(options.userMetadata(key, value)); + } + } + + // methods that only facilitate returning the correct object type + + /** + * @see TemplateOptions#blockOnPort(int, int) + */ + @Override + public GleSYSTemplateOptions blockOnPort(int port, int seconds) { + return GleSYSTemplateOptions.class.cast(super.blockOnPort(port, seconds)); + } + + /** + * @see TemplateOptions#inboundPorts(int...) + */ + @Override + public GleSYSTemplateOptions inboundPorts(int... ports) { + return GleSYSTemplateOptions.class.cast(super.inboundPorts(ports)); + } + + /** + * @see TemplateOptions#authorizePublicKey(String) + */ + @Override + public GleSYSTemplateOptions authorizePublicKey(String publicKey) { + return GleSYSTemplateOptions.class.cast(super.authorizePublicKey(publicKey)); + } + + /** + * @see TemplateOptions#installPrivateKey(String) + */ + @Override + public GleSYSTemplateOptions installPrivateKey(String privateKey) { + return GleSYSTemplateOptions.class.cast(super.installPrivateKey(privateKey)); + } + + /** + * @see TemplateOptions#runScript(Payload) + */ + @Deprecated + @Override + public GleSYSTemplateOptions runScript(Payload script) { + return GleSYSTemplateOptions.class.cast(super.runScript(script)); + } + + /** + * {@inheritDoc} + */ + @Override + public GleSYSTemplateOptions userMetadata(Map userMetadata) { + return GleSYSTemplateOptions.class.cast(super.userMetadata(userMetadata)); + } + + /** + * {@inheritDoc} + */ + @Override + public GleSYSTemplateOptions userMetadata(String key, String value) { + return GleSYSTemplateOptions.class.cast(super.userMetadata(key, value)); + } +} diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapterExpectTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapterExpectTest.java new file mode 100644 index 0000000000..5cd795ba72 --- /dev/null +++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSComputeServiceAdapterExpectTest.java @@ -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.glesys.compute; + +import static org.testng.Assert.assertEquals; + +import org.jclouds.glesys.compute.internal.BaseGleSYSComputeServiceExpectTest; +import org.testng.annotations.Test; + +import com.google.common.collect.Iterables; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "live", singleThreaded = true, testName = "GleSYSComputeServiceAdapterExpectTest") +public class GleSYSComputeServiceAdapterExpectTest extends BaseGleSYSComputeServiceExpectTest { + + @Test + public void testListImages() { + + GleSYSComputeServiceAdapter adapter = injectorForKnownArgumentsAndConstantPassword().getInstance(GleSYSComputeServiceAdapter.class); + + assertEquals(Iterables.size(adapter.listImages()), 34); + + } + + + //TODO: most importantly createServer and listHardwareProfiles tests +} diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSComputeServiceLiveTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSComputeServiceLiveTest.java new file mode 100644 index 0000000000..9b132f707e --- /dev/null +++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSComputeServiceLiveTest.java @@ -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.glesys.compute; + +import org.jclouds.compute.BaseComputeServiceLiveTest; +import org.jclouds.compute.ComputeServiceContextFactory; +import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.glesys.GleSYSAsyncClient; +import org.jclouds.glesys.GleSYSClient; +import org.jclouds.rest.RestContext; +import org.jclouds.sshj.config.SshjSshClientModule; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableMap; +import com.google.inject.Module; + +/** + * + * TODO: enable this + * + * @author Adrian Cole + */ +@Test(groups = "live", enabled = false, singleThreaded = true) +public class GleSYSComputeServiceLiveTest extends BaseComputeServiceLiveTest { + public GleSYSComputeServiceLiveTest() { + provider = "glesys"; + } + + @Override + protected Module getSshModule() { + return new SshjSshClientModule(); + } + + public void testAssignability() throws Exception { + @SuppressWarnings("unused") + RestContext tmContext = new ComputeServiceContextFactory() + .createContext(provider, identity, credential).getProviderSpecificContext(); + } + + // GleSYS does not support metadata + @Override + protected void checkUserMetadataInNodeEquals(NodeMetadata node, ImmutableMap userMetadata) { + } +} diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSExperimentExpectTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSExperimentExpectTest.java new file mode 100644 index 0000000000..1dc7ca53e4 --- /dev/null +++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSExperimentExpectTest.java @@ -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.glesys.compute; + +import static org.testng.Assert.assertEquals; + +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.glesys.compute.internal.BaseGleSYSComputeServiceExpectTest; +import org.testng.annotations.Test; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "live", singleThreaded = true, testName = "GleSYSExperimentLiveTest") +public class GleSYSExperimentExpectTest extends BaseGleSYSComputeServiceExpectTest { + + @Test + public void testAndExperiment() { + ComputeServiceContext context = null; + try { + + context = computeContextForKnownArgumentsAndConstantPassword(); + + assertEquals(context.getComputeService().listAssignableLocations().size(), 4); + + } finally { + if (context != null) + context.close(); + } + } + +} diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSExperimentLiveTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSExperimentLiveTest.java new file mode 100644 index 0000000000..e4c4b9795b --- /dev/null +++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSExperimentLiveTest.java @@ -0,0 +1,59 @@ +/** + * 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.glesys.compute; + +import static org.testng.Assert.assertEquals; + +import org.jclouds.compute.BaseVersionedServiceLiveTest; +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.ComputeServiceContextFactory; +import org.jclouds.logging.log4j.config.Log4JLoggingModule; +import org.jclouds.sshj.config.SshjSshClientModule; +import org.testng.annotations.Test; + +import com.google.common.collect.ImmutableSet; +import com.google.inject.Module; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "live", singleThreaded = true, testName = "GleSYSExperimentLiveTest") +public class GleSYSExperimentLiveTest extends BaseVersionedServiceLiveTest { + public GleSYSExperimentLiveTest() { + provider = "glesys"; + } + + @Test + public void testAndExperiment() { + ComputeServiceContext context = null; + try { + + context = new ComputeServiceContextFactory().createContext(provider, identity, credential, ImmutableSet + . of(new Log4JLoggingModule(), new SshjSshClientModule())); + + assertEquals(context.getComputeService().listAssignableLocations().size(), 6); + + } finally { + if (context != null) + context.close(); + } + } + +} diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSTemplateBuilderLiveTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSTemplateBuilderLiveTest.java new file mode 100644 index 0000000000..ae2c209fbb --- /dev/null +++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/GleSYSTemplateBuilderLiveTest.java @@ -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.glesys.compute; + +import static org.jclouds.compute.util.ComputeServiceUtils.getCores; +import static org.jclouds.compute.util.ComputeServiceUtils.getSpace; +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.util.Set; + +import org.jclouds.compute.BaseTemplateBuilderLiveTest; +import org.jclouds.compute.domain.OsFamily; +import org.jclouds.compute.domain.OsFamilyVersion64Bit; +import org.jclouds.compute.domain.Template; +import org.jclouds.compute.domain.Volume; +import org.jclouds.glesys.compute.options.GleSYSTemplateOptions; +import org.testng.annotations.Test; + +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; +import com.google.common.collect.ImmutableSet; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "live", testName = "GleSYSTemplateBuilderLiveTest") +public class GleSYSTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest { + + public GleSYSTemplateBuilderLiveTest() { + provider = "glesys"; + } + + // / allows us to break when a new os is added + @Override + protected Predicate defineUnsupportedOperatingSystems() { + return Predicates.not(new Predicate() { + + @Override + public boolean apply(OsFamilyVersion64Bit input) { + // TODO: this is an incomplete list until ParseOsFamilyVersion64BitFromImageName is + // complete + switch (input.family) { + case UBUNTU: + return (input.version.equals("")|| input.version.equals("11.04")) && input.is64Bit; + case DEBIAN: + return input.version.equals("") || input.version.matches("[56].0"); + case FEDORA: + return input.version.equals("") || input.version.equals("13") || input.version.equals("15"); + case CENTOS: + return input.version.equals("") || input.version.equals("5") || input.version.equals("5.0") + || input.version.equals("6.0"); + default: + return false; + } + } + + }); + } + + @Test + public void testDefaultTemplateBuilder() throws IOException { + Template defaultTemplate = context.getComputeService().templateBuilder().build(); + assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "11.04"); + assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true); + assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU); + assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); + assertEquals(defaultTemplate.getHardware().getRam(), 512); + assertEquals(defaultTemplate.getHardware().getHypervisor(), "Xen"); + assertEquals(getSpace(defaultTemplate.getHardware()), 5.0d); + assertEquals(defaultTemplate.getHardware().getVolumes().get(0).getType(), Volume.Type.LOCAL); + // test that we bound the correct templateoptions in guice + assertEquals(defaultTemplate.getOptions().getClass(), GleSYSTemplateOptions.class); + } + + @Override + protected Set getIso3166Codes() { + return ImmutableSet. of("US-CA", "US-VA", "BR-SP"); + } +} \ No newline at end of file diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/functions/ParseOsFamilyVersion64BitFromImageNameTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/functions/ParseOsFamilyVersion64BitFromImageNameTest.java new file mode 100644 index 0000000000..cb3e97faa5 --- /dev/null +++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/functions/ParseOsFamilyVersion64BitFromImageNameTest.java @@ -0,0 +1,80 @@ +/** + * 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.glesys.compute.functions; + +import static com.google.common.collect.Iterables.transform; +import static com.google.common.collect.Lists.newArrayList; +import static org.testng.Assert.assertEquals; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.Map.Entry; + +import org.jclouds.compute.config.BaseComputeServiceContextModule; +import org.jclouds.compute.domain.OsFamilyVersion64Bit; +import org.jclouds.compute.reference.ComputeServiceConstants; +import org.jclouds.json.Json; +import org.jclouds.json.config.GsonModule; +import org.jclouds.json.internal.GsonWrapper; +import org.jclouds.util.Strings2; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import com.google.common.base.Function; +import com.google.gson.Gson; +import com.google.inject.Guice; +import com.google.inject.TypeLiteral; + +/** + * + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ParseOsFamilyVersion64BitFromImageNameTest") +public class ParseOsFamilyVersion64BitFromImageNameTest { + Json json = new GsonWrapper(new Gson()); + + //TODO: update osmatches corresponding with server_templates.json, this may imply an update to ComputeServiceConstants and/or OsFamily + @DataProvider(name = "data") + public Object[][] createData() throws IOException { + InputStream is = ParseOsFamilyVersion64BitFromImageNameTest.class.getResourceAsStream("/osmatches.json"); + Map values = json.fromJson(Strings2.toStringAndClose(is), + new TypeLiteral>() { + }.getType()); + + return newArrayList( + transform(values.entrySet(), new Function, Object[]>() { + + @Override + public Object[] apply(Entry input) { + return new Object[] { input.getKey(), input.getValue() }; + } + + })).toArray(new Object[][] {}); + } + + ParseOsFamilyVersion64BitFromImageName parser = new ParseOsFamilyVersion64BitFromImageName(new BaseComputeServiceContextModule() { + }.provideOsVersionMap(new ComputeServiceConstants.ReferenceData(), Guice.createInjector(new GsonModule()) + .getInstance(Json.class))); + + @Test(dataProvider = "data") + public void test(String input, OsFamilyVersion64Bit expected) { + assertEquals(parser.apply(input), expected); + } +} diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/functions/ServerSpecToHardwareTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/functions/ServerSpecToHardwareTest.java new file mode 100644 index 0000000000..52a047fd53 --- /dev/null +++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/functions/ServerSpecToHardwareTest.java @@ -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.glesys.compute.functions; + +import org.jclouds.glesys.compute.internal.BaseGleSYSComputeServiceExpectTest; +import org.testng.annotations.Test; + +/** + * TODO + * + */ +@Test(groups = "unit") +public class ServerSpecToHardwareTest extends BaseGleSYSComputeServiceExpectTest { + + @Test + public void testHardwareRequest() { + + ServerSpecToHardware toTest = injectorForKnownArgumentsAndConstantPassword().getInstance(ServerSpecToHardware.class); + + } + + +} diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/internal/BaseGleSYSComputeServiceExpectTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/internal/BaseGleSYSComputeServiceExpectTest.java new file mode 100644 index 0000000000..d564ae21b0 --- /dev/null +++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/internal/BaseGleSYSComputeServiceExpectTest.java @@ -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.glesys.compute.internal; + +import java.net.URI; +import java.util.Properties; + +import org.jclouds.compute.ComputeService; +import org.jclouds.compute.ComputeServiceContext; +import org.jclouds.compute.ComputeServiceContextFactory; +import org.jclouds.glesys.compute.config.GleSYSComputeServiceContextModule.PasswordProvider; +import org.jclouds.http.HttpRequest; +import org.jclouds.http.HttpResponse; +import org.jclouds.logging.config.NullLoggingModule; +import org.jclouds.rest.BaseRestClientExpectTest; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.ImmutableSet; +import com.google.inject.AbstractModule; +import com.google.inject.Injector; +import com.google.inject.Module; + +/** + * Base class for writing GleSYS Expect tests for ComputeService operations + * + * @author Adrian Cole + */ +public abstract class BaseGleSYSComputeServiceExpectTest extends BaseRestClientExpectTest { + + public BaseGleSYSComputeServiceExpectTest() { + provider = "glesys"; + } + + @Override + public ComputeService createClient(Function fn, Module module, Properties props) { + return new ComputeServiceContextFactory(setupRestProperties()).createContext(provider, identity, credential, + ImmutableSet. of(new ExpectModule(fn), new NullLoggingModule(), module), props) + .getComputeService(); + } + + protected PasswordProvider passwordGenerator() { + // make sure we can predict passwords generated for createServer requests + return new PasswordProvider() { + public String get() { + return "foo"; + } + }; + } + + protected Injector injectorForKnownArgumentsAndConstantPassword() { + return computeContextForKnownArgumentsAndConstantPassword().utils().injector(); + } + + protected ComputeServiceContext computeContextForKnownArgumentsAndConstantPassword() { + return requestsSendResponses( + HttpRequest.builder().method("GET").endpoint( + URI.create("https://api.glesys.com/server/templates/format/json")).headers( + ImmutableMultimap. builder().put("Accept", "application/json").put( + "Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build()).build(), + HttpResponse.builder().statusCode(200).payload(payloadFromResource("/server_templates.json")).build(), + HttpRequest.builder().method("GET").endpoint( + URI.create("https://api.glesys.com/server/allowedarguments/format/json")).headers( + ImmutableMultimap. builder().put("Accept", "application/json").put( + "Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==").build()).build(), + HttpResponse.builder().statusCode(204).payload(payloadFromResource("/server_allowed_arguments.json")) + .build(), new AbstractModule() { + + @Override + protected void configure() { + bind(PasswordProvider.class).toInstance(passwordGenerator()); + } + + }).getContext(); + } +} diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptionsTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptionsTest.java new file mode 100644 index 0000000000..cf1e14796f --- /dev/null +++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/compute/options/GleSYSTemplateOptionsTest.java @@ -0,0 +1,64 @@ +/** + * 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.glesys.compute.options; + +import static org.jclouds.glesys.compute.options.GleSYSTemplateOptions.Builder.ip; +import static org.testng.Assert.assertEquals; + +import org.jclouds.compute.options.TemplateOptions; +import org.testng.annotations.Test; + +/** + * Tests possible uses of {@code GleSYSTemplateOptions} and {@code + * GleSYSTemplateOptions.Builder.*}. + * + * @author Adrian Cole + */ +// NOTE:without testName, this will not call @Before* and fail w/NPE during surefire +@Test(groups = "unit", testName = "GleSYSTemplateOptionsTest") +public class GleSYSTemplateOptionsTest { + @Test + public void testAs() { + TemplateOptions options = new GleSYSTemplateOptions(); + assertEquals(options.as(GleSYSTemplateOptions.class), options); + } + + @Test + public void testDefaultip() { + TemplateOptions options = new GleSYSTemplateOptions(); + assertEquals(options.as(GleSYSTemplateOptions.class).getIp(), null); + } + + @Test + public void testip() { + TemplateOptions options = new GleSYSTemplateOptions().ip("1.1.1.1"); + assertEquals(options.as(GleSYSTemplateOptions.class).getIp(), "1.1.1.1"); + } + + @Test + public void testipStatic() { + TemplateOptions options = ip("1.1.1.1"); + assertEquals(options.as(GleSYSTemplateOptions.class).getIp(), "1.1.1.1"); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testipIsInvalidThrowsIllegalArgument() { + new GleSYSTemplateOptions().ip("foo"); + } +} diff --git a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ServerClientExpectTest.java b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ServerClientExpectTest.java index effa906582..f287aabd79 100644 --- a/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ServerClientExpectTest.java +++ b/sandbox-providers/glesys/src/test/java/org/jclouds/glesys/features/ServerClientExpectTest.java @@ -117,26 +117,26 @@ public class ServerClientExpectTest extends BaseRestClientExpectTest expectedBuilder = ImmutableSet.