mirror of https://github.com/apache/jclouds.git
Add compute service support to openstack-labs nova client
This commit is contained in:
parent
6df17b858d
commit
cc4b0cac82
|
@ -79,6 +79,9 @@ public class RegionIdToURIFromAccessForTypeAndVersionSupplier implements RegionI
|
|||
|
||||
@Override
|
||||
public boolean apply(Endpoint input) {
|
||||
if (input.getVersionId() == null) {
|
||||
return true;
|
||||
}
|
||||
return input.getVersionId().equals(apiVersion);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,12 @@ import java.util.Set;
|
|||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.location.Region;
|
||||
import org.jclouds.location.functions.RegionToEndpointOrProviderIfNull;
|
||||
import org.jclouds.openstack.nova.v1_1.features.*;
|
||||
import org.jclouds.openstack.nova.v1_1.features.FlavorAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.FloatingIPAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.KeyPairAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.SecurityGroupAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ImageAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ServerAsyncClient;
|
||||
import org.jclouds.rest.annotations.Delegate;
|
||||
import org.jclouds.rest.annotations.EndpointParam;
|
||||
|
||||
|
@ -88,5 +93,4 @@ public interface NovaAsyncClient {
|
|||
@Delegate
|
||||
KeyPairAsyncClient getKeyPairClientForRegion(
|
||||
@EndpointParam(parser = RegionToEndpointOrProviderIfNull.class) @Nullable String region);
|
||||
|
||||
}
|
||||
|
|
|
@ -21,16 +21,20 @@ package org.jclouds.openstack.nova.v1_1;
|
|||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.compute.ComputeServiceContextBuilder;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.config.NovaComputeServiceContextModule;
|
||||
import org.jclouds.openstack.nova.v1_1.config.NovaRestClientModule;
|
||||
import org.jclouds.rest.RestContextBuilder;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
*
|
||||
* A context builder for getting nova clients.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class NovaContextBuilder extends RestContextBuilder<NovaClient, NovaAsyncClient> {
|
||||
public class NovaContextBuilder extends ComputeServiceContextBuilder<NovaClient, NovaAsyncClient>
|
||||
{
|
||||
|
||||
public NovaContextBuilder(Properties props) {
|
||||
super(NovaClient.class, NovaAsyncClient.class, props);
|
||||
|
@ -41,4 +45,8 @@ public class NovaContextBuilder extends RestContextBuilder<NovaClient, NovaAsync
|
|||
modules.add(new NovaRestClientModule());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
modules.add(new NovaComputeServiceContextModule());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/**
|
||||
* 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.compute.config;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.inject.TypeLiteral;
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.functions.IdentityFunction;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.FlavorToHardware;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.NovaImageToImage;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.NovaImageToOperatingSystem;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.ServerToNodeMetadata;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.strategy.NovaComputeServiceAdapter;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Flavor;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||
|
||||
/**
|
||||
* Module for building a compute service context for Nova
|
||||
*
|
||||
* @author Matt Stephenson
|
||||
*/
|
||||
public class NovaComputeServiceContextModule extends
|
||||
ComputeServiceAdapterContextModule<NovaClient, NovaAsyncClient, Server, Flavor, org.jclouds.openstack.nova.v1_1.domain.Image, Location>
|
||||
{
|
||||
public NovaComputeServiceContextModule()
|
||||
{
|
||||
super(NovaClient.class, NovaAsyncClient.class);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
protected void configure()
|
||||
{
|
||||
super.configure();
|
||||
bind(new TypeLiteral<ComputeServiceAdapter<Server, Flavor, org.jclouds.openstack.nova.v1_1.domain.Image, Location>>(){}).to(NovaComputeServiceAdapter.class);
|
||||
|
||||
bind(new TypeLiteral<Function<Server, NodeMetadata>>(){}).to(ServerToNodeMetadata.class);
|
||||
|
||||
bind(new TypeLiteral<Function<org.jclouds.openstack.nova.v1_1.domain.Image, Image>>(){}).to(NovaImageToImage.class);
|
||||
bind(new TypeLiteral<Function<org.jclouds.openstack.nova.v1_1.domain.Image, OperatingSystem>>(){}).to(NovaImageToOperatingSystem.class);
|
||||
|
||||
bind(new TypeLiteral<Function<Flavor, Hardware>>(){}).to(FlavorToHardware.class);
|
||||
|
||||
// we aren't converting location from a provider-specific type
|
||||
bind(new TypeLiteral<Function<Location, Location>>(){}).to((Class)IdentityFunction.class);
|
||||
}
|
||||
}
|
|
@ -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.openstack.nova.v1_1.compute.functions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.HardwareBuilder;
|
||||
import org.jclouds.compute.domain.Processor;
|
||||
import org.jclouds.compute.domain.internal.VolumeImpl;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Flavor;
|
||||
|
||||
/**
|
||||
* A function for transforming the nova specific Flavor object to the generic Hardware object.
|
||||
*
|
||||
* @author Matt Stephenson
|
||||
*/
|
||||
public class FlavorToHardware implements Function<Flavor, Hardware>
|
||||
{
|
||||
@Override
|
||||
public Hardware apply(Flavor flavor)
|
||||
{
|
||||
return new HardwareBuilder()
|
||||
.id(flavor.getId())
|
||||
.name(flavor.getName())
|
||||
.ram(flavor.getRam())
|
||||
.processor(new Processor(flavor.getVcpus(), 1.0))
|
||||
.volume(new VolumeImpl(Float.valueOf(flavor.getDisk()), true, true))
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -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.openstack.nova.v1_1.compute.functions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.ImageBuilder;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* A function for transforming a nova-specific Image into a generic Image object.
|
||||
*
|
||||
* @author Matt Stephenson
|
||||
*/
|
||||
public class NovaImageToImage implements Function<org.jclouds.openstack.nova.v1_1.domain.Image, Image>
|
||||
{
|
||||
private final Function<org.jclouds.openstack.nova.v1_1.domain.Image, OperatingSystem> imageToOs;
|
||||
|
||||
@Inject
|
||||
public NovaImageToImage(Function<org.jclouds.openstack.nova.v1_1.domain.Image, OperatingSystem> imageToOs)
|
||||
{
|
||||
this.imageToOs = imageToOs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image apply(org.jclouds.openstack.nova.v1_1.domain.Image image)
|
||||
{
|
||||
return new ImageBuilder()
|
||||
.id(image.getId())
|
||||
.name(image.getName())
|
||||
.operatingSystem(imageToOs.apply(image))
|
||||
.description(image.getName())
|
||||
.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
/**
|
||||
* 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.compute.functions;
|
||||
|
||||
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;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.compute.util.ComputeServiceUtils;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Image;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
/**
|
||||
* A function for transforming a nova specific Image into a generic OperatingSystem object.
|
||||
*
|
||||
* @author Matt Stephenson
|
||||
*/
|
||||
public class NovaImageToOperatingSystem implements Function<Image, OperatingSystem>
|
||||
{
|
||||
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])");
|
||||
|
||||
@javax.annotation.Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
|
||||
private final Map<OsFamily, Map<String, String>> osVersionMap;
|
||||
|
||||
@Inject
|
||||
public NovaImageToOperatingSystem(Map<OsFamily, Map<String, String>> osVersionMap)
|
||||
{
|
||||
this.osVersionMap = osVersionMap;
|
||||
}
|
||||
|
||||
public OperatingSystem apply(final Image from)
|
||||
{
|
||||
OsFamily osFamily = null;
|
||||
String osVersion = null;
|
||||
|
||||
String imageName = Objects.firstNonNull(from.getName(), "unspecified");
|
||||
|
||||
boolean is64Bit = true;
|
||||
|
||||
if (imageName.indexOf("Windows") != -1)
|
||||
{
|
||||
osFamily = OsFamily.WINDOWS;
|
||||
Matcher matcher = WINDOWS_PATTERN.matcher(from.getName());
|
||||
if (matcher.find())
|
||||
{
|
||||
osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(1), osVersionMap);
|
||||
is64Bit = matcher.group(2).equals("x64");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (imageName.contains("Red Hat EL"))
|
||||
{
|
||||
osFamily = OsFamily.RHEL;
|
||||
}
|
||||
else if (imageName.contains("Oracle EL"))
|
||||
{
|
||||
osFamily = OsFamily.OEL;
|
||||
}
|
||||
else
|
||||
{
|
||||
final Iterable<String> imageNameParts = Splitter.on(CharMatcher.WHITESPACE).trimResults().split(imageName.toLowerCase());
|
||||
|
||||
osFamily = Iterables.find(Arrays.asList(OsFamily.values()), new Predicate<OsFamily>()
|
||||
{
|
||||
@Override
|
||||
public boolean apply(@Nullable OsFamily osFamily)
|
||||
{
|
||||
return Iterables.any(imageNameParts, Predicates.equalTo(osFamily.name().toLowerCase()));
|
||||
}
|
||||
});
|
||||
}
|
||||
Matcher matcher = DEFAULT_PATTERN.matcher(imageName);
|
||||
if (matcher.find() && matcher.groupCount() >= 3)
|
||||
{
|
||||
osVersion = ComputeServiceUtils.parseVersionOrReturnEmptyString(osFamily, matcher.group(3), osVersionMap);
|
||||
}
|
||||
}
|
||||
return new OperatingSystem(osFamily, imageName, osVersion, null, imageName, is64Bit);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/**
|
||||
* 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.compute.functions;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.NodeMetadataBuilder;
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
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.ServerStatus;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A function for transforming a nova-specific Server into a generic NodeMetadata object.
|
||||
*
|
||||
* @author Matt Stephenson
|
||||
*/
|
||||
public class ServerToNodeMetadata implements Function<Server, NodeMetadata>
|
||||
{
|
||||
|
||||
@VisibleForTesting
|
||||
public static final Map<ServerStatus, NodeState> serverToNodeState = ImmutableMap.<ServerStatus, NodeState>builder()
|
||||
.put(ServerStatus.ACTIVE, NodeState.RUNNING)
|
||||
.put(ServerStatus.SUSPENDED, NodeState.SUSPENDED)
|
||||
.put(ServerStatus.DELETED, NodeState.TERMINATED)
|
||||
.put(ServerStatus.RESIZE, NodeState.PENDING)
|
||||
.put(ServerStatus.VERIFY_RESIZE, NodeState.PENDING)
|
||||
.put(ServerStatus.BUILD, NodeState.PENDING)
|
||||
.put(ServerStatus.PASSWORD, NodeState.PENDING)
|
||||
.put(ServerStatus.REBUILD, NodeState.PENDING)
|
||||
.put(ServerStatus.REBOOT, NodeState.PENDING)
|
||||
.put(ServerStatus.HARD_REBOOT, NodeState.PENDING)
|
||||
.put(ServerStatus.UNKNOWN, NodeState.UNRECOGNIZED)
|
||||
.put(ServerStatus.UNRECOGNIZED, NodeState.UNRECOGNIZED).build();
|
||||
|
||||
@Override
|
||||
public NodeMetadata apply(Server server)
|
||||
{
|
||||
return new NodeMetadataBuilder()
|
||||
.id(server.getId())
|
||||
.name(server.getName())
|
||||
.publicAddresses(Iterables.transform(server.getPublicAddresses(), new AddressToStringTransformationFunction()))
|
||||
.privateAddresses(Iterables.transform(server.getPrivateAddresses(), new AddressToStringTransformationFunction()))
|
||||
.state(server.getStatus().getNodeState())
|
||||
.build();
|
||||
}
|
||||
|
||||
private class AddressToStringTransformationFunction implements Function<Address, String>
|
||||
{
|
||||
@Override
|
||||
public String apply(Address address)
|
||||
{
|
||||
return address.getAddr();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
/**
|
||||
* 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.compute.strategy;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LoginCredentials;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Flavor;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Image;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.RebootType;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||
import org.jclouds.openstack.nova.v1_1.features.FlavorClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ImageClient;
|
||||
import org.jclouds.openstack.nova.v1_1.features.ServerClient;
|
||||
import java.util.Set;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* The adapter used by the NovaComputeServiceContextModule to interface the nova-specific domain model to the computeService generic domain model.
|
||||
*
|
||||
* @author Matt Stephenson
|
||||
*/
|
||||
public class NovaComputeServiceAdapter implements ComputeServiceAdapter<Server, Flavor, Image, Location>
|
||||
{
|
||||
|
||||
private final NovaClient novaClient;
|
||||
private final ServerClient defaultLocationServerClient;
|
||||
private final FlavorClient defaultFlavorClient;
|
||||
private final ImageClient defaultImageClient;
|
||||
private final Set<String> regions;
|
||||
|
||||
|
||||
@Inject
|
||||
public NovaComputeServiceAdapter(NovaClient novaClient)
|
||||
{
|
||||
this.novaClient = novaClient;
|
||||
regions = novaClient.getConfiguredRegions();
|
||||
if (regions.isEmpty())
|
||||
{
|
||||
throw new IllegalStateException("No regions exist for this compute service. The Nova compute service requires at least 1 region.");
|
||||
}
|
||||
String region = regions.iterator().next();
|
||||
this.defaultLocationServerClient = novaClient.getServerClientForRegion(region);
|
||||
this.defaultFlavorClient = novaClient.getFlavorClientForRegion(region);
|
||||
this.defaultImageClient = novaClient.getImageClientForRegion(region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeAndInitialCredentials<Server> createNodeWithGroupEncodedIntoName(String tag, String name, Template template)
|
||||
{
|
||||
ServerClient serverClient = template.getLocation() != null ? novaClient.getServerClientForRegion(template.getLocation().getId()) : defaultLocationServerClient;
|
||||
Server server = serverClient.createServer(name, template.getImage().getId(), template.getHardware().getId());
|
||||
return new NodeAndInitialCredentials<Server>(server, server.getId() + "", LoginCredentials.builder().password(server.getAdminPass()).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Flavor> listHardwareProfiles()
|
||||
{
|
||||
return defaultFlavorClient.listFlavorsInDetail();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Image> listImages()
|
||||
{
|
||||
return defaultImageClient.listImagesInDetail();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Location> listLocations()
|
||||
{
|
||||
return Iterables.transform(novaClient.getConfiguredRegions(), new Function<String, Location>()
|
||||
{
|
||||
|
||||
@Override
|
||||
public Location apply(@Nullable String region)
|
||||
{
|
||||
return new LocationBuilder().id(region).description(region).build();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Server getNode(String id)
|
||||
{
|
||||
return defaultLocationServerClient.getServer(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroyNode(String id)
|
||||
{
|
||||
defaultLocationServerClient.deleteServer(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rebootNode(String id)
|
||||
{
|
||||
defaultLocationServerClient.rebootServer(id, RebootType.SOFT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resumeNode(String id)
|
||||
{
|
||||
throw new UnsupportedOperationException("suspend not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void suspendNode(String id)
|
||||
{
|
||||
throw new UnsupportedOperationException("suspend not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<Server> listNodes()
|
||||
{
|
||||
ImmutableSet.Builder<Server> servers = new ImmutableSet.Builder<Server>();
|
||||
|
||||
for (String region : regions)
|
||||
{
|
||||
servers.addAll(novaClient.getServerClientForRegion(region).listServersInDetail());
|
||||
}
|
||||
|
||||
return servers.build();
|
||||
}
|
||||
}
|
|
@ -18,11 +18,9 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.domain;
|
||||
|
||||
import static com.google.common.base.Objects.toStringHelper;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -37,6 +35,8 @@ import org.jclouds.util.Multimaps2;
|
|||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import static com.google.common.base.Objects.toStringHelper;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
/**
|
||||
* A server is a virtual machine instance in the compute system. Flavor and
|
||||
* image are requisite elements when creating a server.
|
||||
|
@ -69,8 +69,8 @@ public class Server extends Resource {
|
|||
private Resource flavor;
|
||||
private Map<String, String> metadata = Maps.newHashMap();
|
||||
// TODO: get gson multimap ad
|
||||
private Multimap<Address.Type, Address> addresses = LinkedHashMultimap
|
||||
.create();
|
||||
private Multimap<Address.Type, Address> addresses = LinkedHashMultimap.create();
|
||||
private String adminPass;
|
||||
|
||||
/**
|
||||
* @see Server#getTenantId()
|
||||
|
@ -211,11 +211,19 @@ public class Server extends Resource {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Server#getAdminPass()
|
||||
*/
|
||||
public Builder adminPass(String adminPass) {
|
||||
this.adminPass = adminPass;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Server build() {
|
||||
// return new Server(id, name, links, addresses);
|
||||
return new Server(id, name, links, tenantId, userId, updated,
|
||||
created, hostId, accessIPv4, accessIPv6, status, progress,
|
||||
image, flavor, addresses, metadata);
|
||||
image, flavor, adminPass, addresses, metadata);
|
||||
}
|
||||
|
||||
public Builder fromServer(Server in) {
|
||||
|
@ -268,15 +276,15 @@ public class Server extends Resource {
|
|||
protected int progress;
|
||||
protected Resource image;
|
||||
protected Resource flavor;
|
||||
protected final String adminPass;
|
||||
// TODO: get gson multimap adapter!
|
||||
protected final Map<Address.Type, Set<Address>> addresses;
|
||||
protected Map<String, String> metadata;
|
||||
protected String adminPass;
|
||||
|
||||
protected Server(String id, String name, Set<Link> links, String tenantId,
|
||||
String userId, Date updated, Date created, String hostId,
|
||||
String accessIPv4, String accessIPv6, ServerStatus status,
|
||||
int progress, Resource image, Resource flavor,
|
||||
int progress, Resource image, Resource flavor, String adminPass,
|
||||
Multimap<Address.Type, Address> addresses, Map<String, String> metadata) {
|
||||
super(id, name, links);
|
||||
this.tenantId = tenantId;
|
||||
|
@ -293,7 +301,7 @@ public class Server extends Resource {
|
|||
this.metadata = Maps.newHashMap(metadata);
|
||||
this.addresses = Multimaps2.toOldSchool(ImmutableMultimap
|
||||
.copyOf(checkNotNull(addresses, "addresses")));
|
||||
|
||||
this.adminPass = adminPass;
|
||||
}
|
||||
|
||||
public String getTenantId() {
|
||||
|
@ -343,11 +351,6 @@ public class Server extends Resource {
|
|||
public Map<String, String> getMetadata() {
|
||||
return this.metadata;
|
||||
}
|
||||
|
||||
|
||||
public String getAdminPass() {
|
||||
return this.adminPass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the private ip addresses assigned to the server
|
||||
|
@ -402,6 +405,13 @@ public class Server extends Resource {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the administrative password for this server.
|
||||
*/
|
||||
public String getAdminPass() {
|
||||
return adminPass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper("").add("id", id).add("name", name)
|
||||
|
@ -411,7 +421,7 @@ public class Server extends Resource {
|
|||
.add("status", status).add("progress", progress)
|
||||
.add("image", image).add("flavor", flavor)
|
||||
.add("metadata", metadata)
|
||||
.add("links", links).add("addresses", addresses).toString();
|
||||
.add("links", links).add("addresses", addresses)
|
||||
.add("adminPass",adminPass).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.domain;
|
||||
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
|
||||
/**
|
||||
* Servers contain a status attribute that can be used as an indication of the
|
||||
* current server state. Servers with an ACTIVE status are available for use.
|
||||
|
@ -29,7 +31,27 @@ package org.jclouds.openstack.nova.v1_1.domain;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public enum ServerStatus {
|
||||
ACTIVE, BUILD, REBUILD, SUSPENDED, RESIZE, VERIFY_RESIZE, REVERT_RESIZE, PASSWORD, REBOOT, HARD_REBOOT, DELETED, UNKNOWN, ERROR, UNRECOGNIZED;
|
||||
|
||||
ACTIVE (NodeState.RUNNING),
|
||||
BUILD (NodeState.PENDING),
|
||||
REBUILD (NodeState.PENDING),
|
||||
SUSPENDED (NodeState.SUSPENDED),
|
||||
RESIZE (NodeState.PENDING),
|
||||
VERIFY_RESIZE(NodeState.PENDING),
|
||||
REVERT_RESIZE(NodeState.PENDING),
|
||||
PASSWORD (NodeState.PENDING),
|
||||
REBOOT (NodeState.PENDING),
|
||||
HARD_REBOOT (NodeState.PENDING),
|
||||
DELETED (NodeState.TERMINATED),
|
||||
UNKNOWN (NodeState.UNRECOGNIZED),
|
||||
ERROR (NodeState.ERROR),
|
||||
UNRECOGNIZED (NodeState.UNRECOGNIZED);
|
||||
|
||||
private final NodeState nodeState;
|
||||
|
||||
ServerStatus(NodeState nodeState) {
|
||||
this.nodeState = nodeState;
|
||||
}
|
||||
|
||||
public String value() {
|
||||
return name();
|
||||
|
@ -43,4 +65,8 @@ public enum ServerStatus {
|
|||
}
|
||||
}
|
||||
|
||||
public NodeState getNodeState()
|
||||
{
|
||||
return nodeState;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,9 +94,8 @@ public interface ServerAsyncClient {
|
|||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||
ListenableFuture<Server> getServer(@PathParam("id") String id);
|
||||
|
||||
|
||||
/**
|
||||
* @see NovaClient#deleteServer
|
||||
* @see ServerClient#deleteServer
|
||||
*/
|
||||
@DELETE
|
||||
@Consumes
|
||||
|
@ -105,7 +104,7 @@ public interface ServerAsyncClient {
|
|||
ListenableFuture<Boolean> deleteServer(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see NovaClient#rebootServer
|
||||
* @see ServerClient#rebootServer
|
||||
*/
|
||||
@POST
|
||||
@Path("/servers/{id}/action")
|
||||
|
@ -115,7 +114,7 @@ public interface ServerAsyncClient {
|
|||
ListenableFuture<Void> rebootServer(@PathParam("id") String id, @PayloadParam("type") RebootType rebootType);
|
||||
|
||||
/**
|
||||
* @see NovaClient#resizeServer
|
||||
* @see ServerClient#resizeServer
|
||||
*/
|
||||
@POST
|
||||
@Path("/servers/{id}/action")
|
||||
|
@ -125,7 +124,7 @@ public interface ServerAsyncClient {
|
|||
ListenableFuture<Void> resizeServer(@PathParam("id") String id, @PayloadParam("flavorId") String flavorId);
|
||||
|
||||
/**
|
||||
* @see NovaClient#confirmResizeServer
|
||||
* @see ServerClient#confirmResizeServer
|
||||
*/
|
||||
@POST
|
||||
@Path("/servers/{id}/action")
|
||||
|
@ -135,7 +134,7 @@ public interface ServerAsyncClient {
|
|||
ListenableFuture<Void> confirmResizeServer(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see NovaClient#revertResizeServer
|
||||
* @see ServerClient#revertResizeServer
|
||||
*/
|
||||
@POST
|
||||
@Path("/servers/{id}/action")
|
||||
|
@ -145,7 +144,7 @@ public interface ServerAsyncClient {
|
|||
ListenableFuture<Void> revertResizeServer(@PathParam("id") String id);
|
||||
|
||||
/**
|
||||
* @see NovaClient#createServer
|
||||
* @see ServerClient#createServer
|
||||
*/
|
||||
@POST
|
||||
@Unwrap
|
||||
|
@ -156,7 +155,7 @@ public interface ServerAsyncClient {
|
|||
@PayloadParam("flavorRef") String flavorRef, CreateServerOptions... options);
|
||||
|
||||
/**
|
||||
* @see NovaClient#rebuildServer
|
||||
* @see ServerClient#rebuildServer
|
||||
*/
|
||||
@POST
|
||||
@Path("/servers/{id}/action")
|
||||
|
@ -166,7 +165,7 @@ public interface ServerAsyncClient {
|
|||
|
||||
|
||||
/**
|
||||
* @see NovaClient#changeAdminPass
|
||||
* @see ServerClient#changeAdminPass
|
||||
*/
|
||||
@POST
|
||||
@Path("/servers/{id}/action")
|
||||
|
@ -176,7 +175,7 @@ public interface ServerAsyncClient {
|
|||
ListenableFuture<Void> changeAdminPass(@PathParam("id") String id, @PayloadParam("adminPass") String adminPass);
|
||||
|
||||
/**
|
||||
* @see NovaClient#renameServer
|
||||
* @see ServerClient#renameServer
|
||||
*/
|
||||
@PUT
|
||||
@Path("/servers/{id}")
|
||||
|
|
|
@ -18,33 +18,14 @@
|
|||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.features;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.DELETE;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import org.jclouds.concurrent.Timeout;
|
||||
import org.jclouds.openstack.domain.Resource;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.RebootType;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||
import org.jclouds.openstack.nova.v1_1.options.CreateServerOptions;
|
||||
import org.jclouds.openstack.nova.v1_1.options.RebuildServerOptions;
|
||||
import org.jclouds.rest.annotations.ExceptionParser;
|
||||
import org.jclouds.rest.annotations.MapBinder;
|
||||
import org.jclouds.rest.annotations.Payload;
|
||||
import org.jclouds.rest.annotations.PayloadParam;
|
||||
import org.jclouds.rest.annotations.Unwrap;
|
||||
import org.jclouds.rest.functions.ReturnFalseOnNotFoundOr404;
|
||||
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* Provides synchronous access to Server.
|
||||
|
@ -82,49 +63,92 @@ public interface ServerClient {
|
|||
Server getServer(String id);
|
||||
|
||||
/**
|
||||
* @see NovaClient#createServer
|
||||
* Create a new server
|
||||
*
|
||||
* @param name
|
||||
* name of the server to create
|
||||
* @param imageRef
|
||||
* reference to the image for the server to use
|
||||
* @param flavorRef
|
||||
* reference to the flavor to use when creating the server
|
||||
* @param options
|
||||
* optional parameters to be passed into the server creation request
|
||||
* @return the newly created server
|
||||
*/
|
||||
Server createServer(String name, String imageRef,
|
||||
String flavorRef, CreateServerOptions... options);
|
||||
Server createServer(String name, String imageRef, String flavorRef, CreateServerOptions... options);
|
||||
|
||||
/**
|
||||
* @see NovaClient#deleteServer
|
||||
* Terminate and delete a server.
|
||||
*
|
||||
* @param id
|
||||
* id of the server
|
||||
* @return True if successful, False otherwise
|
||||
*/
|
||||
Boolean deleteServer(String id);
|
||||
|
||||
/**
|
||||
* @see NovaClient#rebootServer
|
||||
*/
|
||||
/**
|
||||
* Reboot a server.
|
||||
*
|
||||
* @param id
|
||||
* id of the server
|
||||
* @param rebootType
|
||||
* The type of reboot to perform (Hard/Soft)
|
||||
*/
|
||||
void rebootServer(String id, RebootType rebootType);
|
||||
|
||||
/**
|
||||
* @see NovaClient#resizeServer
|
||||
*/
|
||||
/**
|
||||
* Resize a server to a new flavor size.
|
||||
*
|
||||
* @param id
|
||||
* id of the server
|
||||
* @param flavorId
|
||||
* id of the new flavor to use
|
||||
*/
|
||||
void resizeServer(String id, String flavorId);
|
||||
|
||||
/**
|
||||
* @see NovaClient#confirmResizeServer
|
||||
/**
|
||||
* Confirm a resize operation.
|
||||
*
|
||||
* @param id
|
||||
* id of the server
|
||||
*/
|
||||
void confirmResizeServer(String id);
|
||||
|
||||
/**
|
||||
* @see NovaClient#revertResizeServer
|
||||
*/
|
||||
/**
|
||||
* Revert a resize operation.
|
||||
*
|
||||
* @param id
|
||||
* id of the server
|
||||
*/
|
||||
void revertResizeServer(String id);
|
||||
|
||||
/**
|
||||
* @see NovaClient#rebuildServer
|
||||
/**
|
||||
* Rebuild a server.
|
||||
*
|
||||
* @param id
|
||||
* id of the server
|
||||
* @param options
|
||||
* Optional paramaters to the rebuilding operation.
|
||||
*/
|
||||
void rebuildServer(String id, RebuildServerOptions... options);
|
||||
|
||||
/**
|
||||
* @see NovaClient#changeAdminPass
|
||||
/**
|
||||
* Change the administrative password to a server.
|
||||
*
|
||||
* @param id
|
||||
* id of the server
|
||||
* @param adminPass
|
||||
* The new administrative password to use
|
||||
*/
|
||||
void changeAdminPass(String id, String adminPass);
|
||||
|
||||
/**
|
||||
* @see NovaClient#renameServer
|
||||
/**
|
||||
* Rename a server.
|
||||
*
|
||||
* @param id
|
||||
* id of the server
|
||||
* @param newName
|
||||
* The new name for the server
|
||||
*/
|
||||
void renameServer(String id, String newName);
|
||||
|
||||
}
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
/**
|
||||
* 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.features;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
|
|
@ -1,3 +1,21 @@
|
|||
/**
|
||||
* 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.features;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* 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.features;
|
||||
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.domain.Resource;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaComputeServiceExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseServerListTest;
|
||||
import org.testng.annotations.Test;
|
||||
import java.net.URI;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests the compute service abstraction of the nova client.
|
||||
*
|
||||
* @author Matt Stephenson
|
||||
*/
|
||||
@Test(groups = "unit", testName = "NovaComputeServiceExpectTest")
|
||||
public class NovaComputeServiceExpectTest extends BaseNovaComputeServiceExpectTest
|
||||
{
|
||||
|
||||
public void testListServersWhenResponseIs2xx() throws Exception
|
||||
{
|
||||
HttpRequest listServers = HttpRequest.builder().method("GET").endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/servers/detail")).headers(
|
||||
ImmutableMultimap.<String, String>builder().put("Accept", "application/json").put("X-Auth-Token",
|
||||
authToken).build()).build();
|
||||
|
||||
HttpResponse listServersResponse = HttpResponse.builder().statusCode(200).payload(
|
||||
payloadFromResource("/server_list_details.json")).build();
|
||||
|
||||
ComputeService clientWhenServersExist = requestsSendResponses(keystoneAuthWithAccessKeyAndSecretKey,
|
||||
responseWithKeystoneAccess, listServers, listServersResponse);
|
||||
|
||||
|
||||
assertNotNull(clientWhenServersExist.listAssignableLocations());
|
||||
assertEquals(clientWhenServersExist.listAssignableLocations().size(), 1);
|
||||
assertEquals(clientWhenServersExist.listAssignableLocations().iterator().next().getId(), "North");
|
||||
|
||||
assertNotNull(clientWhenServersExist.listNodes());
|
||||
assertEquals(clientWhenServersExist.listNodes().size(), 1);
|
||||
assertEquals(clientWhenServersExist.listNodes().iterator().next().getId(), "52415800-8b69-11e0-9b19-734f000004d2");
|
||||
assertEquals(clientWhenServersExist.listNodes().iterator().next().getName(), "sample-server");
|
||||
}
|
||||
|
||||
public void testListServersWhenReponseIs404IsEmpty() throws Exception
|
||||
{
|
||||
HttpRequest listServers = HttpRequest.builder().method("GET").endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/servers/detail")).headers(
|
||||
ImmutableMultimap.<String, String>builder().put("Accept", "application/json").put("X-Auth-Token",
|
||||
authToken).build()).build();
|
||||
|
||||
HttpResponse listServersResponse = HttpResponse.builder().statusCode(404).build();
|
||||
|
||||
ComputeService clientWhenNoServersExist = requestsSendResponses(keystoneAuthWithAccessKeyAndSecretKey,
|
||||
responseWithKeystoneAccess, listServers, listServersResponse);
|
||||
|
||||
assertTrue(clientWhenNoServersExist.listNodes().isEmpty());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* 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.functions;
|
||||
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.FlavorToHardware;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Flavor;
|
||||
import org.testng.annotations.Test;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests the function used to transform Flavor objects into Hardware objects
|
||||
*
|
||||
* @author Matt Stephenson
|
||||
*/
|
||||
public class FlavorToHardwareTest
|
||||
{
|
||||
@Test
|
||||
public void testConversion()
|
||||
{
|
||||
UUID id = UUID.randomUUID();
|
||||
Flavor flavorToConvert = Flavor.builder()
|
||||
.id(id.toString())
|
||||
.name("Test Flavor " + id)
|
||||
.ram(262144)
|
||||
.disk(10000)
|
||||
.vcpus(16)
|
||||
.build();
|
||||
|
||||
Hardware converted = new FlavorToHardware().apply(flavorToConvert);
|
||||
|
||||
assertEquals(converted.getName(), flavorToConvert.getName());
|
||||
assertEquals(converted.getId(), flavorToConvert.getId());
|
||||
assertEquals(converted.getRam(), flavorToConvert.getRam());
|
||||
|
||||
assertNotNull(converted.getProcessors());
|
||||
assertFalse(converted.getProcessors().isEmpty());
|
||||
assertEquals(converted.getProcessors().iterator().next().getCores(), (double)flavorToConvert.getVcpus());
|
||||
|
||||
assertNotNull(converted.getVolumes());
|
||||
assertFalse(converted.getVolumes().isEmpty());
|
||||
assertEquals(converted.getVolumes().iterator().next().getSize(), Float.valueOf(flavorToConvert.getDisk()));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* 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.functions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.NovaImageToImage;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Image;
|
||||
import org.testng.annotations.Test;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* Tests the function that transforms nova-specific images to generic images.
|
||||
*
|
||||
* @author Matt Stephenson
|
||||
*/
|
||||
public class NovaImageToImageTest
|
||||
{
|
||||
@Test
|
||||
public void testConversion()
|
||||
{
|
||||
UUID id = UUID.randomUUID();
|
||||
Image novaImageToConvert = Image.builder().id(id.toString()).name("Test Image " + id).build();
|
||||
OperatingSystem operatingSystem = new OperatingSystem(OsFamily.UBUNTU, "My Test OS", "My Test Version", "x86", "My Test OS", true);
|
||||
NovaImageToImage converter = new NovaImageToImage(new MockImageToOsConverter(operatingSystem));
|
||||
org.jclouds.compute.domain.Image convertedImage = converter.apply(novaImageToConvert);
|
||||
|
||||
assertEquals(convertedImage.getId(), novaImageToConvert.getId());
|
||||
assertEquals(convertedImage.getName(), novaImageToConvert.getName());
|
||||
assertEquals(convertedImage.getOperatingSystem(), operatingSystem);
|
||||
}
|
||||
|
||||
private class MockImageToOsConverter implements Function<Image, OperatingSystem>
|
||||
{
|
||||
|
||||
private final OperatingSystem operatingSystem;
|
||||
|
||||
public MockImageToOsConverter(OperatingSystem operatingSystem)
|
||||
{
|
||||
this.operatingSystem = operatingSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OperatingSystem apply(@Nullable Image image)
|
||||
{
|
||||
return operatingSystem;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object o)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
/**
|
||||
* 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.functions;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.compute.domain.OsFamily;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.NovaImageToOperatingSystem;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Image;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/**
|
||||
* Tests for the function for transforming a nova specific Image into a generic OperatingSystem object.
|
||||
*
|
||||
* @author Matt Stephenson
|
||||
*/
|
||||
public class NovaImageToOperatingSystemTest
|
||||
{
|
||||
|
||||
@Test(dataProvider = "getOsFamilyValues")
|
||||
public void testOsFamilyValues(OsFamily family)
|
||||
{
|
||||
|
||||
Image imageToConvert = Image.builder().id("id-" + family.name()).name(family.name()).build();
|
||||
|
||||
NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(new HashMap<OsFamily, Map<String, String>>());
|
||||
|
||||
OperatingSystem convertedOs = converter.apply(imageToConvert);
|
||||
|
||||
assertEquals(convertedOs.getName(), imageToConvert.getName());
|
||||
assertEquals(convertedOs.getFamily(), family);
|
||||
assertEquals(convertedOs.getDescription(), imageToConvert.getName());
|
||||
assertEquals(convertedOs.getVersion(), null);
|
||||
assertEquals(convertedOs.getArch(), null);
|
||||
assertTrue(convertedOs.is64Bit());
|
||||
}
|
||||
|
||||
@DataProvider
|
||||
public Object[][] getOsFamilyValues()
|
||||
{
|
||||
return Iterables.toArray(Iterables.transform(Arrays.asList(OsFamily.values()), new Function<OsFamily, Object[]>()
|
||||
{
|
||||
@Override
|
||||
public Object[] apply(@Nullable OsFamily osFamily)
|
||||
{
|
||||
return new Object[]{osFamily};
|
||||
}
|
||||
}), Object[].class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWindowsServer2008R2x64()
|
||||
{
|
||||
String name = "Windows Server 2008 R2 x64";
|
||||
|
||||
Image imageToConvert = Image.builder().id("id-" + name).name(name).build();
|
||||
|
||||
Map<OsFamily, Map<String, String>> osFamilyMap = new HashMap<OsFamily, Map<String, String>>();
|
||||
osFamilyMap.put(OsFamily.WINDOWS, ImmutableMap.of("Server 2008 R2", "Server-2008-R2"));
|
||||
|
||||
NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(osFamilyMap);
|
||||
|
||||
OperatingSystem convertedOs = converter.apply(imageToConvert);
|
||||
|
||||
assertEquals(convertedOs.getName(), imageToConvert.getName());
|
||||
assertEquals(convertedOs.getFamily(), OsFamily.WINDOWS);
|
||||
assertEquals(convertedOs.getDescription(), imageToConvert.getName());
|
||||
assertEquals(convertedOs.getVersion(), "Server-2008-R2");
|
||||
assertEquals(convertedOs.getArch(), null);
|
||||
assertTrue(convertedOs.is64Bit());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWindows98x86()
|
||||
{
|
||||
String name = "Windows 98 x86";
|
||||
|
||||
Image imageToConvert = Image.builder().id("id-" + name).name(name).build();
|
||||
|
||||
Map<OsFamily, Map<String, String>> osFamilyMap = new HashMap<OsFamily, Map<String, String>>();
|
||||
osFamilyMap.put(OsFamily.WINDOWS, ImmutableMap.of("98", "98"));
|
||||
|
||||
NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(osFamilyMap);
|
||||
|
||||
OperatingSystem convertedOs = converter.apply(imageToConvert);
|
||||
|
||||
assertEquals(convertedOs.getName(), imageToConvert.getName());
|
||||
assertEquals(convertedOs.getFamily(), OsFamily.WINDOWS);
|
||||
assertEquals(convertedOs.getDescription(), imageToConvert.getName());
|
||||
assertEquals(convertedOs.getVersion(), "98");
|
||||
assertEquals(convertedOs.getArch(), null);
|
||||
assertFalse(convertedOs.is64Bit());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRHEL()
|
||||
{
|
||||
String name = "Red Hat EL";
|
||||
|
||||
Image imageToConvert = Image.builder().id("id-" + name).name(name).build();
|
||||
|
||||
NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(new HashMap<OsFamily, Map<String, String>>());
|
||||
|
||||
OperatingSystem convertedOs = converter.apply(imageToConvert);
|
||||
|
||||
assertEquals(convertedOs.getName(), imageToConvert.getName());
|
||||
assertEquals(convertedOs.getFamily(), OsFamily.RHEL);
|
||||
assertEquals(convertedOs.getDescription(), imageToConvert.getName());
|
||||
assertEquals(convertedOs.getVersion(), null);
|
||||
assertEquals(convertedOs.getArch(), null);
|
||||
assertTrue(convertedOs.is64Bit());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOEL()
|
||||
{
|
||||
String name = "Oracle EL";
|
||||
|
||||
Image imageToConvert = Image.builder().id("id-" + name).name(name).build();
|
||||
|
||||
NovaImageToOperatingSystem converter = new NovaImageToOperatingSystem(new HashMap<OsFamily, Map<String, String>>());
|
||||
|
||||
OperatingSystem convertedOs = converter.apply(imageToConvert);
|
||||
|
||||
assertEquals(convertedOs.getName(), imageToConvert.getName());
|
||||
assertEquals(convertedOs.getFamily(), OsFamily.OEL);
|
||||
assertEquals(convertedOs.getDescription(), imageToConvert.getName());
|
||||
assertEquals(convertedOs.getVersion(), null);
|
||||
assertEquals(convertedOs.getArch(), null);
|
||||
assertTrue(convertedOs.is64Bit());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
/**
|
||||
* 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.functions;
|
||||
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.ServerToNodeMetadata;
|
||||
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.ServerStatus;
|
||||
import org.testng.annotations.Test;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.testng.Assert.assertEquals;
|
||||
import static org.testng.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* Tests for the function for transforming a nova specific Server into a generic NodeMetadata object.
|
||||
*
|
||||
* @author Matt Stephenson
|
||||
*/
|
||||
public class ServerToNodeMetadataTest
|
||||
{
|
||||
@Test
|
||||
public void testConversion()
|
||||
{
|
||||
UUID id = UUID.randomUUID();
|
||||
Server serverToConvert = Server.builder()
|
||||
.id(id.toString())
|
||||
.name("Test Server " + id)
|
||||
.privateAddresses(Address.createV4("10.0.0.1"))
|
||||
.publicAddresses(Address.createV4("10.0.1.1"))
|
||||
.status(ServerStatus.ACTIVE)
|
||||
.build();
|
||||
|
||||
ServerToNodeMetadata converter = new ServerToNodeMetadata();
|
||||
|
||||
NodeMetadata convertedNodeMetadata = converter.apply(serverToConvert);
|
||||
|
||||
assertEquals(serverToConvert.getId(), convertedNodeMetadata.getId());
|
||||
assertEquals(serverToConvert.getName(), convertedNodeMetadata.getName());
|
||||
assertEquals(serverToConvert.getStatus().getNodeState(), convertedNodeMetadata.getState());
|
||||
|
||||
assertNotNull(convertedNodeMetadata.getPrivateAddresses());
|
||||
assertEquals(convertedNodeMetadata.getPrivateAddresses().size(), 1);
|
||||
assertEquals(convertedNodeMetadata.getPrivateAddresses().iterator().next(), "10.0.0.1");
|
||||
|
||||
assertNotNull(convertedNodeMetadata.getPublicAddresses());
|
||||
assertEquals(convertedNodeMetadata.getPublicAddresses().size(), 1);
|
||||
assertEquals(convertedNodeMetadata.getPublicAddresses().iterator().next(), "10.0.1.1");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/**
|
||||
* 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.internal;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Module;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceContextFactory;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.logging.config.NullLoggingModule;
|
||||
import org.jclouds.openstack.keystone.v2_0.internal.KeystoneFixture;
|
||||
import org.jclouds.rest.BaseRestClientExpectTest;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* Base class for writing KeyStone Expect tests with the ComputeService abstraction
|
||||
*
|
||||
* @author Matt Stephenson
|
||||
*/
|
||||
public class BaseNovaComputeServiceExpectTest extends BaseRestClientExpectTest<ComputeService>
|
||||
{
|
||||
protected HttpRequest keystoneAuthWithUsernameAndPassword;
|
||||
protected HttpRequest keystoneAuthWithAccessKeyAndSecretKey;
|
||||
protected String authToken;
|
||||
protected HttpResponse responseWithKeystoneAccess;
|
||||
|
||||
public BaseNovaComputeServiceExpectTest()
|
||||
{
|
||||
provider = "openstack-nova";
|
||||
keystoneAuthWithUsernameAndPassword = KeystoneFixture.INSTANCE.initialAuthWithUsernameAndPassword(identity,
|
||||
credential);
|
||||
keystoneAuthWithAccessKeyAndSecretKey = KeystoneFixture.INSTANCE.initialAuthWithAccessKeyAndSecretKey(identity,
|
||||
credential);
|
||||
authToken = KeystoneFixture.INSTANCE.getAuthToken();
|
||||
responseWithKeystoneAccess = KeystoneFixture.INSTANCE.responseWithAccess();
|
||||
// now, createContext arg will need tenant prefix
|
||||
identity = KeystoneFixture.INSTANCE.getTenantName() + ":" + identity;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ComputeService createClient(Function<HttpRequest, HttpResponse> fn, Module module, Properties props)
|
||||
{
|
||||
return new ComputeServiceContextFactory(setupRestProperties()).createContext(provider, identity, credential,
|
||||
ImmutableSet.<Module>of(new ExpectModule(fn), new NullLoggingModule(), module), props).getComputeService();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"servers": [
|
||||
{
|
||||
"id": "52415800-8b69-11e0-9b19-734f000004d2",
|
||||
"tenant_id": "1234",
|
||||
"user_id": "5678",
|
||||
"name": "sample-server",
|
||||
"updated": "2010-10-10T12:00:00Z",
|
||||
"created": "2010-08-10T12:00:00Z",
|
||||
"hostId": "e4d909c290d0fb1ca068ffaddf22cbd0",
|
||||
"accessIPv4" : "67.23.10.132",
|
||||
"accessIPv6" : "::babe:67.23.10.132",
|
||||
"status": "BUILD",
|
||||
"progress": 60,
|
||||
"image" : {
|
||||
"id": "52415800-8b69-11e0-9b19-734f6f006e54",
|
||||
"links": [
|
||||
{
|
||||
"rel": "self",
|
||||
"href": "http://servers.api.openstack.org/v1.1/1234/images/52415800-8b69-11e0-9b19-734f6f006e54"
|
||||
},
|
||||
{
|
||||
"rel": "bookmark",
|
||||
"href": "http://servers.api.openstack.org/1234/images/52415800-8b69-11e0-9b19-734f6f006e54"
|
||||
}
|
||||
]
|
||||
},
|
||||
"flavor" : {
|
||||
"id": "52415800-8b69-11e0-9b19-734f216543fd",
|
||||
"links": [
|
||||
{
|
||||
"rel": "self",
|
||||
"href": "http://servers.api.openstack.org/v1.1/1234/flavors/52415800-8b69-11e0-9b19-734f216543fd"
|
||||
},
|
||||
{
|
||||
"rel": "bookmark",
|
||||
"href": "http://servers.api.openstack.org/1234/flavors/52415800-8b69-11e0-9b19-734f216543fd"
|
||||
}
|
||||
]
|
||||
},
|
||||
"addresses": {
|
||||
"public" : [
|
||||
{
|
||||
"version": 4,
|
||||
"addr": "67.23.10.132"
|
||||
},
|
||||
{
|
||||
"version": 6,
|
||||
"addr": "::babe:67.23.10.132"
|
||||
},
|
||||
{
|
||||
"version": 4,
|
||||
"addr": "67.23.10.131"
|
||||
},
|
||||
{
|
||||
"version": 6,
|
||||
"addr": "::babe:4317:0A83"
|
||||
}
|
||||
],
|
||||
"private" : [
|
||||
{
|
||||
"version": 4,
|
||||
"addr": "10.176.42.16"
|
||||
},
|
||||
{
|
||||
"version": 6,
|
||||
"addr": "::babe:10.176.42.16"
|
||||
}
|
||||
]
|
||||
},
|
||||
"metadata": {
|
||||
"Server Label": "Web Head 1",
|
||||
"Image Version": "2.1"
|
||||
},
|
||||
"links": [
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue