mirror of https://github.com/apache/jclouds.git
[JCLOUDS-1079] Make Floating IPs public in the NodeMetadata in openstack-nova provider
This commit is contained in:
parent
8bbcfed312
commit
e0ab5d848a
|
@ -18,7 +18,9 @@ package org.jclouds.openstack.nova.v2_0.compute.functions;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
|
import static com.google.common.base.Predicates.and;
|
||||||
import static com.google.common.base.Predicates.not;
|
import static com.google.common.base.Predicates.not;
|
||||||
|
import static com.google.common.base.Predicates.or;
|
||||||
import static com.google.common.collect.Iterables.filter;
|
import static com.google.common.collect.Iterables.filter;
|
||||||
import static com.google.common.collect.Iterables.find;
|
import static com.google.common.collect.Iterables.find;
|
||||||
import static com.google.common.collect.Iterables.transform;
|
import static com.google.common.collect.Iterables.transform;
|
||||||
|
@ -37,6 +39,7 @@ import javax.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
|
||||||
|
import com.google.common.base.Optional;
|
||||||
import org.jclouds.collect.Memoized;
|
import org.jclouds.collect.Memoized;
|
||||||
import org.jclouds.compute.domain.ComputeMetadata;
|
import org.jclouds.compute.domain.ComputeMetadata;
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
|
@ -124,14 +127,14 @@ public class ServerInRegionToNodeMetadata implements Function<ServerInRegion, No
|
||||||
builder.publicAddresses(
|
builder.publicAddresses(
|
||||||
filter(
|
filter(
|
||||||
transform(
|
transform(
|
||||||
filter(addresses, not(isPrivateAddress)),
|
filter(addresses, or(isFloatingAddress, not(isPrivateAddress))),
|
||||||
AddressToStringTransformationFunction.INSTANCE),
|
AddressToStringTransformationFunction.INSTANCE),
|
||||||
isInet4Address));
|
isInet4Address));
|
||||||
|
|
||||||
builder.privateAddresses(
|
builder.privateAddresses(
|
||||||
filter(
|
filter(
|
||||||
transform(
|
transform(
|
||||||
filter(addresses, isPrivateAddress),
|
filter(addresses, and(not(isFloatingAddress), isPrivateAddress)),
|
||||||
AddressToStringTransformationFunction.INSTANCE),
|
AddressToStringTransformationFunction.INSTANCE),
|
||||||
isInet4Address));
|
isInet4Address));
|
||||||
|
|
||||||
|
@ -144,6 +147,13 @@ public class ServerInRegionToNodeMetadata implements Function<ServerInRegion, No
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static final Predicate<Address> isFloatingAddress = new Predicate<Address>() {
|
||||||
|
public boolean apply(Address in) {
|
||||||
|
final Optional<String> addrType = in.getType();
|
||||||
|
return addrType.isPresent() && "floating".equals(addrType.get());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public static final Predicate<Address> isPrivateAddress = new Predicate<Address>() {
|
public static final Predicate<Address> isPrivateAddress = new Predicate<Address>() {
|
||||||
public boolean apply(Address in) {
|
public boolean apply(Address in) {
|
||||||
return InetAddresses2.IsPrivateIPAddress.INSTANCE.apply(in.getAddr());
|
return InetAddresses2.IsPrivateIPAddress.INSTANCE.apply(in.getAddr());
|
||||||
|
|
|
@ -22,6 +22,10 @@ import java.beans.ConstructorProperties;
|
||||||
|
|
||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
import com.google.common.base.Objects.ToStringHelper;
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IP address
|
* IP address
|
||||||
|
@ -50,7 +54,10 @@ public class Address {
|
||||||
|
|
||||||
protected String addr;
|
protected String addr;
|
||||||
protected int version;
|
protected int version;
|
||||||
|
protected String macAddr;
|
||||||
|
protected String type;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see Address#getAddr()
|
* @see Address#getAddr()
|
||||||
*/
|
*/
|
||||||
|
@ -67,14 +74,26 @@ public class Address {
|
||||||
return self();
|
return self();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public T macAddr(String macAddr) {
|
||||||
|
this.macAddr = macAddr;
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
|
public T type(String type) {
|
||||||
|
this.type = type;
|
||||||
|
return self();
|
||||||
|
}
|
||||||
|
|
||||||
public Address build() {
|
public Address build() {
|
||||||
return new Address(addr, version);
|
return new Address(addr, version, macAddr, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T fromAddress(Address in) {
|
public T fromAddress(Address in) {
|
||||||
return this
|
return this
|
||||||
.addr(in.getAddr())
|
.addr(in.getAddr())
|
||||||
.version(in.getVersion());
|
.version(in.getVersion())
|
||||||
|
.macAddr(in.getMacAddr().orNull())
|
||||||
|
.type(in.getType().orNull());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,13 +106,19 @@ public class Address {
|
||||||
|
|
||||||
private final String addr;
|
private final String addr;
|
||||||
private final int version;
|
private final int version;
|
||||||
|
@Named("OS-EXT-IPS-MAC:mac_addr")
|
||||||
|
private final Optional<String> macAddr;
|
||||||
|
@Named("OS-EXT-IPS:type")
|
||||||
|
private final Optional<String> type;
|
||||||
|
|
||||||
@ConstructorProperties({
|
@ConstructorProperties({
|
||||||
"addr", "version"
|
"addr", "version", "OS-EXT-IPS-MAC:mac_addr", "OS-EXT-IPS:type"
|
||||||
})
|
})
|
||||||
protected Address(String addr, int version) {
|
protected Address(String addr, int version, @Nullable String macAddr, @Nullable String type) {
|
||||||
this.addr = checkNotNull(addr, "addr");
|
this.addr = checkNotNull(addr, "addr");
|
||||||
this.version = version;
|
this.version = version;
|
||||||
|
this.macAddr = Optional.fromNullable(macAddr);
|
||||||
|
this.type = Optional.fromNullable(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,9 +135,17 @@ public class Address {
|
||||||
return this.version;
|
return this.version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<String> getMacAddr() {
|
||||||
|
return this.macAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<String> getType() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(addr, version);
|
return Objects.hashCode(addr, version, macAddr, type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -121,12 +154,14 @@ public class Address {
|
||||||
if (obj == null || getClass() != obj.getClass()) return false;
|
if (obj == null || getClass() != obj.getClass()) return false;
|
||||||
Address that = Address.class.cast(obj);
|
Address that = Address.class.cast(obj);
|
||||||
return Objects.equal(this.addr, that.addr)
|
return Objects.equal(this.addr, that.addr)
|
||||||
&& Objects.equal(this.version, that.version);
|
&& Objects.equal(this.version, that.version)
|
||||||
|
&& Objects.equal(this.macAddr, that.macAddr)
|
||||||
|
&& Objects.equal(this.type, that.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ToStringHelper string() {
|
protected ToStringHelper string() {
|
||||||
return Objects.toStringHelper(this)
|
return Objects.toStringHelper(this)
|
||||||
.add("addr", addr).add("version", version);
|
.add("addr", addr).add("version", version).add("macAddr", macAddr.or("")).add("type", type.or(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -40,6 +40,7 @@ import org.jclouds.openstack.nova.v2_0.compute.config.NovaComputeServiceContextM
|
||||||
import org.jclouds.openstack.nova.v2_0.domain.Server;
|
import org.jclouds.openstack.nova.v2_0.domain.Server;
|
||||||
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.ServerInRegion;
|
import org.jclouds.openstack.nova.v2_0.domain.regionscoped.ServerInRegion;
|
||||||
import org.jclouds.openstack.nova.v2_0.parse.ParseServerTest;
|
import org.jclouds.openstack.nova.v2_0.parse.ParseServerTest;
|
||||||
|
import org.jclouds.openstack.nova.v2_0.parse.ParseServerWithAddressExtensionsTest;
|
||||||
import org.jclouds.openstack.nova.v2_0.parse.ParseServerWithoutImageTest;
|
import org.jclouds.openstack.nova.v2_0.parse.ParseServerWithoutImageTest;
|
||||||
import org.jclouds.openstack.v2_0.domain.Link;
|
import org.jclouds.openstack.v2_0.domain.Link;
|
||||||
import org.jclouds.openstack.v2_0.domain.Resource;
|
import org.jclouds.openstack.v2_0.domain.Resource;
|
||||||
|
@ -226,6 +227,30 @@ public class ServerInRegionToNodeMetadataTest {
|
||||||
assertNull(convertedNodeMetadata.getImageId());
|
assertNull(convertedNodeMetadata.getImageId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFloatingIp() {
|
||||||
|
Hardware existingHardware = new HardwareBuilder().id("az-1.region-a.geo-1/52415800-8b69-11e0-9b19-734f216543fd")
|
||||||
|
.providerId("52415800-8b69-11e0-9b19-734f216543fd").location(region).build();
|
||||||
|
Image existingImage = new ImageBuilder().id("az-1.region-a.geo-1/52415800-8b69-11e0-9b19-734f6f006e54")
|
||||||
|
.operatingSystem(OperatingSystem.builder().family(OsFamily.LINUX).description("foobuntu").build())
|
||||||
|
.providerId("52415800-8b69-11e0-9b19-734f6f006e54").description("foobuntu").status(Image.Status.AVAILABLE)
|
||||||
|
.location(region).build();
|
||||||
|
|
||||||
|
Server serverToConvert = new ParseServerWithAddressExtensionsTest().expected();
|
||||||
|
ServerInRegion serverInRegionToConvert = new ServerInRegion(serverToConvert, "az-1.region-a.geo-1");
|
||||||
|
|
||||||
|
ServerInRegionToNodeMetadata converter = new ServerInRegionToNodeMetadata(
|
||||||
|
NovaComputeServiceContextModule.toPortableNodeStatus, locationIndex,
|
||||||
|
Suppliers.<Set<? extends Image>> ofInstance(ImmutableSet.of(existingImage)),
|
||||||
|
Suppliers.<Set<? extends Hardware>> ofInstance(ImmutableSet.of(existingHardware)),
|
||||||
|
namingConvention);
|
||||||
|
|
||||||
|
NodeMetadata convertedNodeMetadata = converter.apply(serverInRegionToConvert);
|
||||||
|
|
||||||
|
assertEquals(convertedNodeMetadata.getPrivateAddresses(), ImmutableSet.of("172.16.130.24"));
|
||||||
|
assertEquals(convertedNodeMetadata.getPublicAddresses(), ImmutableSet.of("10.8.54.75"));
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: clean up this syntax
|
// TODO: clean up this syntax
|
||||||
private void checkHardwareAndImageStatus(Hardware expectedHardware, Hardware existingHardware,
|
private void checkHardwareAndImageStatus(Hardware expectedHardware, Hardware existingHardware,
|
||||||
String expectedImageId, OperatingSystem expectedOs, Image existingImage) {
|
String expectedImageId, OperatingSystem expectedOs, Image existingImage) {
|
||||||
|
|
|
@ -130,7 +130,8 @@ public class ParseServerDetailsStatesTest extends BaseSetParserTest<Server> {
|
||||||
.hypervisorHostName("rdohavana.localdomain").build()
|
.hypervisorHostName("rdohavana.localdomain").build()
|
||||||
)
|
)
|
||||||
.addresses(ImmutableMultimap.<String, Address>builder()
|
.addresses(ImmutableMultimap.<String, Address>builder()
|
||||||
.putAll("public", Address.createV4("172.24.4.232")).build()
|
.putAll("public", Address.builder().addr("172.24.4.232").version(4)
|
||||||
|
.macAddr("fa:16:3e:df:22:1b").type("fixed").build()).build()
|
||||||
).build(),
|
).build(),
|
||||||
Server.builder()
|
Server.builder()
|
||||||
.links(
|
.links(
|
||||||
|
@ -168,7 +169,8 @@ public class ParseServerDetailsStatesTest extends BaseSetParserTest<Server> {
|
||||||
.instanceName("instance-00000006").build()
|
.instanceName("instance-00000006").build()
|
||||||
)
|
)
|
||||||
.addresses(ImmutableMultimap.<String, Address>builder()
|
.addresses(ImmutableMultimap.<String, Address>builder()
|
||||||
.putAll("public", Address.createV4("172.24.4.229")).build()
|
.putAll("public", Address.builder().addr("172.24.4.229").version(4)
|
||||||
|
.macAddr("fa:16:3e:cb:56:d6").type("fixed").build()).build()
|
||||||
).build(),
|
).build(),
|
||||||
Server.builder()
|
Server.builder()
|
||||||
.links(
|
.links(
|
||||||
|
@ -209,7 +211,8 @@ public class ParseServerDetailsStatesTest extends BaseSetParserTest<Server> {
|
||||||
.hypervisorHostName("rdohavana.localdomain").build()
|
.hypervisorHostName("rdohavana.localdomain").build()
|
||||||
)
|
)
|
||||||
.addresses(ImmutableMultimap.<String, Address>builder()
|
.addresses(ImmutableMultimap.<String, Address>builder()
|
||||||
.putAll("public", Address.createV4("172.24.4.227")).build()
|
.putAll("public", Address.builder().addr("172.24.4.227").version(4)
|
||||||
|
.macAddr("fa:16:3e:18:fe:c8").type("fixed").build()).build()
|
||||||
).build(),
|
).build(),
|
||||||
Server.builder()
|
Server.builder()
|
||||||
.links(
|
.links(
|
||||||
|
@ -250,7 +253,8 @@ public class ParseServerDetailsStatesTest extends BaseSetParserTest<Server> {
|
||||||
.hypervisorHostName("rdohavana.localdomain").build()
|
.hypervisorHostName("rdohavana.localdomain").build()
|
||||||
)
|
)
|
||||||
.addresses(ImmutableMultimap.<String, Address>builder()
|
.addresses(ImmutableMultimap.<String, Address>builder()
|
||||||
.putAll("public", Address.createV4("172.24.4.228")).build()
|
.putAll("public", Address.builder().addr("172.24.4.228").version(4)
|
||||||
|
.macAddr("fa:16:3e:64:1a:d5").type("fixed").build()).build()
|
||||||
).build()
|
).build()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.jclouds.openstack.nova.v2_0.parse;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.inject.Guice;
|
||||||
|
import com.google.inject.Injector;
|
||||||
|
import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
|
import org.jclouds.json.BaseItemParserTest;
|
||||||
|
import org.jclouds.json.config.GsonModule;
|
||||||
|
import org.jclouds.openstack.nova.v2_0.config.NovaParserModule;
|
||||||
|
import org.jclouds.openstack.nova.v2_0.domain.Address;
|
||||||
|
import org.jclouds.openstack.nova.v2_0.domain.Server;
|
||||||
|
import org.jclouds.openstack.nova.v2_0.domain.Server.Status;
|
||||||
|
import org.jclouds.openstack.nova.v2_0.domain.ServerExtendedStatus;
|
||||||
|
import org.jclouds.openstack.v2_0.domain.Link;
|
||||||
|
import org.jclouds.openstack.v2_0.domain.Link.Relation;
|
||||||
|
import org.jclouds.openstack.v2_0.domain.Resource;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
@Test(groups = "unit", testName = "ParseServerWithAddressExtensionsTest")
|
||||||
|
public class ParseServerWithAddressExtensionsTest extends BaseItemParserTest<Server> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String resource() {
|
||||||
|
return "/server_details_with_address_ext.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SelectJson("server")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public Server expected() {
|
||||||
|
return Server
|
||||||
|
.builder()
|
||||||
|
.id("0bdc3a8d-3a96-4ccc-bb40-715537a7df7b")
|
||||||
|
.tenantId("cac29c920a6149aabe499757b6ba81c7")
|
||||||
|
.userId("ed15e338032f4a2c85b7fa80e40b9917")
|
||||||
|
.name("cloudts-f07")
|
||||||
|
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2016-02-17T14:48:00Z"))
|
||||||
|
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2016-02-17T14:46:13Z"))
|
||||||
|
.hostId("18a9cd55f76c520dcad6c31d5b2b8f4c921979629c0274c0f7d2de39")
|
||||||
|
.status(Status.ACTIVE)
|
||||||
|
.image(
|
||||||
|
Resource
|
||||||
|
.builder()
|
||||||
|
.id("9a9f496a-f5c2-4286-81a4-98189a48777a")
|
||||||
|
.links(
|
||||||
|
Link.create(
|
||||||
|
Relation.BOOKMARK,
|
||||||
|
URI.create("http://openstack:8774/cac29c920a6149aabe499757b6ba81c7/images/9a9f496a-f5c2-4286-81a4-98189a48777a")))
|
||||||
|
.build())
|
||||||
|
.flavor(
|
||||||
|
Resource
|
||||||
|
.builder()
|
||||||
|
.id("3")
|
||||||
|
.links(
|
||||||
|
Link.create(
|
||||||
|
Relation.BOOKMARK,
|
||||||
|
URI.create("http://openstack:8774/cac29c920a6149aabe499757b6ba81c7/flavors/3")))
|
||||||
|
.build())
|
||||||
|
.links(
|
||||||
|
Link.create(
|
||||||
|
Relation.SELF,
|
||||||
|
URI.create("http://openstack:8774/v2/cac29c920a6149aabe499757b6ba81c7/servers/0bdc3a8d-3a96-4ccc-bb40-715537a7df7b")),
|
||||||
|
Link.create(
|
||||||
|
Relation.BOOKMARK,
|
||||||
|
URI.create("http://openstack:8774/cac29c920a6149aabe499757b6ba81c7/servers/0bdc3a8d-3a96-4ccc-bb40-715537a7df7b")))
|
||||||
|
.metadata(ImmutableMap.<String, String>of("jclouds-group", "cloudts"))
|
||||||
|
.addresses(ImmutableMultimap.<String, Address>builder()
|
||||||
|
.putAll("jenkins",
|
||||||
|
Address.builder().version(4).addr("172.16.130.24").macAddr("fa:16:3e:bf:82:43").type("fixed").build(),
|
||||||
|
Address.builder().version(4).addr("10.8.54.75").macAddr("fa:16:3e:bf:82:43").type("floating").build())
|
||||||
|
.build())
|
||||||
|
.diskConfig("MANUAL")
|
||||||
|
.configDrive("")
|
||||||
|
.availabilityZone("nova")
|
||||||
|
.accessIPv4("")
|
||||||
|
.accessIPv6("")
|
||||||
|
.keyName("jenkins")
|
||||||
|
.extendedStatus(ServerExtendedStatus.builder().vmState("active").powerState(1).build())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Injector injector() {
|
||||||
|
return Guice.createInjector(new NovaParserModule(), new GsonModule());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
{
|
||||||
|
"server": {
|
||||||
|
"OS-DCF:diskConfig": "MANUAL",
|
||||||
|
"OS-EXT-AZ:availability_zone": "nova",
|
||||||
|
"OS-EXT-STS:power_state": 1,
|
||||||
|
"OS-EXT-STS:task_state": null,
|
||||||
|
"OS-EXT-STS:vm_state": "active",
|
||||||
|
"OS-SRV-USG:launched_at": "2016-02-17T14:48:00.000000",
|
||||||
|
"OS-SRV-USG:terminated_at": null,
|
||||||
|
"accessIPv4": "",
|
||||||
|
"accessIPv6": "",
|
||||||
|
"addresses": {
|
||||||
|
"jenkins": [
|
||||||
|
{
|
||||||
|
"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:bf:82:43",
|
||||||
|
"OS-EXT-IPS:type": "fixed",
|
||||||
|
"addr": "172.16.130.24",
|
||||||
|
"version": 4
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:bf:82:43",
|
||||||
|
"OS-EXT-IPS:type": "floating",
|
||||||
|
"addr": "10.8.54.75",
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"config_drive": "",
|
||||||
|
"created": "2016-02-17T14:46:13Z",
|
||||||
|
"flavor": {
|
||||||
|
"id": "3",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"href": "http://openstack:8774/cac29c920a6149aabe499757b6ba81c7/flavors/3",
|
||||||
|
"rel": "bookmark"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"hostId": "18a9cd55f76c520dcad6c31d5b2b8f4c921979629c0274c0f7d2de39",
|
||||||
|
"id": "0bdc3a8d-3a96-4ccc-bb40-715537a7df7b",
|
||||||
|
"image": {
|
||||||
|
"id": "9a9f496a-f5c2-4286-81a4-98189a48777a",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"href": "http://openstack:8774/cac29c920a6149aabe499757b6ba81c7/images/9a9f496a-f5c2-4286-81a4-98189a48777a",
|
||||||
|
"rel": "bookmark"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"key_name": "jenkins",
|
||||||
|
"links": [
|
||||||
|
{
|
||||||
|
"href": "http://openstack:8774/v2/cac29c920a6149aabe499757b6ba81c7/servers/0bdc3a8d-3a96-4ccc-bb40-715537a7df7b",
|
||||||
|
"rel": "self"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"href": "http://openstack:8774/cac29c920a6149aabe499757b6ba81c7/servers/0bdc3a8d-3a96-4ccc-bb40-715537a7df7b",
|
||||||
|
"rel": "bookmark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"jclouds-group": "cloudts"
|
||||||
|
},
|
||||||
|
"name": "cloudts-f07",
|
||||||
|
"os-extended-volumes:volumes_attached": [],
|
||||||
|
"progress": 0,
|
||||||
|
"security_groups": [
|
||||||
|
{
|
||||||
|
"name": "allow-all"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"status": "ACTIVE",
|
||||||
|
"tenant_id": "cac29c920a6149aabe499757b6ba81c7",
|
||||||
|
"updated": "2016-02-17T14:48:00Z",
|
||||||
|
"user_id": "ed15e338032f4a2c85b7fa80e40b9917"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue