diff --git a/common/openstack/src/test/resources/keystoneAuthResponse_trystack.json b/common/openstack/src/test/resources/keystoneAuthResponse_trystack.json new file mode 100644 index 0000000000..27844f2fd8 --- /dev/null +++ b/common/openstack/src/test/resources/keystoneAuthResponse_trystack.json @@ -0,0 +1,49 @@ +{ + "access": { + "token": { + "expires": "2012-03-23T21:44:09", + "id": "Auth_4f173437e4b013bee56d1007", + "tenant": { + "id": "3456", + "name": "508151008" + } + }, + "serviceCatalog": [{ + "endpoints": [{ + "adminURL": "https://nova-api.trystack.org:9774/v1.1/3456", + "region": "RegionOne", + "internalURL": "https://nova-api.trystack.org:9774/v1.1/3456", + "publicURL": "https://nova-api.trystack.org:9774/v1.1/3456" + }], + "type": "compute", + "name": "nova" + }, { + "endpoints": [{ + "adminURL": "https://GLANCE_API_IS_NOT_DISCLOSED/v1.1/3456", + "region": "RegionOne", + "internalURL": "https://GLANCE_API_IS_NOT_DISCLOSED/v1.1/3456", + "publicURL": "https://GLANCE_API_IS_NOT_DISCLOSED/v1.1/3456" + }], + "type": "image", + "name": "glance" + }, { + "endpoints": [{ + "adminURL": "https://nova-api.trystack.org:5443/v2.0", + "region": "RegionOne", + "internalURL": "https://keystone.thefreecloud.org:5000/v2.0", + "publicURL": "https://keystone.thefreecloud.org:5000/v2.0" + }], + "type": "identity", + "name": "keystone" + }], + "user": { + "id": "43", + "roles": [{ + "tenantId": "3456", + "id": "2", + "name": "Member" + }], + "name": "508151008" + } + } +} \ No newline at end of file diff --git a/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/config/NovaComputeServiceContextModule.java b/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/config/NovaComputeServiceContextModule.java index f043b20d25..c1f80d9adc 100644 --- a/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/config/NovaComputeServiceContextModule.java +++ b/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/config/NovaComputeServiceContextModule.java @@ -109,7 +109,7 @@ public class NovaComputeServiceContextModule bind(new TypeLiteral>() { }).to(ImageInZoneToImage.class); bind(new TypeLiteral>() { - }).to(NovaImageToOperatingSystem.class); + }).to(ImageToOperatingSystem.class); bind(new TypeLiteral>() { }).to(FlavorInZoneToHardware.class); diff --git a/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/CreateSecurityGroupIfNeeded.java b/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/CreateSecurityGroupIfNeeded.java index df08888da6..14e9769936 100644 --- a/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/CreateSecurityGroupIfNeeded.java +++ b/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/CreateSecurityGroupIfNeeded.java @@ -86,14 +86,11 @@ public class CreateSecurityGroupIfNeeded implements Function> authorizing securityGroup(%s) permission to port %d", securityGroup, port); - logger.trace(">> authorizing securityGroup(%s) permission to itself on port %d", securityGroup, port); - securityGroupClient.createSecurityGroupRuleAllowingSecurityGroupId(securityGroup.getId(), Ingress.builder() - .ipProtocol(IpProtocol.TCP).fromPort(port).toPort(port).build(), securityGroup.getId()); - logger.trace(">> authorizing securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, port); + // NOTE that permission to itself isn't supported on trystack! + logger.debug(">> authorizing securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, port); securityGroupClient.createSecurityGroupRuleAllowingCidrBlock(securityGroup.getId(), Ingress.builder().ipProtocol( IpProtocol.TCP).fromPort(port).toPort(port).build(), "0.0.0.0/0"); - logger.debug("<< authorized securityGroup(%s) permission to port %d", securityGroup, port); + logger.debug("<< authorized securityGroup(%s) permission to 0.0.0.0/0 on port %d", securityGroup, port); } } diff --git a/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/NovaImageToOperatingSystem.java b/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/ImageToOperatingSystem.java similarity index 64% rename from labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/NovaImageToOperatingSystem.java rename to labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/ImageToOperatingSystem.java index 6e79b1f8ba..7a81a06519 100644 --- a/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/NovaImageToOperatingSystem.java +++ b/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/ImageToOperatingSystem.java @@ -18,8 +18,16 @@ */ package org.jclouds.openstack.nova.v1_1.compute.functions; +import static com.google.common.base.Predicates.containsPattern; +import static com.google.common.base.Predicates.equalTo; +import static com.google.common.base.Predicates.not; +import static com.google.common.collect.Iterables.any; +import static com.google.common.collect.Iterables.filter; +import static com.google.common.collect.Iterables.find; + import java.util.Arrays; import java.util.Map; +import java.util.NoSuchElementException; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -38,17 +46,14 @@ import com.google.common.base.CharMatcher; import com.google.common.base.Function; import com.google.common.base.Objects; import com.google.common.base.Predicate; -import com.google.common.base.Predicates; import com.google.common.base.Splitter; -import com.google.common.collect.Iterables; /** - * A function for transforming a nova specific Image into a generic - * OperatingSystem object. + * A function for transforming a nova specific Image into a generic OperatingSystem object. * * @author Matt Stephenson */ -public class NovaImageToOperatingSystem implements Function { +public class ImageToOperatingSystem implements Function { public static final Pattern DEFAULT_PATTERN = Pattern.compile("(([^ ]*) ([0-9.]+) ?.*)"); // Windows Server 2008 R2 x64 public static final Pattern WINDOWS_PATTERN = Pattern.compile("Windows (.*) (x[86][64])"); @@ -60,7 +65,7 @@ public class NovaImageToOperatingSystem implements Function> osVersionMap; @Inject - public NovaImageToOperatingSystem(Map> osVersionMap) { + public ImageToOperatingSystem(Map> osVersionMap) { this.osVersionMap = osVersionMap; } @@ -85,15 +90,26 @@ public class NovaImageToOperatingSystem implements Function imageNameParts = Splitter.on(CharMatcher.WHITESPACE).trimResults() - .split(imageName.toLowerCase()); + final Iterable imageNameParts = Splitter.on(CharMatcher.WHITESPACE).trimResults().split( + imageName.toLowerCase()); - osFamily = Iterables.find(Arrays.asList(OsFamily.values()), new Predicate() { - @Override - public boolean apply(@Nullable OsFamily osFamily) { - return Iterables.any(imageNameParts, Predicates.equalTo(osFamily.name().toLowerCase())); + try { + osFamily = find(Arrays.asList(OsFamily.values()), new Predicate() { + @Override + public boolean apply(@Nullable OsFamily osFamily) { + return any(imageNameParts, equalTo(osFamily.name().toLowerCase())); + } + }); + } catch (NoSuchElementException e) { + String ubuntuVersion = startsWithUbuntuVersion(imageNameParts); + if (ubuntuVersion != null) { + osFamily = OsFamily.UBUNTU; + osVersion = ubuntuVersion; + } else { + logger.trace("could not parse operating system family for image(%s): %s", imageNameParts); + osFamily = OsFamily.UNRECOGNIZED; } - }); + } } Matcher matcher = DEFAULT_PATTERN.matcher(imageName); if (matcher.find() && matcher.groupCount() >= 3) { @@ -102,4 +118,14 @@ public class NovaImageToOperatingSystem implements Function imageNameParts) { + Map ubuntuVersions = osVersionMap.get(OsFamily.UBUNTU); + for (String ubuntuKey : filter(ubuntuVersions.keySet(), not(equalTo("")))) { + if (any(imageNameParts, containsPattern("^" + ubuntuKey + ".*"))) { + return ubuntuVersions.get(ubuntuKey); + } + } + return null; + } } diff --git a/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/ServerInZoneToNodeMetadata.java b/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/ServerInZoneToNodeMetadata.java index e875ccc4ef..3234551604 100644 --- a/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/ServerInZoneToNodeMetadata.java +++ b/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/compute/functions/ServerInZoneToNodeMetadata.java @@ -20,6 +20,7 @@ package org.jclouds.openstack.nova.v1_1.compute.functions; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; +import static com.google.common.collect.Iterables.concat; import static com.google.common.collect.Iterables.filter; import static com.google.common.collect.Iterables.find; import static com.google.common.collect.Iterables.transform; @@ -97,7 +98,7 @@ public class ServerInZoneToNodeMetadata implements Function internetAddresses) { + this.addresses.replaceValues(Address.Type.INTERNET, ImmutableSet.copyOf(checkNotNull(internetAddresses, + "internetAddresses"))); + return this; + } + /** * @see Server#getPublicAddresses() */ @@ -466,6 +482,19 @@ public class Server extends Resource { return ImmutableSet.copyOf(privateAddresses); } } + + /** + * @return the internet ip addresses assigned to the server + * @since essex + */ + public Set
getInternetAddresses() { + Collection
internetAddrs = getAddresses().get(Address.Type.INTERNET); + if (internetAddrs == null) { + return ImmutableSet.
of(); + } else { + return ImmutableSet.copyOf(internetAddrs); + } + } /** * @return the public ip addresses assigned to the server diff --git a/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/ExtensionNamespaces.java b/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/ExtensionNamespaces.java index df97dda590..f4ef0c7ca1 100644 --- a/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/ExtensionNamespaces.java +++ b/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/extensions/ExtensionNamespaces.java @@ -25,8 +25,65 @@ package org.jclouds.openstack.nova.v1_1.extensions; * @see */ public interface ExtensionNamespaces { + /** + * Keypair Support + */ public static final String KEYPAIRS = "http://docs.openstack.org/ext/keypairs/api/v1.1"; + /** + * Volumes support + */ public static final String VOLUMES = "http://docs.openstack.org/ext/volumes/api/v1.1"; + /** + * Volume types support + */ + public static final String VOLUME_TYPES = "http://docs.openstack.org/ext/volume_types/api/v1.1"; + /** + * Security group support + */ public static final String SECURITY_GROUPS = "http://docs.openstack.org/ext/securitygroups/api/v1.1"; + /** + * Floating IPs support + */ public static final String FLOATING_IPS = "http://docs.openstack.org/ext/floating_ips/api/v1.1"; + /** + * Multiple network support + */ + public static final String MULTINIC = "http://docs.openstack.org/ext/multinic/api/v1.1"; + /** + * Host administration + */ + public static final String HOSTS = "http://docs.openstack.org/ext/hosts/api/v1.1"; + /** + * Quotas management support + */ + public static final String QUOTAS = "http://docs.openstack.org/ext/quotas-sets/api/v1.1"; + /** + * Instance type (flavor) extra specs + */ + public static final String FLAVOR_EXTRA_SPECS = "http://docs.openstack.org/ext/flavor_extra_specs/api/v1.1"; + /** + * Provide additional data for flavors + */ + public static final String FLAVOR_EXTRA_DATA = "http://docs.openstack.org/ext/flavor_extra_data/api/v1.1"; + /** + * Virtual interface support + */ + public static final String VIRTUAL_INTERFACES = "http://docs.openstack.org/ext/virtual_interfaces/api/v1.1"; + /** + * Extended support to the Create Server v1.1 API + */ + public static final String CREATESERVEREXT = "http://docs.openstack.org/ext/createserverext/api/v1.1"; + /** + * Virtual Storage Arrays support + */ + public static final String VSA = "http://docs.openstack.org/ext/vsa/api/v1.1"; + /** + * Simple tenant usage extension + */ + public static final String SIMPLE_TENANT_USAGE = "http://docs.openstack.org/ext/os-simple-tenant-usage/api/v1.1"; + /** + * Instance rescue mode + */ + public static final String RESCUE = "http://docs.openstack.org/ext/rescue/api/v1.1"; + } diff --git a/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/functions/ExtensionToNameSpace.java b/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/functions/ExtensionToNameSpace.java index ddc4dfc4fe..9cbf40cce4 100644 --- a/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/functions/ExtensionToNameSpace.java +++ b/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/functions/ExtensionToNameSpace.java @@ -20,7 +20,10 @@ package org.jclouds.openstack.nova.v1_1.functions; import java.net.URI; +import javax.inject.Inject; +import javax.inject.Provider; import javax.inject.Singleton; +import javax.ws.rs.core.UriBuilder; import org.jclouds.openstack.nova.v1_1.domain.Extension; @@ -28,10 +31,16 @@ import com.google.common.base.Function; @Singleton public class ExtensionToNameSpace implements Function { + private final Provider uriBuilders; + + @Inject + public ExtensionToNameSpace(Provider uriBuilders) { + this.uriBuilders = uriBuilders; + } @Override public URI apply(Extension input) { - return input.getNamespace(); + return uriBuilders.get().uri(input.getNamespace()).scheme("http").build(); } public String toString() { diff --git a/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/predicates/ExtensionPredicates.java b/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/predicates/ExtensionPredicates.java index 443f644f6f..aac9bbfe90 100644 --- a/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/predicates/ExtensionPredicates.java +++ b/labs/openstack-nova/src/main/java/org/jclouds/openstack/nova/v1_1/predicates/ExtensionPredicates.java @@ -47,7 +47,7 @@ public class ExtensionPredicates { return new Predicate() { @Override public boolean apply(Extension ext) { - return namespace.equals(ext.getNamespace()); + return namespace.toASCIIString().equals(ext.getNamespace().toASCIIString().replace("https", "http")); } @Override diff --git a/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/compute/NovaComputeServiceExpectTest.java b/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/compute/NovaComputeServiceExpectTest.java index 422462d93e..1960e74f9b 100644 --- a/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/compute/NovaComputeServiceExpectTest.java +++ b/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/compute/NovaComputeServiceExpectTest.java @@ -18,6 +18,7 @@ */ package org.jclouds.openstack.nova.v1_1.compute; +import static org.jclouds.compute.util.ComputeServiceUtils.getCores; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; @@ -26,18 +27,18 @@ import java.net.URI; import java.util.Map; import java.util.Set; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Iterables; - import org.jclouds.compute.ComputeService; import org.jclouds.compute.domain.NodeMetadata; +import org.jclouds.compute.domain.Template; import org.jclouds.domain.Location; import org.jclouds.http.HttpRequest; import org.jclouds.http.HttpResponse; import org.jclouds.openstack.nova.v1_1.internal.BaseNovaComputeServiceExpectTest; import org.testng.annotations.Test; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.Iterables; /** * Tests the compute service abstraction of the nova client. @@ -46,14 +47,13 @@ import com.google.common.collect.ImmutableMultimap; */ @Test(groups = "unit", testName = "NovaComputeServiceExpectTest") public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTest { - - public void testListServersWhenResponseIs2xx() throws Exception { + + public void testListLocationsWhenResponseIs2xx() throws Exception { Map requestResponseMap = ImmutableMap. builder().put( keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess).put(extensionsOfNovaRequest, extensionsOfNovaResponse).put(listImagesDetail, listImagesDetailResponse).put(listServers, - listServersResponse).put(listFlavorsDetail, listFlavorsDetailResponse).put(listFloatingIps, - listFloatingIpsResponse).build(); + listServersResponse).put(listFlavorsDetail, listFlavorsDetailResponse).build(); ComputeService clientWhenServersExist = requestsSendResponses(requestResponseMap); @@ -69,6 +69,46 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe assertEquals(clientWhenServersExist.listNodes().iterator().next().getName(), "sample-server"); } + public void testDefaultTemplateTryStack() throws Exception { + + Map requestResponseMap = ImmutableMap. builder().put( + keystoneAuthWithAccessKeyAndSecretKey, + HttpResponse.builder().statusCode(200).message("HTTP/1.1 200").payload( + payloadFromResourceWithContentType("/keystoneAuthResponse_trystack.json", "application/json")) + .build()).put( + extensionsOfNovaRequest.toBuilder().endpoint( + URI.create("https://nova-api.trystack.org:9774/v1.1/3456/extensions")).build(), + HttpResponse.builder().statusCode(200).payload(payloadFromResource("/extension_list_trystack.json")) + .build()).put( + listImagesDetail.toBuilder().endpoint( + URI.create("https://nova-api.trystack.org:9774/v1.1/3456/images/detail")).build(), + HttpResponse.builder().statusCode(200).payload(payloadFromResource("/image_list_detail_trystack.json")) + .build()).put( + listServers.toBuilder().endpoint( + URI.create("https://nova-api.trystack.org:9774/v1.1/3456/servers/detail")).build(), + listServersResponse).put( + listFlavorsDetail.toBuilder().endpoint( + URI.create("https://nova-api.trystack.org:9774/v1.1/3456/flavors/detail")).build(), + HttpResponse.builder().statusCode(200).payload(payloadFromResource("/flavor_list_detail_trystack.json")) + .build()).build(); + + ComputeService clientForTryStack = requestsSendResponses(requestResponseMap); + + Template defaultTemplate = clientForTryStack.templateBuilder().imageId("RegionOne/15").build(); + checkTemplate(defaultTemplate); + checkTemplate(clientForTryStack.templateBuilder().fromTemplate(defaultTemplate).build()); + + } + + private void checkTemplate(Template defaultTemplate) { + assertEquals(defaultTemplate.getImage().getId(), "RegionOne/15"); + assertEquals(defaultTemplate.getImage().getProviderId(), "15"); + assertEquals(defaultTemplate.getHardware().getId(), "RegionOne/1"); + assertEquals(defaultTemplate.getHardware().getProviderId(), "1"); + assertEquals(defaultTemplate.getLocation().getId(), "RegionOne"); + assertEquals(getCores(defaultTemplate.getHardware()), 1.0d); + } + public void testListServersWhenReponseIs404IsEmpty() throws Exception { HttpRequest listServers = HttpRequest.builder().method("GET").endpoint( URI.create("https://compute.north.host/v1.1/3456/servers/detail")).headers( @@ -89,8 +129,7 @@ public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTe Map requestResponseMap = ImmutableMap. builder().put( keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess).put(extensionsOfNovaRequest, extensionsOfNovaResponse).put(listImagesDetail, listImagesDetailResponse).put(listServers, - listServersResponse).put(listFlavorsDetail, listFlavorsDetailResponse).put(listFloatingIps, - listFloatingIpsResponse).build(); + listServersResponse).put(listFlavorsDetail, listFlavorsDetailResponse).build(); ComputeService clientThatCreatesNode = requestsSendResponses(requestResponseMap); diff --git a/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/compute/functions/NovaImageToOperatingSystemTest.java b/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/compute/functions/ImageToOperatingSystemTest.java similarity index 73% rename from labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/compute/functions/NovaImageToOperatingSystemTest.java rename to labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/compute/functions/ImageToOperatingSystemTest.java index e2a337b4f5..b3d3a52e15 100644 --- a/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/compute/functions/NovaImageToOperatingSystemTest.java +++ b/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/compute/functions/ImageToOperatingSystemTest.java @@ -44,14 +44,14 @@ import com.google.common.collect.Iterables; * * @author Matt Stephenson */ -public class NovaImageToOperatingSystemTest { +public class ImageToOperatingSystemTest { @Test(dataProvider = "getOsFamilyValues") public void testOsFamilyValues(OsFamily family) { Image imageToConvert = Image.builder().id("id-" + family.name()).name(family.name()).build(); - NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem( + ImageToOperatingSystem converter = new ImageToOperatingSystem( new HashMap>()); OperatingSystem convertedOs = converter.apply(imageToConvert); @@ -84,7 +84,7 @@ public class NovaImageToOperatingSystemTest { Map> osFamilyMap = new HashMap>(); osFamilyMap.put(OsFamily.WINDOWS, ImmutableMap.of("Server 2008 R2", "Server-2008-R2")); - NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(osFamilyMap); + ImageToOperatingSystem converter = new ImageToOperatingSystem(osFamilyMap); OperatingSystem convertedOs = converter.apply(imageToConvert); @@ -105,7 +105,7 @@ public class NovaImageToOperatingSystemTest { Map> osFamilyMap = new HashMap>(); osFamilyMap.put(OsFamily.WINDOWS, ImmutableMap.of("98", "98")); - NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(osFamilyMap); + ImageToOperatingSystem converter = new ImageToOperatingSystem(osFamilyMap); OperatingSystem convertedOs = converter.apply(imageToConvert); @@ -123,7 +123,7 @@ public class NovaImageToOperatingSystemTest { Image imageToConvert = Image.builder().id("id-" + name).name(name).build(); - NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem( + ImageToOperatingSystem converter = new ImageToOperatingSystem( new HashMap>()); OperatingSystem convertedOs = converter.apply(imageToConvert); @@ -142,7 +142,7 @@ public class NovaImageToOperatingSystemTest { Image imageToConvert = Image.builder().id("id-" + name).name(name).build(); - NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem( + ImageToOperatingSystem converter = new ImageToOperatingSystem( new HashMap>()); OperatingSystem convertedOs = converter.apply(imageToConvert); @@ -154,4 +154,42 @@ public class NovaImageToOperatingSystemTest { assertEquals(convertedOs.getArch(), null); assertTrue(convertedOs.is64Bit()); } + + + ImageToOperatingSystem converterForUbuntu = new ImageToOperatingSystem(ImmutableMap.> of( + OsFamily.UBUNTU, ImmutableMap.of("lucid", "10.04", "maverick", "10.10", "natty", "11.04", "oneiric", + "11.10"))); + @Test + public void testTryStackOneric() { + + String name = "oneiric-server-cloudimg-amd64"; + + Image imageToConvert = Image.builder().id("id-" + name).name(name).build(); + + OperatingSystem convertedOs = converterForUbuntu.apply(imageToConvert); + + assertEquals(convertedOs.getName(), imageToConvert.getName()); + assertEquals(convertedOs.getFamily(), OsFamily.UBUNTU); + assertEquals(convertedOs.getDescription(), imageToConvert.getName()); + assertEquals(convertedOs.getVersion(), "11.10"); + assertEquals(convertedOs.getArch(), null); + assertTrue(convertedOs.is64Bit()); + } + + @Test + public void testTryStackNatty() { + + String name = "natty-server-cloudimg-amd64"; + + Image imageToConvert = Image.builder().id("id-" + name).name(name).build(); + + OperatingSystem convertedOs = converterForUbuntu.apply(imageToConvert); + + assertEquals(convertedOs.getName(), imageToConvert.getName()); + assertEquals(convertedOs.getFamily(), OsFamily.UBUNTU); + assertEquals(convertedOs.getDescription(), imageToConvert.getName()); + assertEquals(convertedOs.getVersion(), "11.04"); + assertEquals(convertedOs.getArch(), null); + assertTrue(convertedOs.is64Bit()); + } } diff --git a/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/functions/ExtensionToNameSpaceTest.java b/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/functions/ExtensionToNameSpaceTest.java index e63ff9e777..42a966e035 100644 --- a/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/functions/ExtensionToNameSpaceTest.java +++ b/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/functions/ExtensionToNameSpaceTest.java @@ -4,22 +4,41 @@ import static org.testng.Assert.assertEquals; import java.net.URI; +import javax.inject.Provider; +import javax.ws.rs.core.UriBuilder; + import org.jclouds.date.internal.SimpleDateFormatDateService; import org.jclouds.openstack.nova.v1_1.domain.Extension; +import org.jclouds.openstack.nova.v1_1.extensions.ExtensionNamespaces; import org.testng.annotations.Test; +import com.sun.jersey.api.uri.UriBuilderImpl; + /** * @author Adrian Cole */ @Test(groups = "unit", testName = "ExtensionToNameSpaceTest") public class ExtensionToNameSpaceTest { - private final ExtensionToNameSpace fn = new ExtensionToNameSpace(); + private final ExtensionToNameSpace fn = new ExtensionToNameSpace(new Provider() { + + @Override + public UriBuilder get() { + return new UriBuilderImpl(); + } + + }); public void testReturnsNamespace() { URI ns = URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1"); - assertEquals( - fn.apply(Extension.builder().alias("os-keypairs").name("Keypairs").namespace(ns) - .updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-08-08T00:00:00+00:00")) - .description("Keypair Support").build()), ns); + assertEquals(fn.apply(Extension.builder().alias("os-keypairs").name("Keypairs").namespace(ns).updated( + new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-08-08T00:00:00+00:00")).description( + "Keypair Support").build()), ns); + } + + public void testChangesHttpsToHttp() { + assertEquals(fn.apply(Extension.builder().alias("security_groups").name("SecurityGroups").namespace( + URI.create("https://docs.openstack.org/ext/securitygroups/api/v1.1")).updated( + new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-07-21T00:00:00+00:00")).description( + "Security group support").build()), URI.create(ExtensionNamespaces.SECURITY_GROUPS)); } } diff --git a/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/parse/ParseServerWithInternetAddressesTest.java b/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/parse/ParseServerWithInternetAddressesTest.java new file mode 100644 index 0000000000..b5272f2cbc --- /dev/null +++ b/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/parse/ParseServerWithInternetAddressesTest.java @@ -0,0 +1,100 @@ +/** + * 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.openstack.nova.v1_1.parse; + +import java.net.URI; + +import javax.ws.rs.Consumes; +import javax.ws.rs.core.MediaType; + +import org.jclouds.date.internal.SimpleDateFormatDateService; +import org.jclouds.json.BaseItemParserTest; +import org.jclouds.json.config.GsonModule; +import org.jclouds.openstack.domain.Link; +import org.jclouds.openstack.domain.Resource; +import org.jclouds.openstack.domain.Link.Relation; +import org.jclouds.openstack.nova.v1_1.config.NovaParserModule; +import org.jclouds.openstack.nova.v1_1.domain.Address; +import org.jclouds.openstack.nova.v1_1.domain.Server; +import org.jclouds.openstack.nova.v1_1.domain.Server.Status; +import org.jclouds.rest.annotations.SelectJson; +import org.testng.annotations.Test; + +import com.google.inject.Guice; +import com.google.inject.Injector; + +/** + * @author Adrian Cole + */ +@Test(groups = "unit", testName = "ParseServerTest") +public class ParseServerWithInternetAddressesTest extends BaseItemParserTest { + + @Override + public String resource() { + return "/server_details_trystack.json"; + } + + @Override + @SelectJson("server") + @Consumes(MediaType.APPLICATION_JSON) + public Server expected() { + return Server + .builder() + .id("1459") + .uuid("2443c9c7-9791-412e-ac09-a6d55ec25335") + .tenantId("37") + .userId("508151008") + .name("mygroup-72c") + .updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-03-23T01:30:26Z")) + .created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-03-23T01:30:26Z")) + .hostId("881706597197955ac7cc4b353bc7ec884e13fa280de9cc82057796cb") + .status(Status.ACTIVE) + .image( + Resource + .builder() + .id("14") + .links( + Link.create( + Relation.BOOKMARK, + URI.create("https://nova-api.trystack.org:9774/37/images/14"))) + .build()) + .flavor( + Resource + .builder() + .id("1") + .links( + Link.create( + Relation.BOOKMARK, + URI.create("https://nova-api.trystack.org:9774/37/flavors/1"))) + .build()) + .links( + Link.create( + Relation.SELF, + URI.create("https://nova-api.trystack.org:9774/v1.1/37/servers/1459")), + Link.create( + Relation.BOOKMARK, + URI.create("https://nova-api.trystack.org:9774/37/servers/1459"))) + .internetAddresses(Address.createV4("8.21.28.47")).build(); + } + + + protected Injector injector() { + return Guice.createInjector(new NovaParserModule(), new GsonModule()); + } +} diff --git a/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/predicates/ExtensionPredicatesTest.java b/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/predicates/ExtensionPredicatesTest.java index eb0efa9262..6bd9f49686 100644 --- a/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/predicates/ExtensionPredicatesTest.java +++ b/labs/openstack-nova/src/test/java/org/jclouds/openstack/nova/v1_1/predicates/ExtensionPredicatesTest.java @@ -33,10 +33,10 @@ import org.testng.annotations.Test; */ @Test(groups = "unit", testName = "ExtensionPredicatesTest") public class ExtensionPredicatesTest { - Extension ref = Extension.builder().alias("os-keypairs").name("Keypairs") - .namespace(URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1")) - .updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-08-08T00:00:00+00:00")) - .description("Keypair Support").build(); + Extension ref = Extension.builder().alias("os-keypairs").name("Keypairs").namespace( + URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1")).updated( + new SimpleDateFormatDateService().iso8601SecondsDateParse("2011-08-08T00:00:00+00:00")).description( + "Keypair Support").build(); @Test public void testAliasEqualsWhenEqual() { @@ -53,6 +53,12 @@ public class ExtensionPredicatesTest { assert namespaceEquals(URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1")).apply(ref); } + @Test + public void testNamespaceEqualsWhenEqualEvenOnInputHttps() { + assert namespaceEquals(URI.create("http://docs.openstack.org/ext/keypairs/api/v1.1")).apply( + ref.toBuilder().namespace(URI.create("https://docs.openstack.org/ext/keypairs/api/v1.1")).build()); + } + @Test public void testNamespaceEqualsWhenNotEqual() { assert !namespaceEquals(URI.create("foo")).apply(ref); diff --git a/labs/openstack-nova/src/test/resources/extension_list_trystack.json b/labs/openstack-nova/src/test/resources/extension_list_trystack.json new file mode 100644 index 0000000000..0144af6ae4 --- /dev/null +++ b/labs/openstack-nova/src/test/resources/extension_list_trystack.json @@ -0,0 +1,115 @@ +{ + "extensions": [{ + "updated": "2011-06-09T00:00:00+00:00", + "name": "Multinic", + "links": [], + "namespace": "https://docs.openstack.org/ext/multinic/api/v1.1", + "alias": "NMN", + "description": "Multiple network support" + }, { + "updated": "2011-06-29T00:00:00+00:00", + "name": "Hosts", + "links": [], + "namespace": "https://docs.openstack.org/ext/hosts/api/v1.1", + "alias": "os-hosts", + "description": "Host administration" + }, { + "updated": "2011-03-25T00:00:00+00:00", + "name": "Volumes", + "links": [], + "namespace": "https://docs.openstack.org/ext/volumes/api/v1.1", + "alias": "os-volumes", + "description": "Volumes support" + }, { + "updated": "2011-05-25 16:12:21.656723", + "name": "Admin Controller", + "links": [], + "namespace": "https:TODO/", + "alias": "ADMIN", + "description": "The Admin API Extension" + }, { + "updated": "2011-08-08T00:00:00+00:00", + "name": "Quotas", + "links": [], + "namespace": "https://docs.openstack.org/ext/quotas-sets/api/v1.1", + "alias": "os-quota-sets", + "description": "Quotas management support" + }, { + "updated": "2011-08-24T00:00:00+00:00", + "name": "VolumeTypes", + "links": [], + "namespace": "https://docs.openstack.org/ext/volume_types/api/v1.1", + "alias": "os-volume-types", + "description": "Volume types support" + }, { + "updated": "2011-06-23T00:00:00+00:00", + "name": "FlavorExtraSpecs", + "links": [], + "namespace": "https://docs.openstack.org/ext/flavor_extra_specs/api/v1.1", + "alias": "os-flavor-extra-specs", + "description": "Instance type (flavor) extra specs" + }, { + "updated": "2011-09-14T00:00:00+00:00", + "name": "FlavorExtraData", + "links": [], + "namespace": "https://docs.openstack.org/ext/flavor_extra_data/api/v1.1", + "alias": "os-flavor-extra-data", + "description": "Provide additional data for flavors" + }, { + "updated": "2011-08-17T00:00:00+00:00", + "name": "VirtualInterfaces", + "links": [], + "namespace": "https://docs.openstack.org/ext/virtual_interfaces/api/v1.1", + "alias": "virtual_interfaces", + "description": "Virtual interface support" + }, { + "updated": "2011-07-19T00:00:00+00:00", + "name": "Createserverext", + "links": [], + "namespace": "https://docs.openstack.org/ext/createserverext/api/v1.1", + "alias": "os-create-server-ext", + "description": "Extended support to the Create Server v1.1 API" + }, { + "updated": "2011-08-08T00:00:00+00:00", + "name": "Keypairs", + "links": [], + "namespace": "https://docs.openstack.org/ext/keypairs/api/v1.1", + "alias": "os-keypairs", + "description": "Keypair Support" + }, { + "updated": "2011-08-25T00:00:00+00:00", + "name": "VSAs", + "links": [], + "namespace": "https://docs.openstack.org/ext/vsa/api/v1.1", + "alias": "zadr-vsa", + "description": "Virtual Storage Arrays support" + }, { + "updated": "2011-08-19T00:00:00+00:00", + "name": "SimpleTenantUsage", + "links": [], + "namespace": "https://docs.openstack.org/ext/os-simple-tenant-usage/api/v1.1", + "alias": "os-simple-tenant-usage", + "description": "Simple tenant usage extension" + }, { + "updated": "2011-08-18T00:00:00+00:00", + "name": "Rescue", + "links": [], + "namespace": "https://docs.openstack.org/ext/rescue/api/v1.1", + "alias": "os-rescue", + "description": "Instance rescue mode" + }, { + "updated": "2011-07-21T00:00:00+00:00", + "name": "SecurityGroups", + "links": [], + "namespace": "https://docs.openstack.org/ext/securitygroups/api/v1.1", + "alias": "security_groups", + "description": "Security group support" + }, { + "updated": "2011-06-16T00:00:00+00:00", + "name": "Floating_ips", + "links": [], + "namespace": "https://docs.openstack.org/ext/floating_ips/api/v1.1", + "alias": "os-floating-ips", + "description": "Floating IPs support" + }] +} \ No newline at end of file diff --git a/labs/openstack-nova/src/test/resources/flavor_list_detail_trystack.json b/labs/openstack-nova/src/test/resources/flavor_list_detail_trystack.json new file mode 100644 index 0000000000..c0377d1df6 --- /dev/null +++ b/labs/openstack-nova/src/test/resources/flavor_list_detail_trystack.json @@ -0,0 +1,83 @@ +{ + "flavors": [{ + "rxtx_quota": 0, + "name": "m1.medium", + "links": [{ + "href": "https://nova-api.trystack.org:9774/v1.1/37/flavors/3", + "rel": "self" + }, { + "href": "https://nova-api.trystack.org:9774/37/flavors/3", + "rel": "bookmark" + }], + "ram": 4096, + "vcpus": 2, + "rxtx_cap": 0, + "swap": 0, + "disk": 40, + "id": 3 + }, { + "rxtx_quota": 0, + "name": "m1.large", + "links": [{ + "href": "https://nova-api.trystack.org:9774/v1.1/37/flavors/4", + "rel": "self" + }, { + "href": "https://nova-api.trystack.org:9774/37/flavors/4", + "rel": "bookmark" + }], + "ram": 8192, + "vcpus": 4, + "rxtx_cap": 0, + "swap": 0, + "disk": 80, + "id": 4 + }, { + "rxtx_quota": 0, + "name": "m1.tiny", + "links": [{ + "href": "https://nova-api.trystack.org:9774/v1.1/37/flavors/1", + "rel": "self" + }, { + "href": "https://nova-api.trystack.org:9774/37/flavors/1", + "rel": "bookmark" + }], + "ram": 512, + "vcpus": 1, + "rxtx_cap": 0, + "swap": 0, + "disk": 0, + "id": 1 + }, { + "rxtx_quota": 0, + "name": "m1.xlarge", + "links": [{ + "href": "https://nova-api.trystack.org:9774/v1.1/37/flavors/5", + "rel": "self" + }, { + "href": "https://nova-api.trystack.org:9774/37/flavors/5", + "rel": "bookmark" + }], + "ram": 16384, + "vcpus": 8, + "rxtx_cap": 0, + "swap": 0, + "disk": 160, + "id": 5 + }, { + "rxtx_quota": 0, + "name": "m1.small", + "links": [{ + "href": "https://nova-api.trystack.org:9774/v1.1/37/flavors/2", + "rel": "self" + }, { + "href": "https://nova-api.trystack.org:9774/37/flavors/2", + "rel": "bookmark" + }], + "ram": 2048, + "vcpus": 1, + "rxtx_cap": 0, + "swap": 0, + "disk": 20, + "id": 2 + }] +} \ No newline at end of file diff --git a/labs/openstack-nova/src/test/resources/image_list_detail_trystack.json b/labs/openstack-nova/src/test/resources/image_list_detail_trystack.json new file mode 100644 index 0000000000..1be3de21f2 --- /dev/null +++ b/labs/openstack-nova/src/test/resources/image_list_detail_trystack.json @@ -0,0 +1,81 @@ +{ + "images": [{ + "status": "ACTIVE", + "updated": "2012-02-02T19:11:00Z", + "name": "oneiric-server-cloudimg-amd64", + "links": [{ + "href": "https://nova-api.trystack.org:9774/v1.1/37/images/15", + "rel": "self" + }, { + "href": "https://nova-api.trystack.org:9774/37/images/15", + "rel": "bookmark" + }], + "created": "2012-02-02T19:10:52Z", + "progress": 100, + "id": "15", + "metadata": { + "kernel_id": "14", + "min_disk": 0, + "min_ram": 0, + "owner": "1" + } + }, { + "status": "ACTIVE", + "updated": "2012-02-02T19:10:51Z", + "name": "oneiric-server-cloudimg-amd64-kernel", + "links": [{ + "href": "https://nova-api.trystack.org:9774/v1.1/37/images/14", + "rel": "self" + }, { + "href": "https://nova-api.trystack.org:9774/37/images/14", + "rel": "bookmark" + }], + "created": "2012-02-02T19:10:50Z", + "progress": 100, + "id": "14", + "metadata": { + "min_disk": 0, + "owner": "1", + "min_ram": 0 + } + }, { + "status": "ACTIVE", + "updated": "2012-02-02T19:10:41Z", + "name": "natty-server-cloudimg-amd64", + "links": [{ + "href": "https://nova-api.trystack.org:9774/v1.1/37/images/13", + "rel": "self" + }, { + "href": "https://nova-api.trystack.org:9774/37/images/13", + "rel": "bookmark" + }], + "created": "2012-02-02T19:10:33Z", + "progress": 100, + "id": "13", + "metadata": { + "kernel_id": "12", + "min_disk": 0, + "min_ram": 0, + "owner": "1" + } + }, { + "status": "ACTIVE", + "updated": "2012-02-02T19:10:33Z", + "name": "natty-server-cloudimg-amd64-kernel", + "links": [{ + "href": "https://nova-api.trystack.org:9774/v1.1/37/images/12", + "rel": "self" + }, { + "href": "https://nova-api.trystack.org:9774/37/images/12", + "rel": "bookmark" + }], + "created": "2012-02-02T19:10:32Z", + "progress": 100, + "id": "12", + "metadata": { + "min_disk": 0, + "owner": "1", + "min_ram": 0 + } + }] +} \ No newline at end of file diff --git a/labs/openstack-nova/src/test/resources/server_details_trystack.json b/labs/openstack-nova/src/test/resources/server_details_trystack.json new file mode 100644 index 0000000000..2918b02190 --- /dev/null +++ b/labs/openstack-nova/src/test/resources/server_details_trystack.json @@ -0,0 +1,46 @@ +{ + "server": { + "status": "ACTIVE", + "updated": "2012-03-23T01:30:26Z", + "hostId": "881706597197955ac7cc4b353bc7ec884e13fa280de9cc82057796cb", + "user_id": "508151008", + "name": "mygroup-72c", + "links": [{ + "href": "https://nova-api.trystack.org:9774/v1.1/37/servers/1459", + "rel": "self" + }, { + "href": "https://nova-api.trystack.org:9774/37/servers/1459", + "rel": "bookmark" + }], + "addresses": { + "internet": [{ + "version": 4, + "addr": "8.21.28.47" + }] + }, + "tenant_id": "37", + "image": { + "id": "14", + "links": [{ + "href": "https://nova-api.trystack.org:9774/37/images/14", + "rel": "bookmark" + }] + }, + "created": "2012-03-23T01:30:26Z", + "uuid": "2443c9c7-9791-412e-ac09-a6d55ec25335", + "accessIPv4": "", + "accessIPv6": "", + "key_name": null, + "progress": 100, + "flavor": { + "id": "1", + "links": [{ + "href": "https://nova-api.trystack.org:9774/37/flavors/1", + "rel": "bookmark" + }] + }, + "config_drive": "", + "id": 1459, + "metadata": {} + } +} \ No newline at end of file