stable glesys

This commit is contained in:
Adrian Cole 2012-09-16 21:29:26 -07:00
parent 8ca0dc3c1d
commit 63f1d334f2
20 changed files with 152 additions and 96 deletions

View File

@ -36,10 +36,10 @@
<properties>
<test.glesys.endpoint>https://api.glesys.com</test.glesys.endpoint>
<test.glesys.api-version>1</test.glesys.api-version>
<test.glesys.build-version></test.glesys.build-version>
<test.glesys.build-version>3.5.0</test.glesys.build-version>
<test.glesys.identity>FIXME</test.glesys.identity>
<test.glesys.credential>FIXME</test.glesys.credential>
<test.glesys.template></test.glesys.template>
<test.glesys.template>osFamily=UBUNTU,osVersionMatches=1[012].[01][04],os64Bit=true,minRam=768</test.glesys.template>
<jclouds.osgi.export>org.jclouds.glesys*;version="${project.version}"</jclouds.osgi.export>
<jclouds.osgi.import>org.jclouds*;version="${project.version}",*</jclouds.osgi.import>
</properties>

View File

@ -78,6 +78,7 @@ public class GleSYSApiMetadata extends BaseRestApiMetadata {
.credentialName("API Key")
.documentation(URI.create("https://customer.glesys.com/api.php"))
.version("1")
.buildVersion("3.5.0")
.defaultEndpoint("https://api.glesys.com")
.defaultProperties(GleSYSApiMetadata.defaultProperties())
.view(TypeToken.of(ComputeServiceContext.class))

View File

@ -62,7 +62,7 @@ public class GleSYSProviderMetadata extends BaseProviderMetadata {
properties.setProperty(PROPERTY_ZONE + ".Falkenberg." + ISO3166_CODES, "SE-N");
properties.setProperty(PROPERTY_ZONE + ".New York City." + ISO3166_CODES, "US-NY");
properties.setProperty(PROPERTY_ZONE + ".Stockholm." + ISO3166_CODES, "SE-AB");
properties.setProperty(TEMPLATE, "minRam=512,osFamily=UBUNTU,hypervisorMatches=OpenVZ,osVersionMatches=1[012].[01][04],os64Bit=true,locationId=Falkenberg");
properties.setProperty(TEMPLATE, "osFamily=UBUNTU,osVersionMatches=1[012].[01][04],os64Bit=true,minRam=768");
return properties;
}

View File

@ -20,8 +20,10 @@ package org.jclouds.glesys.compute;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.jclouds.compute.util.ComputeServiceUtils.metadataAndTagsAsCommaDelimitedValue;
import static org.jclouds.concurrent.FutureIterables.transformParallel;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ExecutorService;
@ -47,6 +49,7 @@ import org.jclouds.compute.domain.internal.VolumeImpl;
import org.jclouds.compute.predicates.ImagePredicates;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
import org.jclouds.crypto.CryptoStreams;
import org.jclouds.domain.Location;
import org.jclouds.domain.LoginCredentials;
import org.jclouds.glesys.GleSYSApi;
@ -64,7 +67,9 @@ import org.jclouds.logging.Logger;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.util.Iterables2;
import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
@ -115,8 +120,12 @@ public class GleSYSComputeServiceAdapter implements ComputeServiceAdapter<Server
CreateServerOptions createServerOptions = new CreateServerOptions();
createServerOptions.ip(templateOptions.getIp());
createServerOptions.description(name); // TODO: add to templateOptions and
// set if present
Map<String, String> md = metadataAndTagsAsCommaDelimitedValue(template.getOptions());
if (md.size() > 0) {
String description = Joiner.on('\n').withKeyValueSeparator("=").join(md);
// TODO: get glesys to stop stripping out equals and commas!
createServerOptions.description(CryptoStreams.hex(description.getBytes(Charsets.UTF_8)));
}
ServerSpec.Builder<?> builder = ServerSpec.builder();
builder.datacenter(template.getLocation().getId());

View File

@ -19,6 +19,9 @@
package org.jclouds.glesys.compute.functions;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Strings.isNullOrEmpty;
import static org.jclouds.compute.util.ComputeServiceUtils.addMetadataAndParseTagsFromCommaDelimitedValue;
import java.util.Map;
import java.util.NoSuchElementException;
@ -42,15 +45,18 @@ import org.jclouds.compute.domain.Volume;
import org.jclouds.compute.domain.internal.VolumeImpl;
import org.jclouds.compute.functions.GroupNamingConvention;
import org.jclouds.compute.reference.ComputeServiceConstants;
import org.jclouds.crypto.CryptoStreams;
import org.jclouds.domain.Location;
import org.jclouds.glesys.domain.Ip;
import org.jclouds.glesys.domain.ServerDetails;
import org.jclouds.logging.Logger;
import org.jclouds.util.InetAddresses2.IsPrivateIPAddress;
import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableList;
@ -104,8 +110,15 @@ public class ServerDetailsToNodeMetadata implements Function<ServerDetails, Node
builder.name(from.getHostname());
builder.hostname(from.getHostname());
Location location = findLocationForServerDetails.apply(from);
assert (location != null) : String.format("no location matched ServerDetails %s", from);
builder.group(nodeNamingConvention.groupInUniqueNameOrNull(from.getDescription()));
checkState(location != null, "no location matched ServerDetails %s", from);
builder.group(nodeNamingConvention.groupInUniqueNameOrNull(from.getHostname()));
// TODO: get glesys to stop stripping out equals and commas!
if (!isNullOrEmpty(from.getDescription()) && from.getDescription().matches("^[0-9A-Fa-f]+$")) {
String decoded = new String(CryptoStreams.hex(from.getDescription()), Charsets.UTF_8);
addMetadataAndParseTagsFromCommaDelimitedValue(builder,
Splitter.on('\n').withKeyValueSeparator("=").split(decoded));
}
builder.imageId(from.getTemplateName() + "");
builder.operatingSystem(parseOperatingSystem(from));
builder.hardware(new HardwareBuilder().ids(from.getId() + "").ram(from.getMemorySizeMB())

View File

@ -30,6 +30,7 @@ import org.jclouds.glesys.domain.EmailOverview;
import org.jclouds.glesys.options.CreateAccountOptions;
import org.jclouds.glesys.options.UpdateAccountOptions;
import org.jclouds.http.filters.BasicAuthentication;
import org.jclouds.http.functions.ReturnTrueOn404;
import org.jclouds.rest.annotations.ExceptionParser;
import org.jclouds.rest.annotations.RequestFilters;
import org.jclouds.rest.annotations.SelectJson;
@ -121,6 +122,7 @@ public interface EmailAccountAsyncApi {
*/
@POST
@Path("/email/delete/format/json")
@ExceptionParser(ReturnTrueOn404.class)
ListenableFuture<Boolean> delete(@FormParam("email") String accountAddress);
}

View File

@ -42,6 +42,10 @@ public class GleSYSTypeAdapters {
@Override
public Server.State read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return Server.State.UNRECOGNIZED;
}
return Server.State.fromValue(reader.nextString());
}
}

View File

@ -56,12 +56,16 @@ public class GleSYSErrorHandler implements HttpErrorHandler {
exception = new AuthorizationException(message, exception);
break;
case 400:
if (message.indexOf("Could not find") != -1) {
if (message.indexOf("not find") != -1) {
exception = new ResourceNotFoundException(message, exception);
}
break;
case 404:
if (message.indexOf("Not supported") != -1) {
exception = new UnsupportedOperationException(message, exception);
} else {
exception = new ResourceNotFoundException(message, exception);
}
break;
case 500:
if (message.indexOf("Locked") != -1) {

View File

@ -70,8 +70,8 @@ public class GleSYSTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
return input.version.equals("") || input.version.equals("5") || input.version.equals("5.5")
|| input.version.equals("5.0") || input.version.equals("6.0");
case WINDOWS:
return input.version.equals("") || input.version.equals("2008")
|| (input.version.equals("2008 R2") && input.is64Bit);
return (input.version.equals("") || input.version.equals("2008")
|| input.version.equals("2008 R2")) && input.is64Bit;
default:
return false;
}
@ -83,13 +83,13 @@ public class GleSYSTemplateBuilderLiveTest extends BaseTemplateBuilderLiveTest {
@Test
public void testDefaultTemplateBuilder() throws IOException {
Template defaultTemplate = view.getComputeService().templateBuilder().build();
assertEquals(defaultTemplate.getImage().getId(), "Ubuntu 12.04 LTS 64-bit");
assertEquals(defaultTemplate.getImage().getId(), "Ubuntu 12.04 x64");
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "12.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(), "OpenVZ");
assertEquals(defaultTemplate.getHardware().getRam(), 768);
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

View File

@ -79,9 +79,9 @@ public class ServerDetailsToNodeMetadataTest extends BaseGleSYSComputeServiceExp
actual.toString(),
new NodeMetadataBuilder()
.ids("vz1840356")
.name("test-email-jclouds")
.hostname("test-email-jclouds")
.group("glesys-s")
.name("glesys-s")
.hostname("glesys-s")
.group("glesys")
.imageId("Ubuntu 10.04 LTS 32-bit")
.operatingSystem(
OperatingSystem.builder().name("Ubuntu 10.04 LTS 32-bit").family(OsFamily.UBUNTU).version("10.04")

View File

@ -29,7 +29,7 @@ import org.jclouds.glesys.domain.ArchiveAllowedArguments;
import org.jclouds.glesys.internal.BaseGleSYSApiLiveTest;
import org.jclouds.predicates.RetryablePredicate;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
@ -42,7 +42,7 @@ import com.google.common.base.Predicate;
@Test(groups = "live", testName = "ArchiveApiLiveTest", singleThreaded = true)
public class ArchiveApiLiveTest extends BaseGleSYSApiLiveTest {
@BeforeGroups(groups = {"live"})
@BeforeClass(groups = { "integration", "live" })
public void setupContext() {
super.setupContext();

View File

@ -31,8 +31,8 @@ import org.jclouds.glesys.internal.BaseGleSYSApiLiveTest;
import org.jclouds.glesys.options.DomainOptions;
import org.jclouds.glesys.options.UpdateRecordOptions;
import org.jclouds.predicates.RetryablePredicate;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
@ -46,7 +46,7 @@ import com.google.common.base.Predicate;
public class DomainApiLiveTest extends BaseGleSYSApiLiveTest {
public String testDomain;
@BeforeGroups(groups = {"live"})
@BeforeClass(groups = { "integration", "live" })
public void setupContext() {
super.setupContext();
testDomain = identity.toLowerCase() + "-domain.jclouds.org";
@ -72,7 +72,7 @@ public class DomainApiLiveTest extends BaseGleSYSApiLiveTest {
createDomain(testDomain);
}
@AfterGroups(groups = {"live"})
@AfterClass(groups = { "integration", "live" })
public void tearDownContext() {
int before = api.list().size();
api.delete(testDomain);

View File

@ -255,8 +255,7 @@ public class EmailAccountApiExpectTest extends BaseGleSYSApiExpectTest {
api.delete("test2@jclouds.org");
}
@Test(expectedExceptions = {ResourceNotFoundException.class})
public void testDeleteWhenResponseIs4xxThrows() throws Exception {
public void testDeleteWhenResponseIs4xxOk() throws Exception {
EmailAccountApi api = requestSendsResponse(
HttpRequest.builder().method("POST").endpoint("https://api.glesys.com/email/delete/format/json")
.addHeader("Authorization", "Basic aWRlbnRpdHk6Y3JlZGVudGlhbA==")

View File

@ -29,12 +29,12 @@ import org.jclouds.glesys.domain.EmailAccount;
import org.jclouds.glesys.domain.EmailAlias;
import org.jclouds.glesys.domain.EmailOverview;
import org.jclouds.glesys.domain.EmailOverviewDomain;
import org.jclouds.glesys.internal.BaseGleSYSApiWithAServerLiveTest;
import org.jclouds.glesys.internal.BaseGleSYSApiLiveTest;
import org.jclouds.glesys.options.CreateAccountOptions;
import org.jclouds.glesys.options.UpdateAccountOptions;
import org.jclouds.predicates.RetryablePredicate;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
@ -47,17 +47,22 @@ import com.google.common.collect.Iterables;
* @author Adam Lowe
*/
@Test(groups = "live", testName = "EmailAccountApiLiveTest", singleThreaded = true)
public class EmailAccountApiLiveTest extends BaseGleSYSApiWithAServerLiveTest {
public class EmailAccountApiLiveTest extends BaseGleSYSApiLiveTest {
public EmailAccountApiLiveTest() {
hostName = hostName + "-email";
}
@BeforeGroups(groups = {"live"})
public void setupDomains() {
testDomain = identity + ".test.jclouds.org";
@BeforeClass(groups = { "integration", "live" })
@Override
public void setupContext() {
super.setupContext();
testDomain = hostName + ".test.jclouds.org";
api = gleContext.getApi().getEmailAccountApi();
deleteAll();
createDomain(testDomain);
emailAccountCounter = new RetryablePredicate<Integer>(
new Predicate<Integer>() {
emailAccountCounter = new RetryablePredicate<Integer>(new Predicate<Integer>() {
public boolean apply(Integer value) {
return api.listDomain(testDomain).size() == value;
}
@ -65,18 +70,18 @@ public class EmailAccountApiLiveTest extends BaseGleSYSApiWithAServerLiveTest {
assertTrue(emailAccountCounter.apply(0));
try {
api.delete("test2@" + testDomain);
} catch(Exception e) {
}
}
@AfterGroups(groups = {"live"})
public void tearDownDomains() {
@AfterClass(groups = { "integration", "live" })
@Override
public void tearDownContext() {
deleteAll();
super.tearDownContext();
}
private void deleteAll() {
api.delete("test@" + testDomain);
api.delete("test1@" + testDomain);
assertTrue(emailAccountCounter.apply(0));
gleContext.getApi().getEmailAccountApi().delete(testDomain);
}
private EmailAccountApi api;
@ -85,8 +90,8 @@ public class EmailAccountApiLiveTest extends BaseGleSYSApiWithAServerLiveTest {
@Test
public void testCreateEmail() {
api.createWithPassword("test@" + testDomain, "password",
CreateAccountOptions.Builder.antiVirus(true).autorespond(true).autorespondMessage("out of office"));
api.createWithPassword("test@" + testDomain, "password", CreateAccountOptions.Builder.antiVirus(true)
.autorespond(true).autorespondMessage("out of office"));
assertTrue(emailAccountCounter.apply(1));

View File

@ -29,8 +29,8 @@ import java.util.Set;
import org.jclouds.glesys.domain.IpDetails;
import org.jclouds.glesys.internal.BaseGleSYSApiWithAServerLiveTest;
import org.jclouds.glesys.options.ListIpOptions;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.collect.FluentIterable;
@ -44,17 +44,24 @@ import com.google.common.collect.Sets;
*/
@Test(groups = "live", testName = "IpApiLiveTest", singleThreaded = true)
public class IpApiLiveTest extends BaseGleSYSApiWithAServerLiveTest {
public IpApiLiveTest() {
hostName = hostName + "-ip";
}
@BeforeMethod
public void setupApi() {
@BeforeClass(groups = { "integration", "live" })
@Override
public void setupContext() {
super.setupContext();
api = gleContext.getApi().getIpApi();
}
@AfterGroups(groups = {"live"})
public void releaseIp() {
@AfterClass(groups = { "integration", "live" })
@Override
public void tearDownContext() {
if (reservedIp != null) {
api.release(reservedIp.getAddress());
}
super.tearDownContext();
}
private IpApi api;
@ -185,7 +192,6 @@ public class IpApiLiveTest extends BaseGleSYSApiWithAServerLiveTest {
assertNull(removed.getServerId());
assertFalse(removed.isReserved());
// reserve an address again!
reserveIp();
}

View File

@ -166,7 +166,7 @@ public class ServerApiExpectTest extends BaseGleSYSApiExpectTest {
public static ServerDetails expectedServerDetails() {
Ip ip = Ip.builder().version4().ip("31.192.231.254").version4().cost(2.0).currency("EUR").build();
Cost cost = Cost.builder().amount(10.22).currency("EUR").timePeriod("month").build();
return ServerDetails.builder().id("vz1840356").transferGB(50).hostname("test-email-jclouds").cpuCores(1).memorySizeMB(512)
return ServerDetails.builder().id("vz1840356").transferGB(50).hostname("glesys-s").cpuCores(1).memorySizeMB(512)
.diskSizeGB(5).datacenter("Falkenberg").description("glesys-s-6dd").platform("OpenVZ")
.templateName("Ubuntu 10.04 LTS 32-bit").state(Server.State.RUNNING).cost(cost).ips(ip).build();
}

View File

@ -40,7 +40,8 @@ import org.jclouds.glesys.options.DestroyServerOptions;
import org.jclouds.glesys.options.ServerStatusOptions;
import org.jclouds.glesys.options.UpdateServerOptions;
import org.jclouds.predicates.RetryablePredicate;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@ -57,16 +58,21 @@ import com.google.common.collect.FluentIterable;
public class ServerApiLiveTest extends BaseGleSYSApiWithAServerLiveTest {
public static final String testHostName2 = "jclouds-test2";
@BeforeMethod
public void setupApi() {
@BeforeClass(groups = { "integration", "live" })
@Override
public void setupContext() {
hostName = hostName + "-server";
super.setupContext();
api = gleContext.getApi().getServerApi();
}
@AfterGroups(groups = {"live"})
public void deleteExtraServer() {
@AfterClass(groups = { "integration", "live" })
@Override
public void tearDownContext() {
if (testServerId2 != null) {
api.destroy(testServerId2, DestroyServerOptions.Builder.discardIp());
}
super.tearDownContext();
}
private ServerApi api;
@ -205,13 +211,20 @@ public class ServerApiLiveTest extends BaseGleSYSApiWithAServerLiveTest {
public void testResourceUsage() throws Exception {
// test server has only been in existence for less than a minute - check all servers
for (Server server : api.list()) {
try {
ResourceUsage usage = api.getResourceUsage(server.getId(), "diskioread", "minute");
assertEquals(usage.getInfo().getResource(), "diskioread");
assertEquals(usage.getInfo().getResolution(), "minute");
} catch (UnsupportedOperationException e) {
usage = api.getResourceUsage(server.getId(), "cpuusage", "minute");
}
try {
ResourceUsage usage = api.getResourceUsage(server.getId(), "cpuusage", "minute");
assertEquals(usage.getInfo().getResource(), "cpuusage");
assertEquals(usage.getInfo().getResolution(), "minute");
} catch (UnsupportedOperationException e) {
}
}
}

View File

@ -28,7 +28,7 @@ import org.jclouds.glesys.GleSYSAsyncApi;
import org.jclouds.glesys.features.DomainApi;
import org.jclouds.predicates.RetryablePredicate;
import org.jclouds.rest.RestContext;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
@ -40,6 +40,7 @@ import com.google.common.base.Predicate;
*/
@Test(groups = "live")
public class BaseGleSYSApiLiveTest extends BaseComputeServiceContextLiveTest {
protected String hostName = System.getProperty("user.name").replace('.','-').toLowerCase();
protected RestContext<GleSYSApi, GleSYSAsyncApi> gleContext;
@ -47,7 +48,7 @@ public class BaseGleSYSApiLiveTest extends BaseComputeServiceContextLiveTest {
provider = "glesys";
}
@BeforeGroups(groups = { "integration", "live" })
@BeforeClass(groups = { "integration", "live" })
@Override
public void setupContext() {
super.setupContext();

View File

@ -36,8 +36,8 @@ import org.jclouds.glesys.features.ServerApi;
import org.jclouds.glesys.options.DestroyServerOptions;
import org.jclouds.glesys.options.ServerStatusOptions;
import org.jclouds.predicates.RetryablePredicate;
import org.testng.annotations.AfterGroups;
import org.testng.annotations.BeforeGroups;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import com.google.common.base.Predicate;
@ -50,25 +50,24 @@ import com.google.common.base.Predicate;
@Test(groups = "live", singleThreaded = true)
public class BaseGleSYSApiWithAServerLiveTest extends BaseGleSYSApiLiveTest {
protected String serverId;
protected String hostName = "test-server-jclouds";
protected ServerStatusChecker serverStatusChecker;
public BaseGleSYSApiWithAServerLiveTest() {
provider = "glesys";
}
@BeforeGroups(groups = { "integration", "live" })
@BeforeClass(groups = { "integration", "live" })
@Override
public final void setupContext() {
public void setupContext() {
assertNull(serverId, "This method should be called EXACTLY once per run");
super.setupContext();
serverStatusChecker = createServer(hostName);
serverId = serverStatusChecker.getServerId();
}
@AfterGroups(groups = {"integration", "live"})
@AfterClass(groups = { "integration", "live" })
@Override
public final void tearDownContext() {
public void tearDownContext() {
gleContext.getApi().getServerApi().destroy(serverId, DestroyServerOptions.Builder.discardIp());
super.tearDownContext();
}
@ -98,7 +97,7 @@ public class BaseGleSYSApiWithAServerLiveTest extends BaseGleSYSApiLiveTest {
assertEquals(testServer.getHostname(), hostName);
assertFalse(testServer.getIps().isEmpty());
ServerStatusChecker runningServerCounter = new ServerStatusChecker(api, testServer.getId(), 180, 10,
ServerStatusChecker runningServerCounter = new ServerStatusChecker(api, testServer.getId(), 300, 10,
TimeUnit.SECONDS);
assertTrue(runningServerCounter.apply(Server.State.RUNNING));

View File

@ -1,7 +1,7 @@
{"response":{"status":{"code":200,"timestamp":"2012-06-21T14:10:57+02:00","text":"OK"},
"server":{
"serverid":"vz1840356",
"hostname":"test-email-jclouds",
"hostname":"glesys-s",
"description":"glesys-s-6dd",
"cpucores":1,
"memorysize":512,