mirror of https://github.com/apache/jclouds.git
openstack implicit security group integration with compute service; ensured hpcloud doesn't pickup kernel or ramdisk images
This commit is contained in:
parent
ac2528ef6f
commit
c9b5b1db87
|
@ -204,7 +204,25 @@ public class NodePredicates {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Return nodes who have a value for {@link NodeMetadata#getGroup}
|
||||
*
|
||||
*/
|
||||
public static Predicate<NodeMetadata> hasGroup() {
|
||||
return new Predicate<NodeMetadata>() {
|
||||
@Override
|
||||
public boolean apply(NodeMetadata nodeMetadata) {
|
||||
return nodeMetadata.getGroup() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "hasGroup()";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Return nodes with specified group that are in the NODE_RUNNING state.
|
||||
*
|
||||
|
|
|
@ -243,5 +243,5 @@ filesystem.propertiesbuilder=org.jclouds.filesystem.FilesystemBlobStorePropertie
|
|||
hpcloud-objectstorage-lvs.contextbuilder=org.jclouds.hpcloud.objectstorage.lvs.HPCloudObjectStorageLasVegasContextBuilder
|
||||
hpcloud-objectstorage-lvs.propertiesbuilder=org.jclouds.hpcloud.objectstorage.lvs.HPCloudObjectStorageLasVegasPropertiesBuilder
|
||||
|
||||
hpcloud-compute.contextbuilder=org.jclouds.openstack.nova.v1_1.NovaContextBuilder
|
||||
hpcloud-compute.contextbuilder=org.jclouds.hpcloud.compute.HPCloudComputeContextBuilder
|
||||
hpcloud-compute.propertiesbuilder=org.jclouds.hpcloud.compute.HPCloudComputePropertiesBuilder
|
||||
|
|
|
@ -16,32 +16,28 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.domain;
|
||||
package org.jclouds.hpcloud.compute;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.hpcloud.compute.config.HPCloudComputeServiceContextModule;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaContextBuilder;
|
||||
|
||||
import com.google.inject.Module;
|
||||
|
||||
/**
|
||||
* In-flight images will have the status attribute set to SAVING and the
|
||||
* conditional progress element (0-100% completion) will also be returned. Other
|
||||
* possible values for the status attribute include: UNKNOWN, ACTIVE, SAVING,
|
||||
* ERROR, and DELETED. Images with an ACTIVE status are available for install.
|
||||
* The optional minDisk and minRam attributes set the minimum disk and RAM
|
||||
* requirements needed to create a server with the image.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum ImageStatus {
|
||||
public class HPCloudComputeContextBuilder extends NovaContextBuilder {
|
||||
|
||||
UNRECOGNIZED, UNKNOWN, ACTIVE, SAVING, ERROR, DELETED;
|
||||
|
||||
public String value() {
|
||||
return name();
|
||||
public HPCloudComputeContextBuilder(Properties props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
public static ImageStatus fromValue(String v) {
|
||||
try {
|
||||
return valueOf(v);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
@Override
|
||||
protected void addContextModule(List<Module> modules) {
|
||||
modules.add(new HPCloudComputeServiceContextModule());
|
||||
}
|
||||
|
||||
}
|
|
@ -20,11 +20,12 @@ package org.jclouds.hpcloud.compute;
|
|||
|
||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||
import static org.jclouds.Constants.PROPERTY_ISO3166_CODES;
|
||||
import static org.jclouds.compute.reference.ComputeServiceConstants.PROPERTY_TIMEOUT_NODE_TERMINATED;
|
||||
import static org.jclouds.openstack.nova.v1_1.reference.NovaConstants.PROPERTY_NOVA_AUTO_ALLOCATE_FLOATING_IPS;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.NovaPropertiesBuilder;
|
||||
import org.jclouds.openstack.nova.v1_1.reference.NovaConstants;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -37,7 +38,9 @@ public class HPCloudComputePropertiesBuilder extends NovaPropertiesBuilder {
|
|||
Properties properties = super.defaultProperties();
|
||||
properties.setProperty(PROPERTY_ISO3166_CODES, "US-NV");
|
||||
properties.setProperty(PROPERTY_ENDPOINT, "https://region-a.geo-1.identity.hpcloudsvc.com:35357");
|
||||
properties.setProperty(NovaConstants.PROPERTY_NOVA_AUTO_ALLOCATE_FLOATING_IPS, "true");
|
||||
properties.setProperty(PROPERTY_NOVA_AUTO_ALLOCATE_FLOATING_IPS, "true");
|
||||
// deallocating ip addresses can take a while
|
||||
properties.setProperty(PROPERTY_TIMEOUT_NODE_TERMINATED, 60 * 1000 + "");
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
package org.jclouds.hpcloud.compute;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.location.Zone;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.NovaComputeServiceAdapter;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.RemoveFloatingIpFromNodeAndDeallocate;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ImageInZone;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.Iterables;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class HPCloudComputeServiceAdapter extends NovaComputeServiceAdapter {
|
||||
|
||||
@Inject
|
||||
public HPCloudComputeServiceAdapter(NovaClient novaClient, @Zone Supplier<Set<String>> zoneIds,
|
||||
RemoveFloatingIpFromNodeAndDeallocate removeFloatingIpFromNodeAndDeallocate) {
|
||||
super(novaClient, zoneIds, removeFloatingIpFromNodeAndDeallocate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterable<ImageInZone> listImages() {
|
||||
return Iterables.filter(super.listImages(), new Predicate<ImageInZone>() {
|
||||
|
||||
@Override
|
||||
public boolean apply(ImageInZone arg0) {
|
||||
String imageName = arg0.getImage().getName();
|
||||
return imageName.indexOf("Kernel") == -1 && imageName.indexOf("Ramdisk") == -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "notKernelOrRamdisk";
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* 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.hpcloud.compute.config;
|
||||
|
||||
import org.jclouds.hpcloud.compute.HPCloudComputeServiceAdapter;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.NovaComputeServiceAdapter;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.config.NovaComputeServiceContextModule;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class HPCloudComputeServiceContextModule extends NovaComputeServiceContextModule {
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
super.configure();
|
||||
bind(NovaComputeServiceAdapter.class).to(HPCloudComputeServiceAdapter.class);
|
||||
}
|
||||
|
||||
}
|
|
@ -73,6 +73,7 @@ public class HPCloudComputeTemplateBuilderLiveTest extends BaseTemplateBuilderLi
|
|||
assertEquals(defaultTemplate.getImage().getOperatingSystem().is64Bit(), true);
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "11.10");
|
||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
||||
assertEquals(defaultTemplate.getImage().getName(), "Ubuntu Oneiric 11.10 Server 64-bit 20111212");
|
||||
assertEquals(defaultTemplate.getLocation().getId(), "az-1.region-a.geo-1");
|
||||
assertEquals(defaultTemplate.getOptions().as(NovaTemplateOptions.class).shouldAutoAssignFloatingIp(), true);
|
||||
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
||||
|
|
|
@ -45,7 +45,6 @@ public class NovaPropertiesBuilder extends PropertiesBuilder {
|
|||
properties.setProperty(PROPERTY_API_VERSION, "1.1");
|
||||
properties.setProperty(PROPERTY_NOVA_AUTO_ALLOCATE_FLOATING_IPS, "false");
|
||||
properties.setProperty(PROPERTY_NOVA_TIMEOUT_SECURITYGROUP_PRESENT, "500");
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.ComputeServiceContext;
|
||||
import org.jclouds.compute.callables.RunScriptOnNode;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.internal.BaseComputeService;
|
||||
import org.jclouds.compute.internal.PersistNodeCredentials;
|
||||
import org.jclouds.compute.options.TemplateOptions;
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants.Timeouts;
|
||||
import org.jclouds.compute.strategy.CreateNodesInGroupThenAddToSet;
|
||||
import org.jclouds.compute.strategy.DestroyNodeStrategy;
|
||||
import org.jclouds.compute.strategy.GetNodeMetadataStrategy;
|
||||
import org.jclouds.compute.strategy.InitializeRunScriptOnNodeOrPlaceInBadMap;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
import org.jclouds.compute.strategy.RebootNodeStrategy;
|
||||
import org.jclouds.compute.strategy.ResumeNodeStrategy;
|
||||
import org.jclouds.compute.strategy.SuspendNodeStrategy;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.options.NovaTemplateOptions;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndName;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClient;
|
||||
import org.jclouds.openstack.nova.v1_1.predicates.SecurityGroupPredicates;
|
||||
import org.jclouds.scriptbuilder.functions.InitAdminAccess;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class NovaComputeService extends BaseComputeService {
|
||||
private final NovaClient novaClient;
|
||||
private final LoadingCache<ZoneAndName, SecurityGroupInZone> securityGroupMap;
|
||||
private final Function<Set<? extends NodeMetadata>, Multimap<String, String>> orphanedGroupsByZoneId;
|
||||
|
||||
@Inject
|
||||
protected NovaComputeService(ComputeServiceContext context, Map<String, Credentials> credentialStore,
|
||||
@Memoized Supplier<Set<? extends Image>> images, @Memoized Supplier<Set<? extends Hardware>> sizes,
|
||||
@Memoized Supplier<Set<? extends Location>> locations, ListNodesStrategy listNodesStrategy,
|
||||
GetNodeMetadataStrategy getNodeMetadataStrategy,
|
||||
CreateNodesInGroupThenAddToSet runNodesAndAddToSetStrategy, RebootNodeStrategy rebootNodeStrategy,
|
||||
DestroyNodeStrategy destroyNodeStrategy, ResumeNodeStrategy startNodeStrategy,
|
||||
SuspendNodeStrategy stopNodeStrategy, Provider<TemplateBuilder> templateBuilderProvider,
|
||||
Provider<TemplateOptions> templateOptionsProvider,
|
||||
@Named("NODE_RUNNING") Predicate<AtomicReference<NodeMetadata>> nodeRunning,
|
||||
@Named("NODE_TERMINATED") Predicate<AtomicReference<NodeMetadata>> nodeTerminated,
|
||||
@Named("NODE_SUSPENDED") Predicate<AtomicReference<NodeMetadata>> nodeSuspended,
|
||||
InitializeRunScriptOnNodeOrPlaceInBadMap.Factory initScriptRunnerFactory,
|
||||
RunScriptOnNode.Factory runScriptOnNodeFactory, InitAdminAccess initAdminAccess,
|
||||
PersistNodeCredentials persistNodeCredentials, Timeouts timeouts,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor, NovaClient novaClient,
|
||||
LoadingCache<ZoneAndName, SecurityGroupInZone> securityGroupMap,
|
||||
Function<Set<? extends NodeMetadata>, Multimap<String, String>> orphanedGroupsByZoneId) {
|
||||
super(context, credentialStore, images, sizes, locations, listNodesStrategy, getNodeMetadataStrategy,
|
||||
runNodesAndAddToSetStrategy, rebootNodeStrategy, destroyNodeStrategy, startNodeStrategy,
|
||||
stopNodeStrategy, templateBuilderProvider, templateOptionsProvider, nodeRunning, nodeTerminated,
|
||||
nodeSuspended, initScriptRunnerFactory, initAdminAccess, runScriptOnNodeFactory, persistNodeCredentials,
|
||||
timeouts, executor);
|
||||
this.novaClient = checkNotNull(novaClient, "novaClient");
|
||||
this.securityGroupMap = checkNotNull(securityGroupMap, "securityGroupMap");
|
||||
this.orphanedGroupsByZoneId = checkNotNull(orphanedGroupsByZoneId, "orphanedGroupsByZoneId");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void cleanUpIncidentalResourcesOfDeadNodes(Set<? extends NodeMetadata> deadNodes) {
|
||||
Multimap<String, String> zoneToZoneAndGroupNames = orphanedGroupsByZoneId.apply(deadNodes);
|
||||
for (String zoneId : zoneToZoneAndGroupNames.keySet()) {
|
||||
cleanOrphanedGroupsInZone(ImmutableSet.copyOf(zoneToZoneAndGroupNames.get(zoneId)), zoneId);
|
||||
}
|
||||
}
|
||||
|
||||
protected void cleanOrphanedGroupsInZone(Set<String> groups, String zoneId) {
|
||||
cleanupOrphanedSecurityGroupsInZone(groups, zoneId);
|
||||
}
|
||||
|
||||
private void cleanupOrphanedSecurityGroupsInZone(Set<String> groups, String zoneId) {
|
||||
Optional<SecurityGroupClient> securityGroupClient = novaClient.getSecurityGroupExtensionForZone(zoneId);
|
||||
if (securityGroupClient.isPresent()) {
|
||||
for (String group : groups) {
|
||||
for (SecurityGroup securityGroup : Iterables.filter(securityGroupClient.get().listSecurityGroups(),
|
||||
SecurityGroupPredicates.nameEquals("jclouds#" + group))) {
|
||||
ZoneAndName zoneAndName = ZoneAndName.fromZoneAndName(zoneId, securityGroup.getName());
|
||||
logger.debug(">> deleting securityGroup(%s)", zoneAndName);
|
||||
securityGroupClient.get().deleteSecurityGroup(securityGroup.getId());
|
||||
// TODO: test this clear happens
|
||||
securityGroupMap.invalidate(zoneAndName);
|
||||
logger.debug("<< deleted securityGroup(%s)", zoneAndName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns template options, except of type {@link NovaTemplateOptions}.
|
||||
*/
|
||||
@Override
|
||||
public NovaTemplateOptions templateOptions() {
|
||||
return NovaTemplateOptions.class.cast(super.templateOptions());
|
||||
}
|
||||
|
||||
}
|
|
@ -34,10 +34,6 @@ import org.jclouds.domain.LoginCredentials;
|
|||
import org.jclouds.location.Zone;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.FlavorInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ImageInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ServerInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneAndId;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.RemoveFloatingIpFromNodeAndDeallocate;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.options.NovaTemplateOptions;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.strategy.ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet;
|
||||
|
@ -45,12 +41,17 @@ 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.domain.zonescoped.FlavorInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ImageInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ServerInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndId;
|
||||
import org.jclouds.openstack.nova.v1_1.options.CreateServerOptions;
|
||||
import org.jclouds.openstack.nova.v1_1.predicates.ImagePredicates;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Iterables;
|
||||
import static com.google.common.collect.Iterables.*;
|
||||
import com.google.common.collect.ImmutableSet.Builder;
|
||||
|
||||
/**
|
||||
|
@ -103,7 +104,7 @@ public class NovaComputeServiceAdapter implements
|
|||
public Iterable<FlavorInZone> listHardwareProfiles() {
|
||||
Builder<FlavorInZone> builder = ImmutableSet.<FlavorInZone> builder();
|
||||
for (final String zoneId : zoneIds.get()) {
|
||||
builder.addAll(Iterables.transform(novaClient.getFlavorClientForZone(zoneId).listFlavorsInDetail(),
|
||||
builder.addAll(transform(novaClient.getFlavorClientForZone(zoneId).listFlavorsInDetail(),
|
||||
new Function<Flavor, FlavorInZone>() {
|
||||
|
||||
@Override
|
||||
|
@ -120,15 +121,15 @@ public class NovaComputeServiceAdapter implements
|
|||
public Iterable<ImageInZone> listImages() {
|
||||
Builder<ImageInZone> builder = ImmutableSet.<ImageInZone> builder();
|
||||
for (final String zoneId : zoneIds.get()) {
|
||||
builder.addAll(Iterables.transform(novaClient.getImageClientForZone(zoneId).listImagesInDetail(),
|
||||
new Function<Image, ImageInZone>() {
|
||||
builder.addAll(transform(filter(novaClient.getImageClientForZone(zoneId).listImagesInDetail(), ImagePredicates
|
||||
.statusEquals(Image.Status.ACTIVE)), new Function<Image, ImageInZone>() {
|
||||
|
||||
@Override
|
||||
public ImageInZone apply(Image arg0) {
|
||||
return new ImageInZone(arg0, zoneId);
|
||||
}
|
||||
@Override
|
||||
public ImageInZone apply(Image arg0) {
|
||||
return new ImageInZone(arg0, zoneId);
|
||||
}
|
||||
|
||||
}));
|
||||
}));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
@ -137,7 +138,7 @@ public class NovaComputeServiceAdapter implements
|
|||
public Iterable<ServerInZone> listNodes() {
|
||||
Builder<ServerInZone> builder = ImmutableSet.<ServerInZone> builder();
|
||||
for (final String zoneId : zoneIds.get()) {
|
||||
builder.addAll(Iterables.transform(novaClient.getServerClientForZone(zoneId).listServersInDetail(),
|
||||
builder.addAll(transform(novaClient.getServerClientForZone(zoneId).listServersInDetail(),
|
||||
new Function<Server, ServerInZone>() {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -27,6 +27,7 @@ import javax.inject.Named;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.collect.Memoized;
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.ComputeServiceAdapter;
|
||||
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
|
@ -39,23 +40,25 @@ 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.NovaComputeService;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.NovaComputeServiceAdapter;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.FlavorInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ImageInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ServerInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneAndId;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneAndName;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneSecurityGroupNameAndPorts;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.CreateSecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.CreateSecurityGroupIfNeeded;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.FlavorInZoneToHardware;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.ImageInZoneToImage;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.NovaImageToOperatingSystem;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.OrphanedGroupsByZoneId;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.ServerInZoneToNodeMetadata;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.loaders.CreateOrUpdateSecurityGroupAsNeeded;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.loaders.FindSecurityGroupOrCreate;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.loaders.LoadFloatingIpsForInstance;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.options.NovaTemplateOptions;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.strategy.ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.FlavorInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ImageInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ServerInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndId;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndName;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
|
||||
import org.jclouds.openstack.nova.v1_1.predicates.FindSecurityGroupWithNameAndReturnTrue;
|
||||
import org.jclouds.openstack.nova.v1_1.reference.NovaConstants;
|
||||
import org.jclouds.predicates.RetryablePredicate;
|
||||
|
@ -68,6 +71,7 @@ import com.google.common.cache.CacheBuilder;
|
|||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.inject.Injector;
|
||||
import com.google.inject.Key;
|
||||
import com.google.inject.Provides;
|
||||
|
@ -92,10 +96,15 @@ public class NovaComputeServiceContextModule
|
|||
super.configure();
|
||||
bind(new TypeLiteral<ComputeServiceAdapter<ServerInZone, FlavorInZone, ImageInZone, Location>>() {
|
||||
}).to(NovaComputeServiceAdapter.class);
|
||||
|
||||
|
||||
bind(ComputeService.class).to(NovaComputeService.class);
|
||||
|
||||
bind(new TypeLiteral<Function<ServerInZone, NodeMetadata>>() {
|
||||
}).to(ServerInZoneToNodeMetadata.class);
|
||||
|
||||
bind(new TypeLiteral<Function<Set<? extends NodeMetadata>, Multimap<String, String>>>() {
|
||||
}).to(OrphanedGroupsByZoneId.class);
|
||||
|
||||
bind(new TypeLiteral<Function<ImageInZone, Image>>() {
|
||||
}).to(ImageInZoneToImage.class);
|
||||
bind(new TypeLiteral<Function<org.jclouds.openstack.nova.v1_1.domain.Image, OperatingSystem>>() {
|
||||
|
@ -112,12 +121,12 @@ public class NovaComputeServiceContextModule
|
|||
|
||||
bind(new TypeLiteral<CacheLoader<ZoneAndId, Iterable<String>>>() {
|
||||
}).annotatedWith(Names.named("FLOATINGIP")).to(LoadFloatingIpsForInstance.class);
|
||||
|
||||
|
||||
bind(new TypeLiteral<Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone>>() {
|
||||
}).to(CreateSecurityGroupInZone.class);
|
||||
|
||||
bind(new TypeLiteral<CacheLoader<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone>>() {
|
||||
}).to(CreateOrUpdateSecurityGroupAsNeeded.class);
|
||||
}).to(CreateSecurityGroupIfNeeded.class);
|
||||
|
||||
bind(new TypeLiteral<CacheLoader<ZoneAndName, SecurityGroupInZone>>() {
|
||||
}).to(FindSecurityGroupOrCreate.class);
|
||||
|
||||
bind(CreateNodesWithGroupEncodedIntoNameThenAddToSet.class).to(
|
||||
ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.class);
|
||||
|
@ -141,8 +150,8 @@ public class NovaComputeServiceContextModule
|
|||
|
||||
@Provides
|
||||
@Singleton
|
||||
protected LoadingCache<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> securityGroupMap(
|
||||
CacheLoader<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> in) {
|
||||
protected LoadingCache<ZoneAndName, SecurityGroupInZone> securityGroupMap(
|
||||
CacheLoader<ZoneAndName, SecurityGroupInZone> in) {
|
||||
return CacheBuilder.newBuilder().build(in);
|
||||
}
|
||||
|
||||
|
|
|
@ -34,8 +34,8 @@ import org.jclouds.compute.domain.NodeMetadataBuilder;
|
|||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneAndId;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.FloatingIP;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndId;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
||||
import org.jclouds.rest.InsufficientResourcesException;
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ package org.jclouds.openstack.nova.v1_1.compute.functions;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.find;
|
||||
import static org.jclouds.openstack.nova.v1_1.predicates.SecurityGroupPredicates.nameEquals;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
@ -29,11 +31,11 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneSecurityGroupNameAndPorts;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Ingress;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.IpProtocol;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClient;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
@ -44,14 +46,14 @@ import com.google.common.base.Optional;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class CreateSecurityGroupInZone implements Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> {
|
||||
public class CreateSecurityGroupIfNeeded implements Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
protected final NovaClient novaClient;
|
||||
|
||||
@Inject
|
||||
public CreateSecurityGroupInZone(NovaClient novaClient) {
|
||||
public CreateSecurityGroupIfNeeded(NovaClient novaClient) {
|
||||
this.novaClient = checkNotNull(novaClient, "novaClient");
|
||||
}
|
||||
|
||||
|
@ -62,16 +64,24 @@ public class CreateSecurityGroupInZone implements Function<ZoneSecurityGroupName
|
|||
String zoneId = zoneSecurityGroupNameAndPorts.getZone();
|
||||
Optional<SecurityGroupClient> client = novaClient.getSecurityGroupExtensionForZone(zoneId);
|
||||
checkArgument(client.isPresent(), "Security groups are required, but the extension is not available!");
|
||||
|
||||
logger.debug(">> creating securityGroup %s", zoneSecurityGroupNameAndPorts);
|
||||
SecurityGroup securityGroup = client.get().createSecurityGroupWithNameAndDescription(
|
||||
zoneSecurityGroupNameAndPorts.getName(), zoneSecurityGroupNameAndPorts.getName());
|
||||
try {
|
||||
|
||||
logger.debug("<< created securityGroup(%s)", securityGroup);
|
||||
for (int port : zoneSecurityGroupNameAndPorts.getPorts()) {
|
||||
authorizeGroupToItselfAndAllIPsToTCPPort(client.get(), securityGroup, port);
|
||||
SecurityGroup securityGroup = client.get().createSecurityGroupWithNameAndDescription(
|
||||
zoneSecurityGroupNameAndPorts.getName(), zoneSecurityGroupNameAndPorts.getName());
|
||||
|
||||
logger.debug("<< created securityGroup(%s)", securityGroup);
|
||||
for (int port : zoneSecurityGroupNameAndPorts.getPorts()) {
|
||||
authorizeGroupToItselfAndAllIPsToTCPPort(client.get(), securityGroup, port);
|
||||
}
|
||||
return new SecurityGroupInZone(client.get().getSecurityGroup(securityGroup.getId()), zoneId);
|
||||
} catch (IllegalStateException e) {
|
||||
logger.trace("<< trying to find securityGroup(%s): %s", zoneSecurityGroupNameAndPorts, e.getMessage());
|
||||
SecurityGroup group = find(client.get().listSecurityGroups(), nameEquals(zoneSecurityGroupNameAndPorts
|
||||
.getName()));
|
||||
logger.debug("<< reused securityGroup(%s)", group.getId());
|
||||
return new SecurityGroupInZone(group, zoneId);
|
||||
}
|
||||
return new SecurityGroupInZone(client.get().getSecurityGroup(securityGroup.getId()), zoneId);
|
||||
}
|
||||
|
||||
private void authorizeGroupToItselfAndAllIPsToTCPPort(SecurityGroupClient securityGroupClient,
|
|
@ -30,8 +30,8 @@ import org.jclouds.compute.domain.HardwareBuilder;
|
|||
import org.jclouds.compute.domain.Processor;
|
||||
import org.jclouds.compute.domain.internal.VolumeImpl;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.FlavorInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Flavor;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.FlavorInZone;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.jclouds.compute.domain.Image;
|
|||
import org.jclouds.compute.domain.ImageBuilder;
|
||||
import org.jclouds.compute.domain.OperatingSystem;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ImageInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ImageInZone;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Supplier;
|
||||
|
@ -55,8 +55,8 @@ public class ImageInZoneToImage implements Function<ImageInZone, Image> {
|
|||
Location location = locationIndex.get().get(imageInZone.getZone());
|
||||
checkState(location != null, "location %s not in locationIndex: %s", imageInZone.getZone(), locationIndex.get());
|
||||
org.jclouds.openstack.nova.v1_1.domain.Image image = imageInZone.getImage();
|
||||
return new ImageBuilder()
|
||||
.id(imageInZone.slashEncode()).providerId(image.getId()).name(image.getName()).operatingSystem(
|
||||
imageToOs.apply(image)).description(image.getName()).location(location).build();
|
||||
return new ImageBuilder().id(imageInZone.slashEncode()).providerId(image.getId()).name(image.getName())
|
||||
.userMetadata(image.getMetadata()).operatingSystem(imageToOs.apply(image)).description(image.getName())
|
||||
.location(location).build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/**
|
||||
* 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 static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static com.google.common.collect.Sets.filter;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.predicates.NodePredicates;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.predicates.AllNodesInGroupTerminated;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndName;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class OrphanedGroupsByZoneId implements Function<Set<? extends NodeMetadata>, Multimap<String, String>> {
|
||||
private final Predicate<ZoneAndName> allNodesInGroupTerminated;
|
||||
|
||||
@Inject
|
||||
protected OrphanedGroupsByZoneId(ComputeService computeService) {
|
||||
this(new AllNodesInGroupTerminated(checkNotNull(computeService, "computeService")));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
OrphanedGroupsByZoneId(Predicate<ZoneAndName> allNodesInGroupTerminated) {
|
||||
this.allNodesInGroupTerminated = checkNotNull(allNodesInGroupTerminated, "allNodesInGroupTerminated");
|
||||
}
|
||||
|
||||
public Multimap<String, String> apply(Set<? extends NodeMetadata> deadNodes) {
|
||||
Iterable<? extends NodeMetadata> nodesWithGroup = filter(deadNodes, NodePredicates.hasGroup());
|
||||
Set<ZoneAndName> zoneAndGroupNames = ImmutableSet.copyOf(filter(transform(nodesWithGroup,
|
||||
new Function<NodeMetadata, ZoneAndName>() {
|
||||
|
||||
@Override
|
||||
public ZoneAndName apply(NodeMetadata input) {
|
||||
String zoneId = input.getLocation().getScope() == LocationScope.HOST ? input.getLocation()
|
||||
.getParent().getId() : input.getLocation().getId();
|
||||
return ZoneAndName.fromZoneAndName(zoneId, input.getGroup());
|
||||
}
|
||||
|
||||
}), allNodesInGroupTerminated));
|
||||
Multimap<String, String> zoneToZoneAndGroupNames = Multimaps.transformValues(Multimaps.index(zoneAndGroupNames,
|
||||
ZoneAndName.ZONE_FUNCTION), ZoneAndName.NAME_FUNCTION);
|
||||
return zoneToZoneAndGroupNames;
|
||||
}
|
||||
|
||||
}
|
|
@ -27,7 +27,7 @@ import javax.inject.Named;
|
|||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneAndId;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndId;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
|
|
@ -20,8 +20,13 @@ package org.jclouds.openstack.nova.v1_1.compute.functions;
|
|||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
import static com.google.common.collect.Iterables.concat;
|
||||
import static com.google.common.collect.Iterables.filter;
|
||||
import static com.google.common.collect.Iterables.find;
|
||||
import static com.google.common.collect.Iterables.transform;
|
||||
import static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.Set;
|
||||
|
@ -42,16 +47,16 @@ import org.jclouds.domain.Location;
|
|||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ServerInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneAndId;
|
||||
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.zonescoped.ServerInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndId;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.net.InetAddresses;
|
||||
|
||||
/**
|
||||
* A function for transforming a nova-specific Server into a generic NodeMetadata object.
|
||||
|
@ -97,15 +102,29 @@ public class ServerInZoneToNodeMetadata implements Function<ServerInZone, NodeMe
|
|||
builder.operatingSystem(findOperatingSystemForServerOrNull(serverInZone));
|
||||
builder.hardware(findHardwareForServerOrNull(serverInZone));
|
||||
builder.state(from.getStatus().getNodeState());
|
||||
builder.publicAddresses(getPublicAddresses(serverInZone));
|
||||
builder.privateAddresses(Iterables.transform(from.getPrivateAddresses(),
|
||||
AddressToStringTransformationFunction.INSTANCE));
|
||||
builder.publicAddresses(filter(getPublicAddresses(serverInZone), isInet4Address));
|
||||
builder.privateAddresses(filter(transform(from.getPrivateAddresses(),
|
||||
AddressToStringTransformationFunction.INSTANCE), isInet4Address));
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static final Predicate<String> isInet4Address = new Predicate<String>() {
|
||||
@Override
|
||||
public boolean apply(String input) {
|
||||
try {
|
||||
// Note we can do this, as InetAddress is now on the white list
|
||||
return (InetAddresses.forString(input) instanceof Inet4Address);
|
||||
} catch (IllegalArgumentException e) {
|
||||
// could be a hostname
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
protected Iterable<String> getPublicAddresses(ServerInZone serverInZone) {
|
||||
return Iterables.concat(Iterables.transform(serverInZone.getServer().getPublicAddresses(),
|
||||
return concat(transform(serverInZone.getServer().getPublicAddresses(),
|
||||
AddressToStringTransformationFunction.INSTANCE), floatingIpCache.getUnchecked(serverInZone));
|
||||
}
|
||||
|
||||
|
@ -131,7 +150,7 @@ public class ServerInZoneToNodeMetadata implements Function<ServerInZone, NodeMe
|
|||
public <T extends ComputeMetadata> T findObjectOfTypeForServerOrNull(Set<? extends T> supply, String type,
|
||||
final String objectId, final ZoneAndId serverInZone) {
|
||||
try {
|
||||
return Iterables.find(supply, new Predicate<T>() {
|
||||
return find(supply, new Predicate<T>() {
|
||||
@Override
|
||||
public boolean apply(T input) {
|
||||
return input.getId().equals(ZoneAndId.fromZoneAndId(serverInZone.getZone(), objectId).slashEncode());
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
/**
|
||||
* 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.loaders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneAndName;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneSecurityGroupNameAndPorts;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Singleton
|
||||
public class CreateOrUpdateSecurityGroupAsNeeded extends
|
||||
CacheLoader<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> {
|
||||
@Resource
|
||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||
protected Logger logger = Logger.NULL;
|
||||
protected final Predicate<AtomicReference<ZoneAndName>> securityGroupEventualConsistencyDelay;
|
||||
protected final Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> groupCreator;
|
||||
|
||||
@Inject
|
||||
public CreateOrUpdateSecurityGroupAsNeeded(
|
||||
@Named("SECURITY") Predicate<AtomicReference<ZoneAndName>> securityGroupEventualConsistencyDelay,
|
||||
Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> groupCreator) {
|
||||
this.securityGroupEventualConsistencyDelay = checkNotNull(securityGroupEventualConsistencyDelay,
|
||||
"securityGroupEventualConsistencyDelay");
|
||||
this.groupCreator = checkNotNull(groupCreator, "groupCreator");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroupInZone load(ZoneSecurityGroupNameAndPorts zoneSecurityGroupNameAndPorts) {
|
||||
checkNotNull(zoneSecurityGroupNameAndPorts, "zoneSecurityGroupNameAndPorts");
|
||||
|
||||
AtomicReference<ZoneAndName> securityGroupInZoneRef = new AtomicReference<ZoneAndName>(
|
||||
zoneSecurityGroupNameAndPorts);
|
||||
|
||||
if (securityGroupEventualConsistencyDelay.apply(securityGroupInZoneRef)) {
|
||||
ZoneAndName securityGroupInZone = securityGroupInZoneRef.get();
|
||||
checkState(
|
||||
securityGroupInZone instanceof SecurityGroupInZone,
|
||||
"programming error: predicate %s should update the atomic reference to the actual security group found",
|
||||
securityGroupEventualConsistencyDelay);
|
||||
// TODO: check ports are actually present!
|
||||
return SecurityGroupInZone.class.cast(securityGroupInZone);
|
||||
} else {
|
||||
return groupCreator.apply(zoneSecurityGroupNameAndPorts);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* 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.loaders;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndName;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class FindSecurityGroupOrCreate extends CacheLoader<ZoneAndName, SecurityGroupInZone> {
|
||||
|
||||
protected final Predicate<AtomicReference<ZoneAndName>> returnSecurityGroupExistsInZone;
|
||||
protected final Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> groupCreator;
|
||||
|
||||
@Inject
|
||||
public FindSecurityGroupOrCreate(
|
||||
@Named("SECURITY") Predicate<AtomicReference<ZoneAndName>> returnSecurityGroupExistsInZone,
|
||||
Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> groupCreator) {
|
||||
this.returnSecurityGroupExistsInZone = checkNotNull(returnSecurityGroupExistsInZone,
|
||||
"returnSecurityGroupExistsInZone");
|
||||
this.groupCreator = checkNotNull(groupCreator, "groupCreator");
|
||||
}
|
||||
|
||||
@Override
|
||||
public SecurityGroupInZone load(ZoneAndName in) {
|
||||
AtomicReference<ZoneAndName> securityGroupInZoneRef = new AtomicReference<ZoneAndName>(checkNotNull(in,
|
||||
"zoneSecurityGroupNameAndPorts"));
|
||||
if (returnSecurityGroupExistsInZone.apply(securityGroupInZoneRef)) {
|
||||
return returnExistingSecurityGroup(securityGroupInZoneRef);
|
||||
} else {
|
||||
return createNewSecurityGroup(in);
|
||||
}
|
||||
}
|
||||
|
||||
private SecurityGroupInZone returnExistingSecurityGroup(AtomicReference<ZoneAndName> securityGroupInZoneRef) {
|
||||
ZoneAndName securityGroupInZone = securityGroupInZoneRef.get();
|
||||
checkState(securityGroupInZone instanceof SecurityGroupInZone,
|
||||
"programming error: predicate %s should update the atomic reference to the actual security group found",
|
||||
returnSecurityGroupExistsInZone);
|
||||
return SecurityGroupInZone.class.cast(securityGroupInZone);
|
||||
}
|
||||
|
||||
private SecurityGroupInZone createNewSecurityGroup(ZoneAndName in) {
|
||||
checkState(
|
||||
checkNotNull(in, "zoneSecurityGroupNameAndPorts") instanceof ZoneSecurityGroupNameAndPorts,
|
||||
"programming error: when issuing get to this cacheloader, you need to pass an instance of ZoneSecurityGroupNameAndPorts, not %s",
|
||||
in);
|
||||
ZoneSecurityGroupNameAndPorts zoneSecurityGroupNameAndPorts = ZoneSecurityGroupNameAndPorts.class.cast(in);
|
||||
return groupCreator.apply(zoneSecurityGroupNameAndPorts);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "returnExistingSecurityGroupInZoneOrCreateAsNeeded()";
|
||||
}
|
||||
|
||||
}
|
|
@ -22,8 +22,8 @@ import javax.inject.Inject;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneAndId;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.FloatingIP;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndId;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* 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.predicates;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Predicates.and;
|
||||
import static com.google.common.collect.Iterables.all;
|
||||
import static org.jclouds.compute.predicates.NodePredicates.TERMINATED;
|
||||
import static org.jclouds.compute.predicates.NodePredicates.inGroup;
|
||||
import static org.jclouds.compute.predicates.NodePredicates.locationId;
|
||||
import static org.jclouds.compute.predicates.NodePredicates.parentLocationId;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.jclouds.compute.ComputeService;
|
||||
import org.jclouds.compute.domain.ComputeMetadata;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndName;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class AllNodesInGroupTerminated implements Predicate<ZoneAndName> {
|
||||
private final ComputeService computeService;
|
||||
|
||||
|
||||
//TODO: TESTME
|
||||
@Inject
|
||||
public AllNodesInGroupTerminated(ComputeService computeService) {
|
||||
this.computeService = checkNotNull(computeService, "computeService");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(ZoneAndName input) {
|
||||
// new nodes can have the zone as their location, existing nodes, the parent is the
|
||||
// location
|
||||
return all(computeService.listNodesDetailsMatching(Predicates.<ComputeMetadata> or(locationId(input.getZone()),
|
||||
parentLocationId(input.getZone()))), and(inGroup(input.getName()), TERMINATED));
|
||||
}
|
||||
}
|
|
@ -21,20 +21,24 @@ package org.jclouds.openstack.nova.v1_1.compute.strategy;
|
|||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.Constants;
|
||||
import org.jclouds.compute.config.CustomizationResponse;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.compute.domain.Template;
|
||||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
|
||||
import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
||||
|
@ -43,8 +47,14 @@ import org.jclouds.concurrent.Futures;
|
|||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.AllocateAndAddFloatingIpToNode;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.options.NovaTemplateOptions;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndName;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.primitives.Ints;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -55,7 +65,9 @@ public class ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddT
|
|||
CreateNodesWithGroupEncodedIntoNameThenAddToSet {
|
||||
|
||||
private final AllocateAndAddFloatingIpToNode allocateAndAddFloatingIpToNode;
|
||||
private final LoadingCache<ZoneAndName, SecurityGroupInZone> securityGroupCache;
|
||||
private final NovaClient novaClient;
|
||||
private final Provider<TemplateBuilder> templateBuilderProvider;
|
||||
|
||||
@Inject
|
||||
protected ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet(
|
||||
|
@ -64,9 +76,13 @@ public class ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddT
|
|||
@Named("NAMING_CONVENTION") String nodeNamingConvention,
|
||||
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
|
||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
||||
AllocateAndAddFloatingIpToNode allocateAndAddFloatingIpToNode, NovaClient novaClient) {
|
||||
Provider<TemplateBuilder> templateBuilderProvider,
|
||||
AllocateAndAddFloatingIpToNode allocateAndAddFloatingIpToNode,
|
||||
LoadingCache<ZoneAndName, SecurityGroupInZone> securityGroupCache, NovaClient novaClient) {
|
||||
super(addNodeWithTagStrategy, listNodesStrategy, nodeNamingConvention, executor,
|
||||
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
|
||||
this.templateBuilderProvider = checkNotNull(templateBuilderProvider, "templateBuilderProvider");
|
||||
this.securityGroupCache = checkNotNull(securityGroupCache, "securityGroupCache");
|
||||
this.allocateAndAddFloatingIpToNode = checkNotNull(allocateAndAddFloatingIpToNode,
|
||||
"allocateAndAddFloatingIpToNode");
|
||||
this.novaClient = checkNotNull(novaClient, "novaClient");
|
||||
|
@ -75,23 +91,38 @@ public class ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddT
|
|||
@Override
|
||||
public Map<?, Future<Void>> execute(String group, int count, Template template, Set<NodeMetadata> goodNodes,
|
||||
Map<NodeMetadata, Exception> badNodes, Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
||||
// ensure we don't mutate the input template
|
||||
Template mutableTemplate = templateBuilderProvider.get().fromTemplate(template).build();
|
||||
|
||||
// TODO: make NovaTemplateOptions with the following:
|
||||
// security group, key pair
|
||||
NovaTemplateOptions templateOptions = NovaTemplateOptions.class.cast(template.getOptions());
|
||||
NovaTemplateOptions templateOptions = NovaTemplateOptions.class.cast(mutableTemplate.getOptions());
|
||||
|
||||
String zone = template.getLocation().getId();
|
||||
String zone = mutableTemplate.getLocation().getId();
|
||||
|
||||
if (templateOptions.shouldAutoAssignFloatingIp()) {
|
||||
checkArgument(novaClient.getFloatingIPExtensionForZone(zone).isPresent(),
|
||||
"Floating IPs are required by options, but the extension is not available! options: %s", templateOptions);
|
||||
"Floating IPs are required by options, but the extension is not available! options: %s",
|
||||
templateOptions);
|
||||
}
|
||||
|
||||
|
||||
boolean securityGroupExensionPresent = novaClient.getSecurityGroupExtensionForZone(zone).isPresent();
|
||||
List<Integer> inboundPorts = Ints.asList(templateOptions.getInboundPorts());
|
||||
if (templateOptions.getSecurityGroupNames().size() > 0) {
|
||||
checkArgument(novaClient.getSecurityGroupExtensionForZone(zone).isPresent(),
|
||||
"Security groups are required by options, but the extension is not available! options: %s", templateOptions);
|
||||
"Security groups are required by options, but the extension is not available! options: %s",
|
||||
templateOptions);
|
||||
} else if (securityGroupExensionPresent && inboundPorts.size() > 0) {
|
||||
String securityGroupName = "jclouds#" + group;
|
||||
try {
|
||||
securityGroupCache.get(new ZoneSecurityGroupNameAndPorts(zone, securityGroupName, inboundPorts));
|
||||
} catch (ExecutionException e) {
|
||||
throw Throwables.propagate(e.getCause());
|
||||
}
|
||||
templateOptions.securityGroupNames(securityGroupName);
|
||||
}
|
||||
|
||||
return super.execute(group, count, template, goodNodes, badNodes, customizationResponses);
|
||||
|
||||
return super.execute(group, count, mutableTemplate, goodNodes, badNodes, customizationResponses);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -27,20 +27,47 @@ import java.util.Set;
|
|||
import org.jclouds.openstack.domain.Link;
|
||||
import org.jclouds.openstack.domain.Resource;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* An image is a collection of files you use to create or rebuild a server.
|
||||
* Operators provide pre-built OS images by default. You may also create custom
|
||||
* images.
|
||||
* An image is a collection of files you use to create or rebuild a server. Operators provide
|
||||
* pre-built OS images by default. You may also create custom images.
|
||||
*
|
||||
* @author Jeremy Daggett
|
||||
* @see <a href=
|
||||
* "http://docs.openstack.org/api/openstack-compute/1.1/content/Images-d1e4427.html"
|
||||
* @see <a href= "http://docs.openstack.org/api/openstack-compute/1.1/content/Images-d1e4427.html"
|
||||
* />
|
||||
*/
|
||||
public class Image extends Resource {
|
||||
/**
|
||||
* In-flight images will have the status attribute set to SAVING and the conditional progress
|
||||
* element (0-100% completion) will also be returned. Other possible values for the status
|
||||
* attribute include: UNKNOWN, ACTIVE, SAVING, ERROR, and DELETED. Images with an ACTIVE status
|
||||
* are available for install. The optional minDisk and minRam attributes set the minimum disk and
|
||||
* RAM requirements needed to create a server with the image.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public static enum Status {
|
||||
|
||||
UNRECOGNIZED, UNKNOWN, ACTIVE, SAVING, ERROR, DELETED;
|
||||
|
||||
public String value() {
|
||||
return name();
|
||||
}
|
||||
|
||||
public static Status fromValue(String v) {
|
||||
try {
|
||||
return valueOf(v);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
@ -55,12 +82,12 @@ public class Image extends Resource {
|
|||
private Date created;
|
||||
private String tenantId;
|
||||
private String userId;
|
||||
private ImageStatus status;
|
||||
private Status status;
|
||||
private int progress;
|
||||
private int minDisk;
|
||||
private int minRam;
|
||||
private Resource server;
|
||||
private Map<String, String> metadata = Maps.newHashMap();
|
||||
private Map<String, String> metadata = Maps.newLinkedHashMap();
|
||||
|
||||
public Builder updated(Date updated) {
|
||||
this.updated = updated;
|
||||
|
@ -82,7 +109,7 @@ public class Image extends Resource {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder status(ImageStatus status) {
|
||||
public Builder status(Status status) {
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
@ -114,12 +141,12 @@ public class Image extends Resource {
|
|||
|
||||
public Image build() {
|
||||
return new Image(id, name, links, updated, created, tenantId, userId, status, progress, minDisk, minRam,
|
||||
server, metadata);
|
||||
server, metadata);
|
||||
}
|
||||
|
||||
public Builder fromImage(Image in) {
|
||||
return fromResource(in).status(in.getStatus()).updated(in.getUpdated()).created(in.getCreated())
|
||||
.progress(in.getProgress()).server(in.getServer()).metadata(in.getMetadata());
|
||||
return fromResource(in).status(in.getStatus()).updated(in.getUpdated()).created(in.getCreated()).progress(
|
||||
in.getProgress()).server(in.getServer()).metadata(in.getMetadata());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -155,21 +182,21 @@ public class Image extends Resource {
|
|||
}
|
||||
}
|
||||
|
||||
private Date updated;
|
||||
private Date created;
|
||||
private final Date updated;
|
||||
private final Date created;
|
||||
@SerializedName("tenant_id")
|
||||
private String tenantId;
|
||||
private final String tenantId;
|
||||
@SerializedName("user_id")
|
||||
private String userId;
|
||||
private ImageStatus status;
|
||||
private int progress;
|
||||
private int minDisk;
|
||||
private int minRam;
|
||||
private Resource server;
|
||||
private Map<String, String> metadata = Maps.newHashMap();
|
||||
private final String userId;
|
||||
private final Status status;
|
||||
private final int progress;
|
||||
private final int minDisk;
|
||||
private final int minRam;
|
||||
private final Resource server;
|
||||
private final Map<String, String> metadata;
|
||||
|
||||
protected Image(String id, String name, Set<Link> links, Date updated, Date created, String tenantId, String userId,
|
||||
ImageStatus status, int progress, int minDisk, int minRam, Resource server, Map<String, String> metadata) {
|
||||
Status status, int progress, int minDisk, int minRam, Resource server, Map<String, String> metadata) {
|
||||
super(id, name, links);
|
||||
this.updated = updated;
|
||||
this.created = created;
|
||||
|
@ -180,7 +207,7 @@ public class Image extends Resource {
|
|||
this.minDisk = minDisk;
|
||||
this.minRam = minRam;
|
||||
this.server = server;
|
||||
this.metadata = metadata;
|
||||
this.metadata = ImmutableMap.<String, String> copyOf(metadata);
|
||||
}
|
||||
|
||||
public Date getUpdated() {
|
||||
|
@ -199,7 +226,7 @@ public class Image extends Resource {
|
|||
return this.userId;
|
||||
}
|
||||
|
||||
public ImageStatus getStatus() {
|
||||
public Status getStatus() {
|
||||
return this.status;
|
||||
}
|
||||
|
||||
|
@ -220,15 +247,16 @@ public class Image extends Resource {
|
|||
}
|
||||
|
||||
public Map<String, String> getMetadata() {
|
||||
return this.metadata;
|
||||
// in case this was assigned in gson
|
||||
return ImmutableMap.copyOf(Maps.filterValues(this.metadata, Predicates.notNull()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringHelper("").add("id", id).add("name", name).add("links", links).add("updated", updated)
|
||||
.add("created", created).add("tenantId", tenantId).add("userId", userId).add("status", status)
|
||||
.add("progress", progress).add("minDisk", minDisk).add("minRam", minRam).add("server", server)
|
||||
.add("metadata", metadata).toString();
|
||||
return toStringHelper("").add("id", id).add("name", name).add("links", links).add("updated", updated).add(
|
||||
"created", created).add("tenantId", tenantId).add("userId", userId).add("status", status).add(
|
||||
"progress", progress).add("minDisk", minDisk).add("minRam", minRam).add("server", server).add(
|
||||
"metadata", metadata).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,22 +26,19 @@ import java.util.Date;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jclouds.compute.domain.NodeState;
|
||||
import org.jclouds.javax.annotation.Nullable;
|
||||
import org.jclouds.openstack.domain.Link;
|
||||
import org.jclouds.openstack.domain.Resource;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Address.Type;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairClient;
|
||||
import org.jclouds.util.InetAddresses2;
|
||||
import org.jclouds.util.Multimaps2;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSetMultimap;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.LinkedHashMultimap;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
|
@ -57,6 +54,47 @@ import com.google.gson.annotations.SerializedName;
|
|||
* />
|
||||
*/
|
||||
public class Server extends Resource {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* Other possible values for the status attribute include: BUILD, REBUILD, SUSPENDED, RESIZE,
|
||||
* VERIFY_RESIZE, REVERT_RESIZE, PASSWORD, REBOOT, HARD_REBOOT, DELETED, UNKNOWN, and ERROR.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public static enum Status {
|
||||
|
||||
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;
|
||||
|
||||
Status(NodeState nodeState) {
|
||||
this.nodeState = nodeState;
|
||||
}
|
||||
|
||||
public String value() {
|
||||
return name();
|
||||
}
|
||||
|
||||
public static Status fromValue(String v) {
|
||||
try {
|
||||
return valueOf(v.replaceAll("\\(.*", ""));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
|
||||
public NodeState getNodeState() {
|
||||
return nodeState;
|
||||
}
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
@ -74,7 +112,7 @@ public class Server extends Resource {
|
|||
private String hostId;
|
||||
private String accessIPv4;
|
||||
private String accessIPv6;
|
||||
private ServerStatus status;
|
||||
private Status status;
|
||||
private String configDrive;
|
||||
private Resource image;
|
||||
private Resource flavor;
|
||||
|
@ -151,7 +189,7 @@ public class Server extends Resource {
|
|||
/**
|
||||
* @see Server#getStatus()
|
||||
*/
|
||||
public Builder status(ServerStatus status) {
|
||||
public Builder status(Status status) {
|
||||
this.status = status;
|
||||
return this;
|
||||
}
|
||||
|
@ -309,7 +347,7 @@ public class Server extends Resource {
|
|||
protected final String hostId;
|
||||
protected final String accessIPv4;
|
||||
protected final String accessIPv6;
|
||||
protected final ServerStatus status;
|
||||
protected final Status status;
|
||||
protected final Resource image;
|
||||
protected final Resource flavor;
|
||||
protected final String adminPass;
|
||||
|
@ -323,8 +361,8 @@ public class Server extends Resource {
|
|||
|
||||
protected Server(String id, String name, Set<Link> links, @Nullable String uuid, String tenantId, String userId,
|
||||
Date updated, Date created, @Nullable String hostId, @Nullable String accessIPv4,
|
||||
@Nullable String accessIPv6, ServerStatus status, @Nullable String configDrive, Resource image,
|
||||
Resource flavor, String adminPass, @Nullable String keyName, Multimap<Address.Type, Address> addresses,
|
||||
@Nullable String accessIPv6, Status status, @Nullable String configDrive, Resource image, Resource flavor,
|
||||
String adminPass, @Nullable String keyName, Multimap<Address.Type, Address> addresses,
|
||||
Map<String, String> metadata) {
|
||||
super(id, name, links);
|
||||
this.uuid = uuid; // TODO: see what version this came up in
|
||||
|
@ -390,7 +428,7 @@ public class Server extends Resource {
|
|||
return Strings.emptyToNull(this.accessIPv6);
|
||||
}
|
||||
|
||||
public ServerStatus getStatus() {
|
||||
public Status getStatus() {
|
||||
return this.status;
|
||||
}
|
||||
|
||||
|
@ -408,7 +446,8 @@ public class Server extends Resource {
|
|||
}
|
||||
|
||||
public Map<String, String> getMetadata() {
|
||||
return this.metadata;
|
||||
// in case this was assigned in gson
|
||||
return ImmutableMap.copyOf(Maps.filterValues(this.metadata, Predicates.notNull()));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -439,29 +478,7 @@ public class Server extends Resource {
|
|||
* @return the ip addresses assigned to the server
|
||||
*/
|
||||
public Multimap<Type, Address> getAddresses() {
|
||||
ImmutableSetMultimap.Builder<Type, Address> returnMapBuilder = new ImmutableSetMultimap.Builder<Type, Address>();
|
||||
|
||||
Set<Address> publicAddresses = addresses.get(Address.Type.PUBLIC);
|
||||
Set<Address> privateAddresses = addresses.get(Address.Type.PRIVATE);
|
||||
if (publicAddresses != null) {
|
||||
returnMapBuilder.putAll(Address.Type.PUBLIC, Iterables.filter(publicAddresses, Predicates
|
||||
.not(IsPrivateAddress.INSTANCE)));
|
||||
}
|
||||
if (privateAddresses != null) {
|
||||
returnMapBuilder.putAll(Address.Type.PRIVATE, Iterables.filter(privateAddresses, IsPrivateAddress.INSTANCE));
|
||||
returnMapBuilder.putAll(Address.Type.PUBLIC, Iterables.filter(privateAddresses, Predicates
|
||||
.not(IsPrivateAddress.INSTANCE)));
|
||||
}
|
||||
ImmutableSetMultimap<Type, Address> returnMap = returnMapBuilder.build();
|
||||
|
||||
return returnMap.size() > 0 ? returnMap : Multimaps2.fromOldSchool(addresses);
|
||||
}
|
||||
|
||||
private static enum IsPrivateAddress implements Predicate<Address> {
|
||||
INSTANCE;
|
||||
public boolean apply(Address in) {
|
||||
return InetAddresses2.IsPrivateIPAddress.INSTANCE.apply(in.getAddr());
|
||||
}
|
||||
return Multimaps2.fromOldSchool(addresses);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
/**
|
||||
* 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.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.
|
||||
*
|
||||
* Other possible values for the status attribute include: BUILD, REBUILD,
|
||||
* SUSPENDED, RESIZE, VERIFY_RESIZE, REVERT_RESIZE, PASSWORD, REBOOT,
|
||||
* HARD_REBOOT, DELETED, UNKNOWN, and ERROR.
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public enum ServerStatus {
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
public static ServerStatus fromValue(String v) {
|
||||
try {
|
||||
return valueOf(v.replaceAll("\\(.*",""));
|
||||
} catch (IllegalArgumentException e) {
|
||||
return UNRECOGNIZED;
|
||||
}
|
||||
}
|
||||
|
||||
public NodeState getNodeState() {
|
||||
return nodeState;
|
||||
}
|
||||
}
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.compute.domain;
|
||||
package org.jclouds.openstack.nova.v1_1.domain.zonescoped;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.compute.domain;
|
||||
package org.jclouds.openstack.nova.v1_1.domain.zonescoped;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
|
@ -26,15 +26,15 @@ import org.jclouds.openstack.nova.v1_1.domain.Image;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class ImageInZone extends ZoneAndId {
|
||||
protected final Image server;
|
||||
protected final Image image;
|
||||
|
||||
public ImageInZone(Image server, String zoneId) {
|
||||
super(zoneId, checkNotNull(server, "server").getId());
|
||||
this.server = server;
|
||||
public ImageInZone(Image image, String zoneId) {
|
||||
super(zoneId, checkNotNull(image, "image").getId());
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public Image getImage() {
|
||||
return server;
|
||||
return image;
|
||||
}
|
||||
|
||||
// superclass hashCode/equals are good enough, and help us use ZoneAndId and ImageInZone
|
||||
|
@ -42,7 +42,7 @@ public class ImageInZone extends ZoneAndId {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[server=" + server + ", zoneId=" + zoneId + "]";
|
||||
return "[image=" + image + ", zoneId=" + zoneId + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.compute.domain;
|
||||
package org.jclouds.openstack.nova.v1_1.domain.zonescoped;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.compute.domain;
|
||||
package org.jclouds.openstack.nova.v1_1.domain.zonescoped;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.compute.domain;
|
||||
package org.jclouds.openstack.nova.v1_1.domain.zonescoped;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
|
@ -16,12 +16,13 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.compute.domain;
|
||||
package org.jclouds.openstack.nova.v1_1.domain.zonescoped;
|
||||
|
||||
import static com.google.common.base.Objects.equal;
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.base.Objects.ToStringHelper;
|
||||
|
@ -33,6 +34,25 @@ import com.google.common.collect.Iterables;
|
|||
* @author Adrian Cole
|
||||
*/
|
||||
public class ZoneAndName {
|
||||
|
||||
public final static Function<ZoneAndName, String> NAME_FUNCTION = new Function<ZoneAndName, String>(){
|
||||
|
||||
@Override
|
||||
public String apply(ZoneAndName input) {
|
||||
return input.getName();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public final static Function<ZoneAndName, String> ZONE_FUNCTION = new Function<ZoneAndName, String>(){
|
||||
|
||||
@Override
|
||||
public String apply(ZoneAndName input) {
|
||||
return input.getZone();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
public static ZoneAndName fromSlashEncoded(String name) {
|
||||
Iterable<String> parts = Splitter.on('/').split(checkNotNull(name, "name"));
|
||||
checkArgument(Iterables.size(parts) == 2, "name must be in format zoneId/name");
|
|
@ -16,29 +16,29 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.compute.domain;
|
||||
package org.jclouds.openstack.nova.v1_1.domain.zonescoped;
|
||||
|
||||
import static com.google.common.base.Objects.equal;
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.base.Objects.ToStringHelper;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
public class ZoneSecurityGroupNameAndPorts extends ZoneAndName {
|
||||
protected final List<Integer> ports;
|
||||
protected final Set<Integer> ports;
|
||||
|
||||
public ZoneSecurityGroupNameAndPorts(String zoneId, String name, List<Integer> ports) {
|
||||
public ZoneSecurityGroupNameAndPorts(String zoneId, String name, Iterable<Integer> ports) {
|
||||
super(zoneId, name);
|
||||
this.ports = ImmutableList.<Integer> copyOf(checkNotNull(ports, "ports"));
|
||||
this.ports = ImmutableSet.<Integer> copyOf(checkNotNull(ports, "ports"));
|
||||
}
|
||||
|
||||
public List<Integer> getPorts() {
|
||||
public Set<Integer> getPorts() {
|
||||
return ports;
|
||||
}
|
||||
|
|
@ -55,6 +55,8 @@ public class NovaErrorHandler implements HttpErrorHandler {
|
|||
exception = new InsufficientResourcesException(message, exception);
|
||||
else if (message.indexOf("has no fixed_ips") != -1)
|
||||
exception = new IllegalStateException(message, exception);
|
||||
else if (message.indexOf("already exists") != -1)
|
||||
exception = new IllegalStateException(message, exception);
|
||||
break;
|
||||
case 401:
|
||||
case 403:
|
||||
|
|
|
@ -29,9 +29,9 @@ import javax.inject.Singleton;
|
|||
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneAndName;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.SecurityGroup;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndName;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClient;
|
||||
import org.jclouds.rest.ResourceNotFoundException;
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
||||
* contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. jclouds licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.jclouds.openstack.nova.v1_1.predicates;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Image;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Image.Status;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
/**
|
||||
* Predicates handy when working with Images
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
||||
public class ImagePredicates {
|
||||
|
||||
/**
|
||||
* matches status of the given image
|
||||
*
|
||||
* @param status
|
||||
* @return predicate that matches status
|
||||
*/
|
||||
public static Predicate<Image> statusEquals(final Status status) {
|
||||
checkNotNull(status, "status must be defined");
|
||||
|
||||
return new Predicate<Image>() {
|
||||
@Override
|
||||
public boolean apply(Image image) {
|
||||
return status.equals(image.getStatus());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "statusEquals(" + status + ")";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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.predicates;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.domain.SecurityGroup;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
|
||||
/**
|
||||
* Predicates handy when working with SecurityGroups
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
|
||||
public class SecurityGroupPredicates {
|
||||
|
||||
/**
|
||||
* matches name of the given extension
|
||||
*
|
||||
* @param name
|
||||
* @return predicate that matches name
|
||||
*/
|
||||
public static Predicate<SecurityGroup> nameEquals(final String name) {
|
||||
checkNotNull(name, "name must be defined");
|
||||
|
||||
return new Predicate<SecurityGroup>() {
|
||||
@Override
|
||||
public boolean apply(SecurityGroup ext) {
|
||||
return name.equals(ext.getName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "nameEquals(" + name + ")";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -65,6 +65,17 @@ public class NovaErrorHandlerTest {
|
|||
IllegalStateException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test400MakesIllegalStateExceptionOnAlreadyExists() {
|
||||
assertCodeMakes(
|
||||
"POST",
|
||||
URI.create("https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/37936628937291/servers"),
|
||||
400,
|
||||
"HTTP/1.1 400 Bad Request",
|
||||
"{\"badRequest\": {\"message\": \"Server with the name 'test' already exists\", \"code\": 400}}",
|
||||
IllegalStateException.class);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test400MakesInsufficientResourcesExceptionOnQuotaExceeded() {
|
||||
|
|
|
@ -29,8 +29,8 @@ import org.jclouds.compute.domain.Template;
|
|||
import org.jclouds.compute.domain.TemplateBuilder;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ServerInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.options.NovaTemplateOptions;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ServerInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaComputeServiceContextExpectTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ import com.google.common.collect.ImmutableSet;
|
|||
* @author Matt Stephenson
|
||||
*/
|
||||
@Test(groups = "unit", testName = "AllocateAndAddFloatingIpToNodeTest")
|
||||
public class AllocateAndAddFloatingIpToNodeTest extends BaseNovaComputeServiceExpectTest {
|
||||
public class AllocateAndAddFloatingIpToNodeExpectTest extends BaseNovaComputeServiceExpectTest {
|
||||
final Location provider = new LocationBuilder().scope(LocationScope.PROVIDER).id("openstack-nova").description(
|
||||
"openstack-nova").build();
|
||||
final Location zone = new LocationBuilder().id("az-1.region-a.geo-1").description("az-1.region-a.geo-1").scope(
|
|
@ -29,8 +29,8 @@ import org.jclouds.compute.domain.Hardware;
|
|||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.FlavorInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Flavor;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.FlavorInZone;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
|
|
|
@ -30,8 +30,8 @@ import org.jclouds.compute.domain.OsFamily;
|
|||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ImageInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Image;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ImageInZone;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
/**
|
||||
* 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 static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.easymock.classextension.EasyMock;
|
||||
import org.jclouds.compute.domain.Hardware;
|
||||
import org.jclouds.compute.domain.Image;
|
||||
import org.jclouds.compute.domain.NodeMetadata;
|
||||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ServerInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndId;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndName;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseCreatedServerTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseServerTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(testName = "OrphanedGroupsByZoneIdTest")
|
||||
public class OrphanedGroupsByZoneIdTest {
|
||||
|
||||
Location provider = new LocationBuilder().scope(LocationScope.PROVIDER).id("openstack-nova").description(
|
||||
"openstack-nova").build();
|
||||
Location zone = new LocationBuilder().id("az-1.region-a.geo-1").description("az-1.region-a.geo-1").scope(
|
||||
LocationScope.ZONE).parent(provider).build();
|
||||
Supplier<Map<String, Location>> locationIndex = Suppliers.<Map<String, Location>> ofInstance(ImmutableMap
|
||||
.<String, Location> of("az-1.region-a.geo-1", zone));
|
||||
|
||||
@Test
|
||||
public void testWhenComputeServiceSaysAllNodesAreDeadBothGroupsAreReturned() {
|
||||
|
||||
ServerInZone withoutHost = new ServerInZone(new ParseCreatedServerTest().expected(), "az-1.region-a.geo-1");
|
||||
ServerInZone withHost = new ServerInZone(new ParseServerTest().expected(), "az-1.region-a.geo-1");
|
||||
|
||||
LoadingCache<ZoneAndId, Iterable<String>> mockLoadingCache = EasyMock.createMock(LoadingCache.class);
|
||||
EasyMock.expect(mockLoadingCache.getUnchecked(withoutHost)).andReturn(ImmutableSet.<String> of());
|
||||
EasyMock.expect(mockLoadingCache.getUnchecked(withHost)).andReturn(ImmutableSet.<String> of());
|
||||
EasyMock.replay(mockLoadingCache);
|
||||
|
||||
ServerInZoneToNodeMetadata converter = new ServerInZoneToNodeMetadata(locationIndex, Suppliers
|
||||
.<Set<? extends Image>> ofInstance(ImmutableSet.<Image> of()), Suppliers
|
||||
.<Set<? extends Hardware>> ofInstance(ImmutableSet.<Hardware> of()), mockLoadingCache);
|
||||
|
||||
Set<? extends NodeMetadata> set = ImmutableSet.of(converter.apply(withHost), converter.apply(withoutHost));
|
||||
|
||||
assertEquals(new OrphanedGroupsByZoneId(Predicates.<ZoneAndName> alwaysTrue()).apply(set), ImmutableMultimap
|
||||
.<String, String> builder().putAll("az-1.region-a.geo-1", "sample", "test").build());
|
||||
|
||||
EasyMock.verify(mockLoadingCache);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWhenComputeServiceSaysAllNodesAreDeadNoGroupsAreReturned() {
|
||||
|
||||
ServerInZone withoutHost = new ServerInZone(new ParseCreatedServerTest().expected(), "az-1.region-a.geo-1");
|
||||
ServerInZone withHost = new ServerInZone(new ParseServerTest().expected(), "az-1.region-a.geo-1");
|
||||
|
||||
LoadingCache<ZoneAndId, Iterable<String>> mockLoadingCache = EasyMock.createMock(LoadingCache.class);
|
||||
EasyMock.expect(mockLoadingCache.getUnchecked(withoutHost)).andReturn(ImmutableSet.<String> of());
|
||||
EasyMock.expect(mockLoadingCache.getUnchecked(withHost)).andReturn(ImmutableSet.<String> of());
|
||||
EasyMock.replay(mockLoadingCache);
|
||||
|
||||
ServerInZoneToNodeMetadata converter = new ServerInZoneToNodeMetadata(locationIndex, Suppliers
|
||||
.<Set<? extends Image>> ofInstance(ImmutableSet.<Image> of()), Suppliers
|
||||
.<Set<? extends Hardware>> ofInstance(ImmutableSet.<Hardware> of()), mockLoadingCache);
|
||||
|
||||
Set<? extends NodeMetadata> set = ImmutableSet.of(converter.apply(withHost), converter.apply(withoutHost));
|
||||
|
||||
assertEquals(new OrphanedGroupsByZoneId(Predicates.<ZoneAndName> alwaysFalse()).apply(set), ImmutableMultimap
|
||||
.<String, String> of());
|
||||
|
||||
EasyMock.verify(mockLoadingCache);
|
||||
}
|
||||
}
|
|
@ -35,9 +35,9 @@ import org.jclouds.compute.domain.OsFamily;
|
|||
import org.jclouds.domain.Location;
|
||||
import org.jclouds.domain.LocationBuilder;
|
||||
import org.jclouds.domain.LocationScope;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ServerInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneAndId;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ServerInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndId;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseCreatedServerTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseServerTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -134,8 +134,8 @@ public class ServerInZoneToNodeMetadataTest {
|
|||
assertEquals(convertedNodeMetadata.getPrivateAddresses(), ImmutableSet.of("10.176.42.16"));
|
||||
|
||||
assertNotNull(convertedNodeMetadata.getPublicAddresses());
|
||||
assertEquals(convertedNodeMetadata.getPublicAddresses(), ImmutableSet.of("67.23.10.132", "::babe:67.23.10.132",
|
||||
"67.23.10.131", "::babe:4317:0A83", "::babe:10.176.42.16"));
|
||||
// note jclouds doesn't yet support ipv6 b/c not tested yet
|
||||
assertEquals(convertedNodeMetadata.getPublicAddresses(), ImmutableSet.of("67.23.10.132", "67.23.10.131"));
|
||||
|
||||
assertNotNull(convertedNodeMetadata.getUserMetadata());
|
||||
assertEquals(convertedNodeMetadata.getUserMetadata(), ImmutableMap.<String, String> of("Server Label",
|
||||
|
|
|
@ -0,0 +1,145 @@
|
|||
/**
|
||||
* 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.loaders;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.testng.Assert.assertEquals;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndName;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
/**
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", singleThreaded = true, testName = "FindSecurityGroupOrCreateTest")
|
||||
public class FindSecurityGroupOrCreateTest {
|
||||
|
||||
@Test
|
||||
public void testWhenNotFoundCreatesANewSecurityGroup() throws Exception {
|
||||
Predicate<AtomicReference<ZoneAndName>> returnSecurityGroupExistsInZone = Predicates.alwaysFalse();
|
||||
|
||||
SecurityGroupInZone securityGroupInZone = createMock(SecurityGroupInZone.class);
|
||||
|
||||
ZoneSecurityGroupNameAndPorts input = new ZoneSecurityGroupNameAndPorts("zone", "groupName", ImmutableSet
|
||||
.<Integer> of(22, 8080));
|
||||
|
||||
Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> groupCreator = Functions.forMap(ImmutableMap
|
||||
.<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> of(input, securityGroupInZone));
|
||||
|
||||
FindSecurityGroupOrCreate parser = new FindSecurityGroupOrCreate(
|
||||
returnSecurityGroupExistsInZone, groupCreator);
|
||||
|
||||
assertEquals(parser.load(input), securityGroupInZone);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWhenFoundReturnsSecurityGroupFromAtomicReferenceValueUpdatedDuringPredicateCheck() throws Exception {
|
||||
final SecurityGroupInZone securityGroupInZone = createMock(SecurityGroupInZone.class);
|
||||
|
||||
Predicate<AtomicReference<ZoneAndName>> returnSecurityGroupExistsInZone = new Predicate<AtomicReference<ZoneAndName>>(){
|
||||
|
||||
@Override
|
||||
public boolean apply(AtomicReference<ZoneAndName> input) {
|
||||
input.set(securityGroupInZone);
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
ZoneAndName input = ZoneAndName.fromZoneAndName("zone", "groupName");
|
||||
|
||||
Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> groupCreator = new Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone>() {
|
||||
|
||||
@Override
|
||||
public SecurityGroupInZone apply(ZoneSecurityGroupNameAndPorts input) {
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
FindSecurityGroupOrCreate parser = new FindSecurityGroupOrCreate(
|
||||
returnSecurityGroupExistsInZone, groupCreator);
|
||||
|
||||
assertEquals(parser.load(input), securityGroupInZone);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test(expectedExceptions = IllegalStateException.class)
|
||||
public void testWhenFoundPredicateMustUpdateAtomicReference() throws Exception {
|
||||
|
||||
Predicate<AtomicReference<ZoneAndName>> returnSecurityGroupExistsInZone = Predicates.alwaysTrue();
|
||||
|
||||
ZoneAndName input = ZoneAndName.fromZoneAndName("zone", "groupName");
|
||||
|
||||
Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> groupCreator = new Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone>() {
|
||||
|
||||
@Override
|
||||
public SecurityGroupInZone apply(ZoneSecurityGroupNameAndPorts input) {
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
FindSecurityGroupOrCreate parser = new FindSecurityGroupOrCreate(
|
||||
returnSecurityGroupExistsInZone, groupCreator);
|
||||
|
||||
parser.load(input);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test(expectedExceptions = IllegalStateException.class)
|
||||
public void testWhenNotFoundInputMustBeZoneSecurityGroupNameAndPorts() throws Exception {
|
||||
Predicate<AtomicReference<ZoneAndName>> returnSecurityGroupExistsInZone = Predicates.alwaysFalse();
|
||||
|
||||
ZoneAndName input = ZoneAndName.fromZoneAndName("zone", "groupName");
|
||||
|
||||
Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> groupCreator = new Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone>() {
|
||||
|
||||
@Override
|
||||
public SecurityGroupInZone apply(ZoneSecurityGroupNameAndPorts input) {
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
FindSecurityGroupOrCreate parser = new FindSecurityGroupOrCreate(
|
||||
returnSecurityGroupExistsInZone, groupCreator);
|
||||
|
||||
parser.load(input);
|
||||
|
||||
}
|
||||
}
|
|
@ -26,8 +26,8 @@ import static org.testng.Assert.assertEquals;
|
|||
import static org.testng.AssertJUnit.assertFalse;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneAndId;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.FloatingIP;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndId;
|
||||
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ import java.util.Set;
|
|||
import org.jclouds.openstack.nova.v1_1.domain.Address;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.FloatingIP;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.ServerStatus;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Server.Status;
|
||||
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;
|
||||
|
@ -136,7 +136,7 @@ public class FloatingIPClientLiveTest extends BaseNovaClientLiveTest {
|
|||
|
||||
private void blockUntilServerActive(String serverId, ServerClient client) throws InterruptedException {
|
||||
Server currentDetails = null;
|
||||
for (currentDetails = client.getServer(serverId); currentDetails.getStatus() != ServerStatus.ACTIVE; currentDetails = client
|
||||
for (currentDetails = client.getServer(serverId); currentDetails.getStatus() != Status.ACTIVE; currentDetails = client
|
||||
.getServer(serverId)) {
|
||||
System.out.printf("blocking on status active%n%s%n", currentDetails);
|
||||
Thread.sleep(5 * 1000);
|
||||
|
|
|
@ -25,9 +25,9 @@ import java.net.URI;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneSecurityGroupNameAndPorts;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.CreateSecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.functions.CreateSecurityGroupIfNeeded;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneSecurityGroupNameAndPorts;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseComputeServiceTypicalSecurityGroupTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
@ -35,32 +35,32 @@ import org.testng.annotations.Test;
|
|||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableMultimap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableMap.Builder;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "CreateSecurityGroupInZoneExpectTest")
|
||||
public class CreateSecurityGroupInZoneExpectTest extends BaseNovaClientExpectTest {
|
||||
@Test(groups = "unit", testName = "CreateSecurityGroupIfNeededTest")
|
||||
public class CreateSecurityGroupIfNeededTest extends BaseNovaClientExpectTest {
|
||||
HttpRequest createSecurityGroup = HttpRequest.builder().method("POST").endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/os-security-groups")).headers(
|
||||
ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
|
||||
authToken).build())
|
||||
.payload(
|
||||
payloadFromStringWithContentType(
|
||||
"{\"security_group\":{\"name\":\"jclouds#mygroup\",\"description\":\"jclouds#mygroup\"}}",
|
||||
"application/json")).build();
|
||||
|
||||
public void testUpdateReferenceWhenSecurityGroupListContainsGroupName() throws Exception {
|
||||
public void testCreateNewGroup() throws Exception {
|
||||
|
||||
Builder<HttpRequest, HttpResponse> builder = ImmutableMap.<HttpRequest, HttpResponse>builder();
|
||||
|
||||
builder.put(keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess);
|
||||
builder.put(extensionsOfNovaRequest, extensionsOfNovaResponse);
|
||||
|
||||
HttpRequest createSecurityGroup = HttpRequest.builder().method("POST").endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/os-security-groups")).headers(
|
||||
ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
|
||||
authToken).build())
|
||||
.payload(
|
||||
payloadFromStringWithContentType(
|
||||
"{\"security_group\":{\"name\":\"jclouds#mygroup\",\"description\":\"jclouds#mygroup\"}}",
|
||||
"application/json")).build();
|
||||
int groupId = 2769;
|
||||
|
||||
|
||||
HttpResponse createSecurityGroupResponse = HttpResponse.builder().statusCode(200)
|
||||
.payload(
|
||||
payloadFromStringWithContentType(
|
||||
|
@ -68,7 +68,7 @@ public class CreateSecurityGroupInZoneExpectTest extends BaseNovaClientExpectTes
|
|||
"application/json; charset=UTF-8")).build();
|
||||
|
||||
builder.put(createSecurityGroup, createSecurityGroupResponse);
|
||||
|
||||
|
||||
int ruleId = 10331;
|
||||
|
||||
for (int port : ImmutableList.of(22,8080)){
|
||||
|
@ -110,25 +110,61 @@ public class CreateSecurityGroupInZoneExpectTest extends BaseNovaClientExpectTes
|
|||
}
|
||||
|
||||
HttpRequest getSecurityGroup = HttpRequest.builder().method("GET").endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/os-security-groups/"+groupId)).headers(
|
||||
URI.create("https://compute.north.host/v1.1/3456/os-security-groups/" + groupId)).headers(
|
||||
ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
|
||||
authToken).build()).build();
|
||||
|
||||
HttpResponse getSecurityGroupResponse = HttpResponse.builder().statusCode(200).payload(
|
||||
payloadFromResource("/securitygroup_details_computeservice_typical.json")).build();
|
||||
|
||||
|
||||
builder.put(getSecurityGroup, getSecurityGroupResponse);
|
||||
|
||||
NovaClient clientWhenSecurityGroupsExist = requestsSendResponses(builder.build());
|
||||
NovaClient clientCanCreateSecurityGroup = requestsSendResponses(builder.build());
|
||||
|
||||
CreateSecurityGroupInZone fn = new CreateSecurityGroupInZone(clientWhenSecurityGroupsExist);
|
||||
CreateSecurityGroupIfNeeded fn = new CreateSecurityGroupIfNeeded(clientCanCreateSecurityGroup);
|
||||
|
||||
// we can find it
|
||||
assertEquals(fn.apply(
|
||||
new ZoneSecurityGroupNameAndPorts("az-1.region-a.geo-1", "jclouds#mygroup", ImmutableList.of(22, 8080)))
|
||||
new ZoneSecurityGroupNameAndPorts("az-1.region-a.geo-1", "jclouds#mygroup", ImmutableSet.of(22, 8080)))
|
||||
.toString(), new SecurityGroupInZone(new ParseComputeServiceTypicalSecurityGroupTest().expected(),
|
||||
"az-1.region-a.geo-1").toString());
|
||||
|
||||
}
|
||||
|
||||
public void testReturnExistingGroupOnAlreadyExists() throws Exception {
|
||||
|
||||
Builder<HttpRequest, HttpResponse> builder = ImmutableMap.<HttpRequest, HttpResponse>builder();
|
||||
|
||||
builder.put(keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess);
|
||||
builder.put(extensionsOfNovaRequest, extensionsOfNovaResponse);
|
||||
|
||||
HttpResponse createSecurityGroupResponse = HttpResponse.builder().statusCode(400)
|
||||
.payload(
|
||||
payloadFromStringWithContentType(
|
||||
"{\"badRequest\": {\"message\": \"Security group test already exists\", \"code\": 400}}",
|
||||
"application/json; charset=UTF-8")).build();
|
||||
|
||||
builder.put(createSecurityGroup, createSecurityGroupResponse);
|
||||
|
||||
HttpRequest listSecurityGroups = HttpRequest.builder().method("GET").endpoint(
|
||||
URI.create("https://compute.north.host/v1.1/3456/os-security-groups")).headers(
|
||||
ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
|
||||
authToken).build()).build();
|
||||
|
||||
HttpResponse listSecurityGroupsResponse = HttpResponse.builder().statusCode(200).payload(
|
||||
payloadFromResource("/securitygroup_list_details_computeservice_typical.json")).build();
|
||||
|
||||
builder.put(listSecurityGroups, listSecurityGroupsResponse);
|
||||
|
||||
NovaClient clientWhenSecurityGroupsExist = requestsSendResponses(builder.build());
|
||||
|
||||
CreateSecurityGroupIfNeeded fn = new CreateSecurityGroupIfNeeded(clientWhenSecurityGroupsExist);
|
||||
|
||||
// we can find it
|
||||
assertEquals(fn.apply(
|
||||
new ZoneSecurityGroupNameAndPorts("az-1.region-a.geo-1", "jclouds#mygroup", ImmutableSet.of(22, 8080)))
|
||||
.toString(), new SecurityGroupInZone(new ParseComputeServiceTypicalSecurityGroupTest().expected(),
|
||||
"az-1.region-a.geo-1").toString());
|
||||
|
||||
}
|
||||
}
|
|
@ -28,8 +28,8 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpResponse;
|
||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneAndName;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.SecurityGroupInZone;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndName;
|
||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaClientExpectTest;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseSecurityGroupListTest;
|
||||
import org.jclouds.openstack.nova.v1_1.predicates.FindSecurityGroupWithNameAndReturnTrue;
|
||||
|
|
|
@ -31,7 +31,7 @@ import org.jclouds.openstack.domain.Resource;
|
|||
import org.jclouds.openstack.domain.Link.Relation;
|
||||
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.ServerStatus;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Server.Status;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -62,7 +62,7 @@ public class ParseCreatedServerTest extends BaseItemParserTest<Server> {
|
|||
.name("test-e92")
|
||||
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-03-19T06:21:13Z"))
|
||||
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-03-19T06:21:13Z"))
|
||||
.status(ServerStatus.BUILD)
|
||||
.status(Status.BUILD)
|
||||
.adminPass("ZWuHcmTMQ7eXoHeM")
|
||||
.image(
|
||||
Resource
|
||||
|
|
|
@ -27,11 +27,11 @@ import org.jclouds.date.internal.SimpleDateFormatDateService;
|
|||
import org.jclouds.json.BaseItemParserTest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.openstack.domain.Link;
|
||||
import org.jclouds.openstack.domain.Link.Relation;
|
||||
import org.jclouds.openstack.domain.Resource;
|
||||
import org.jclouds.openstack.domain.Link.Relation;
|
||||
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Image;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.ImageStatus;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Image.Status;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -63,7 +63,7 @@ public class ParseImageTest extends BaseItemParserTest<Image> {
|
|||
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2010-08-10T12:00:00Z"))
|
||||
.tenantId("12345")
|
||||
.userId("joe")
|
||||
.status(ImageStatus.SAVING)
|
||||
.status(Status.SAVING)
|
||||
.progress(80)
|
||||
.minDisk(5)
|
||||
.minRam(256)
|
||||
|
|
|
@ -27,12 +27,12 @@ import org.jclouds.date.internal.SimpleDateFormatDateService;
|
|||
import org.jclouds.json.BaseItemParserTest;
|
||||
import org.jclouds.json.config.GsonModule;
|
||||
import org.jclouds.openstack.domain.Link;
|
||||
import org.jclouds.openstack.domain.Link.Relation;
|
||||
import org.jclouds.openstack.domain.Resource;
|
||||
import org.jclouds.openstack.domain.Link.Relation;
|
||||
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Address;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.ServerStatus;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Server.Status;
|
||||
import org.jclouds.rest.annotations.SelectJson;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
@ -66,7 +66,7 @@ public class ParseServerTest extends BaseItemParserTest<Server> {
|
|||
.hostId("e4d909c290d0fb1ca068ffaddf22cbd0")
|
||||
.accessIPv4("67.23.10.132")
|
||||
.accessIPv6("::babe:67.23.10.132")
|
||||
.status(ServerStatus.BUILD)
|
||||
.status(Status.BUILD)
|
||||
.image(
|
||||
Resource
|
||||
.builder()
|
||||
|
|
|
@ -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.predicates;
|
||||
|
||||
import static org.jclouds.openstack.nova.v1_1.predicates.ImagePredicates.statusEquals;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Image;
|
||||
import org.jclouds.openstack.nova.v1_1.domain.Image.Status;
|
||||
import org.jclouds.openstack.nova.v1_1.parse.ParseImageTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "ImagePredicatesTest")
|
||||
public class ImagePredicatesTest {
|
||||
Image ref = new ParseImageTest().expected();
|
||||
|
||||
@Test
|
||||
public void teststatusEqualsWhenEqual() {
|
||||
assert statusEquals(Status.SAVING).apply(ref);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void teststatusEqualsWhenNotEqual() {
|
||||
assert !statusEquals(Status.DELETED).apply(ref);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/**
|
||||
* 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.predicates;
|
||||
|
||||
import static org.jclouds.openstack.nova.v1_1.predicates.SecurityGroupPredicates.nameEquals;
|
||||
|
||||
import org.jclouds.openstack.nova.v1_1.domain.SecurityGroup;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Adrian Cole
|
||||
*/
|
||||
@Test(groups = "unit", testName = "SecurityGroupPredicatesTest")
|
||||
public class SecurityGroupPredicatesTest {
|
||||
SecurityGroup ref = SecurityGroup.builder().name("jclouds").description("description").build();
|
||||
|
||||
@Test
|
||||
public void testnameEqualsWhenEqual() {
|
||||
assert nameEquals("jclouds").apply(ref);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testnameEqualsWhenNotEqual() {
|
||||
assert !nameEquals("foo").apply(ref);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
{
|
||||
"security_groups":[
|
||||
{
|
||||
"rules": [{
|
||||
"from_port": 22,
|
||||
"group": {},
|
||||
"ip_protocol": "tcp",
|
||||
"to_port": 22,
|
||||
"parent_group_id": 2769,
|
||||
"ip_range": {
|
||||
"cidr": "0.0.0.0/0"
|
||||
},
|
||||
"id": 10331
|
||||
}, {
|
||||
"from_port": 22,
|
||||
"group": {
|
||||
"tenant_id": "37936628937291",
|
||||
"name": "jclouds#mygroup"
|
||||
},
|
||||
"ip_protocol": "tcp",
|
||||
"to_port": 22,
|
||||
"parent_group_id": 2769,
|
||||
"ip_range": {},
|
||||
"id": 10332
|
||||
}, {
|
||||
"from_port": 8080,
|
||||
"group": {},
|
||||
"ip_protocol": "tcp",
|
||||
"to_port": 8080,
|
||||
"parent_group_id": 2769,
|
||||
"ip_range": {
|
||||
"cidr": "0.0.0.0/0"
|
||||
},
|
||||
"id": 10333
|
||||
}, {
|
||||
"from_port": 8080,
|
||||
"group": {
|
||||
"tenant_id": "37936628937291",
|
||||
"name": "jclouds#mygroup"
|
||||
},
|
||||
"ip_protocol": "tcp",
|
||||
"to_port": 8080,
|
||||
"parent_group_id": 2769,
|
||||
"ip_range": {},
|
||||
"id": 10334
|
||||
}],
|
||||
"tenant_id": "37936628937291",
|
||||
"id": 2769,
|
||||
"name": "jclouds#mygroup",
|
||||
"description": "jclouds#mygroup"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue