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
|
@ -205,6 +205,24 @@ 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.
|
* 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.contextbuilder=org.jclouds.hpcloud.objectstorage.lvs.HPCloudObjectStorageLasVegasContextBuilder
|
||||||
hpcloud-objectstorage-lvs.propertiesbuilder=org.jclouds.hpcloud.objectstorage.lvs.HPCloudObjectStorageLasVegasPropertiesBuilder
|
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
|
hpcloud-compute.propertiesbuilder=org.jclouds.hpcloud.compute.HPCloudComputePropertiesBuilder
|
||||||
|
|
|
@ -16,32 +16,28 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* 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
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public enum ImageStatus {
|
public class HPCloudComputeContextBuilder extends NovaContextBuilder {
|
||||||
|
|
||||||
UNRECOGNIZED, UNKNOWN, ACTIVE, SAVING, ERROR, DELETED;
|
public HPCloudComputeContextBuilder(Properties props) {
|
||||||
|
super(props);
|
||||||
public String value() {
|
|
||||||
return name();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImageStatus fromValue(String v) {
|
@Override
|
||||||
try {
|
protected void addContextModule(List<Module> modules) {
|
||||||
return valueOf(v);
|
modules.add(new HPCloudComputeServiceContextModule());
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
return UNRECOGNIZED;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
|
@ -20,11 +20,12 @@ package org.jclouds.hpcloud.compute;
|
||||||
|
|
||||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||||
import static org.jclouds.Constants.PROPERTY_ISO3166_CODES;
|
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 java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaPropertiesBuilder;
|
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 properties = super.defaultProperties();
|
||||||
properties.setProperty(PROPERTY_ISO3166_CODES, "US-NV");
|
properties.setProperty(PROPERTY_ISO3166_CODES, "US-NV");
|
||||||
properties.setProperty(PROPERTY_ENDPOINT, "https://region-a.geo-1.identity.hpcloudsvc.com:35357");
|
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;
|
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().is64Bit(), true);
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "11.10");
|
assertEquals(defaultTemplate.getImage().getOperatingSystem().getVersion(), "11.10");
|
||||||
assertEquals(defaultTemplate.getImage().getOperatingSystem().getFamily(), OsFamily.UBUNTU);
|
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.getLocation().getId(), "az-1.region-a.geo-1");
|
||||||
assertEquals(defaultTemplate.getOptions().as(NovaTemplateOptions.class).shouldAutoAssignFloatingIp(), true);
|
assertEquals(defaultTemplate.getOptions().as(NovaTemplateOptions.class).shouldAutoAssignFloatingIp(), true);
|
||||||
assertEquals(getCores(defaultTemplate.getHardware()), 1.0d);
|
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_API_VERSION, "1.1");
|
||||||
properties.setProperty(PROPERTY_NOVA_AUTO_ALLOCATE_FLOATING_IPS, "false");
|
properties.setProperty(PROPERTY_NOVA_AUTO_ALLOCATE_FLOATING_IPS, "false");
|
||||||
properties.setProperty(PROPERTY_NOVA_TIMEOUT_SECURITYGROUP_PRESENT, "500");
|
properties.setProperty(PROPERTY_NOVA_TIMEOUT_SECURITYGROUP_PRESENT, "500");
|
||||||
|
|
||||||
return properties;
|
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.location.Zone;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
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.functions.RemoveFloatingIpFromNodeAndDeallocate;
|
||||||
import org.jclouds.openstack.nova.v1_1.compute.options.NovaTemplateOptions;
|
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.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.Image;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.RebootType;
|
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.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.options.CreateServerOptions;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.predicates.ImagePredicates;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.collect.ImmutableSet;
|
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;
|
import com.google.common.collect.ImmutableSet.Builder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -103,7 +104,7 @@ public class NovaComputeServiceAdapter implements
|
||||||
public Iterable<FlavorInZone> listHardwareProfiles() {
|
public Iterable<FlavorInZone> listHardwareProfiles() {
|
||||||
Builder<FlavorInZone> builder = ImmutableSet.<FlavorInZone> builder();
|
Builder<FlavorInZone> builder = ImmutableSet.<FlavorInZone> builder();
|
||||||
for (final String zoneId : zoneIds.get()) {
|
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>() {
|
new Function<Flavor, FlavorInZone>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -120,8 +121,8 @@ public class NovaComputeServiceAdapter implements
|
||||||
public Iterable<ImageInZone> listImages() {
|
public Iterable<ImageInZone> listImages() {
|
||||||
Builder<ImageInZone> builder = ImmutableSet.<ImageInZone> builder();
|
Builder<ImageInZone> builder = ImmutableSet.<ImageInZone> builder();
|
||||||
for (final String zoneId : zoneIds.get()) {
|
for (final String zoneId : zoneIds.get()) {
|
||||||
builder.addAll(Iterables.transform(novaClient.getImageClientForZone(zoneId).listImagesInDetail(),
|
builder.addAll(transform(filter(novaClient.getImageClientForZone(zoneId).listImagesInDetail(), ImagePredicates
|
||||||
new Function<Image, ImageInZone>() {
|
.statusEquals(Image.Status.ACTIVE)), new Function<Image, ImageInZone>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImageInZone apply(Image arg0) {
|
public ImageInZone apply(Image arg0) {
|
||||||
|
@ -137,7 +138,7 @@ public class NovaComputeServiceAdapter implements
|
||||||
public Iterable<ServerInZone> listNodes() {
|
public Iterable<ServerInZone> listNodes() {
|
||||||
Builder<ServerInZone> builder = ImmutableSet.<ServerInZone> builder();
|
Builder<ServerInZone> builder = ImmutableSet.<ServerInZone> builder();
|
||||||
for (final String zoneId : zoneIds.get()) {
|
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>() {
|
new Function<Server, ServerInZone>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -27,6 +27,7 @@ import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.collect.Memoized;
|
import org.jclouds.collect.Memoized;
|
||||||
|
import org.jclouds.compute.ComputeService;
|
||||||
import org.jclouds.compute.ComputeServiceAdapter;
|
import org.jclouds.compute.ComputeServiceAdapter;
|
||||||
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
import org.jclouds.compute.config.ComputeServiceAdapterContextModule;
|
||||||
import org.jclouds.compute.domain.Hardware;
|
import org.jclouds.compute.domain.Hardware;
|
||||||
|
@ -39,23 +40,25 @@ import org.jclouds.domain.Location;
|
||||||
import org.jclouds.functions.IdentityFunction;
|
import org.jclouds.functions.IdentityFunction;
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
|
import org.jclouds.openstack.nova.v1_1.NovaAsyncClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
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.NovaComputeServiceAdapter;
|
||||||
import org.jclouds.openstack.nova.v1_1.compute.domain.FlavorInZone;
|
import org.jclouds.openstack.nova.v1_1.compute.functions.CreateSecurityGroupIfNeeded;
|
||||||
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.FlavorInZoneToHardware;
|
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.ImageInZoneToImage;
|
||||||
import org.jclouds.openstack.nova.v1_1.compute.functions.NovaImageToOperatingSystem;
|
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.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.loaders.LoadFloatingIpsForInstance;
|
||||||
import org.jclouds.openstack.nova.v1_1.compute.options.NovaTemplateOptions;
|
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.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.predicates.FindSecurityGroupWithNameAndReturnTrue;
|
||||||
import org.jclouds.openstack.nova.v1_1.reference.NovaConstants;
|
import org.jclouds.openstack.nova.v1_1.reference.NovaConstants;
|
||||||
import org.jclouds.predicates.RetryablePredicate;
|
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.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
import com.google.inject.Injector;
|
import com.google.inject.Injector;
|
||||||
import com.google.inject.Key;
|
import com.google.inject.Key;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
|
@ -93,9 +97,14 @@ public class NovaComputeServiceContextModule
|
||||||
bind(new TypeLiteral<ComputeServiceAdapter<ServerInZone, FlavorInZone, ImageInZone, Location>>() {
|
bind(new TypeLiteral<ComputeServiceAdapter<ServerInZone, FlavorInZone, ImageInZone, Location>>() {
|
||||||
}).to(NovaComputeServiceAdapter.class);
|
}).to(NovaComputeServiceAdapter.class);
|
||||||
|
|
||||||
|
bind(ComputeService.class).to(NovaComputeService.class);
|
||||||
|
|
||||||
bind(new TypeLiteral<Function<ServerInZone, NodeMetadata>>() {
|
bind(new TypeLiteral<Function<ServerInZone, NodeMetadata>>() {
|
||||||
}).to(ServerInZoneToNodeMetadata.class);
|
}).to(ServerInZoneToNodeMetadata.class);
|
||||||
|
|
||||||
|
bind(new TypeLiteral<Function<Set<? extends NodeMetadata>, Multimap<String, String>>>() {
|
||||||
|
}).to(OrphanedGroupsByZoneId.class);
|
||||||
|
|
||||||
bind(new TypeLiteral<Function<ImageInZone, Image>>() {
|
bind(new TypeLiteral<Function<ImageInZone, Image>>() {
|
||||||
}).to(ImageInZoneToImage.class);
|
}).to(ImageInZoneToImage.class);
|
||||||
bind(new TypeLiteral<Function<org.jclouds.openstack.nova.v1_1.domain.Image, OperatingSystem>>() {
|
bind(new TypeLiteral<Function<org.jclouds.openstack.nova.v1_1.domain.Image, OperatingSystem>>() {
|
||||||
|
@ -114,10 +123,10 @@ public class NovaComputeServiceContextModule
|
||||||
}).annotatedWith(Names.named("FLOATINGIP")).to(LoadFloatingIpsForInstance.class);
|
}).annotatedWith(Names.named("FLOATINGIP")).to(LoadFloatingIpsForInstance.class);
|
||||||
|
|
||||||
bind(new TypeLiteral<Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone>>() {
|
bind(new TypeLiteral<Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone>>() {
|
||||||
}).to(CreateSecurityGroupInZone.class);
|
}).to(CreateSecurityGroupIfNeeded.class);
|
||||||
|
|
||||||
bind(new TypeLiteral<CacheLoader<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone>>() {
|
bind(new TypeLiteral<CacheLoader<ZoneAndName, SecurityGroupInZone>>() {
|
||||||
}).to(CreateOrUpdateSecurityGroupAsNeeded.class);
|
}).to(FindSecurityGroupOrCreate.class);
|
||||||
|
|
||||||
bind(CreateNodesWithGroupEncodedIntoNameThenAddToSet.class).to(
|
bind(CreateNodesWithGroupEncodedIntoNameThenAddToSet.class).to(
|
||||||
ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.class);
|
ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet.class);
|
||||||
|
@ -141,8 +150,8 @@ public class NovaComputeServiceContextModule
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
protected LoadingCache<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> securityGroupMap(
|
protected LoadingCache<ZoneAndName, SecurityGroupInZone> securityGroupMap(
|
||||||
CacheLoader<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> in) {
|
CacheLoader<ZoneAndName, SecurityGroupInZone> in) {
|
||||||
return CacheBuilder.newBuilder().build(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.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
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.FloatingIP;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndId;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
||||||
import org.jclouds.rest.InsufficientResourcesException;
|
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.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
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.annotation.Resource;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
@ -29,11 +31,11 @@ import javax.inject.Singleton;
|
||||||
import org.jclouds.compute.reference.ComputeServiceConstants;
|
import org.jclouds.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
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.Ingress;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.IpProtocol;
|
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.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 org.jclouds.openstack.nova.v1_1.extensions.SecurityGroupClient;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
|
@ -44,14 +46,14 @@ import com.google.common.base.Optional;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
public class CreateSecurityGroupInZone implements Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> {
|
public class CreateSecurityGroupIfNeeded implements Function<ZoneSecurityGroupNameAndPorts, SecurityGroupInZone> {
|
||||||
@Resource
|
@Resource
|
||||||
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
@Named(ComputeServiceConstants.COMPUTE_LOGGER)
|
||||||
protected Logger logger = Logger.NULL;
|
protected Logger logger = Logger.NULL;
|
||||||
protected final NovaClient novaClient;
|
protected final NovaClient novaClient;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public CreateSecurityGroupInZone(NovaClient novaClient) {
|
public CreateSecurityGroupIfNeeded(NovaClient novaClient) {
|
||||||
this.novaClient = checkNotNull(novaClient, "novaClient");
|
this.novaClient = checkNotNull(novaClient, "novaClient");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,8 +64,9 @@ public class CreateSecurityGroupInZone implements Function<ZoneSecurityGroupName
|
||||||
String zoneId = zoneSecurityGroupNameAndPorts.getZone();
|
String zoneId = zoneSecurityGroupNameAndPorts.getZone();
|
||||||
Optional<SecurityGroupClient> client = novaClient.getSecurityGroupExtensionForZone(zoneId);
|
Optional<SecurityGroupClient> client = novaClient.getSecurityGroupExtensionForZone(zoneId);
|
||||||
checkArgument(client.isPresent(), "Security groups are required, but the extension is not available!");
|
checkArgument(client.isPresent(), "Security groups are required, but the extension is not available!");
|
||||||
|
|
||||||
logger.debug(">> creating securityGroup %s", zoneSecurityGroupNameAndPorts);
|
logger.debug(">> creating securityGroup %s", zoneSecurityGroupNameAndPorts);
|
||||||
|
try {
|
||||||
|
|
||||||
SecurityGroup securityGroup = client.get().createSecurityGroupWithNameAndDescription(
|
SecurityGroup securityGroup = client.get().createSecurityGroupWithNameAndDescription(
|
||||||
zoneSecurityGroupNameAndPorts.getName(), zoneSecurityGroupNameAndPorts.getName());
|
zoneSecurityGroupNameAndPorts.getName(), zoneSecurityGroupNameAndPorts.getName());
|
||||||
|
|
||||||
|
@ -72,6 +75,13 @@ public class CreateSecurityGroupInZone implements Function<ZoneSecurityGroupName
|
||||||
authorizeGroupToItselfAndAllIPsToTCPPort(client.get(), securityGroup, port);
|
authorizeGroupToItselfAndAllIPsToTCPPort(client.get(), securityGroup, port);
|
||||||
}
|
}
|
||||||
return new SecurityGroupInZone(client.get().getSecurityGroup(securityGroup.getId()), zoneId);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void authorizeGroupToItselfAndAllIPsToTCPPort(SecurityGroupClient securityGroupClient,
|
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.Processor;
|
||||||
import org.jclouds.compute.domain.internal.VolumeImpl;
|
import org.jclouds.compute.domain.internal.VolumeImpl;
|
||||||
import org.jclouds.domain.Location;
|
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.Flavor;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.FlavorInZone;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.base.Supplier;
|
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.ImageBuilder;
|
||||||
import org.jclouds.compute.domain.OperatingSystem;
|
import org.jclouds.compute.domain.OperatingSystem;
|
||||||
import org.jclouds.domain.Location;
|
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.Function;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
|
@ -55,8 +55,8 @@ public class ImageInZoneToImage implements Function<ImageInZone, Image> {
|
||||||
Location location = locationIndex.get().get(imageInZone.getZone());
|
Location location = locationIndex.get().get(imageInZone.getZone());
|
||||||
checkState(location != null, "location %s not in locationIndex: %s", imageInZone.getZone(), locationIndex.get());
|
checkState(location != null, "location %s not in locationIndex: %s", imageInZone.getZone(), locationIndex.get());
|
||||||
org.jclouds.openstack.nova.v1_1.domain.Image image = imageInZone.getImage();
|
org.jclouds.openstack.nova.v1_1.domain.Image image = imageInZone.getImage();
|
||||||
return new ImageBuilder()
|
return new ImageBuilder().id(imageInZone.slashEncode()).providerId(image.getId()).name(image.getName())
|
||||||
.id(imageInZone.slashEncode()).providerId(image.getId()).name(image.getName()).operatingSystem(
|
.userMetadata(image.getMetadata()).operatingSystem(imageToOs.apply(image)).description(image.getName())
|
||||||
imageToOs.apply(image)).description(image.getName()).location(location).build();
|
.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.compute.reference.ComputeServiceConstants;
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
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 org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
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.checkNotNull;
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
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 static org.jclouds.compute.util.ComputeServiceUtils.parseGroupFromName;
|
||||||
|
|
||||||
|
import java.net.Inet4Address;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -42,16 +47,16 @@ import org.jclouds.domain.Location;
|
||||||
import org.jclouds.domain.LocationBuilder;
|
import org.jclouds.domain.LocationBuilder;
|
||||||
import org.jclouds.domain.LocationScope;
|
import org.jclouds.domain.LocationScope;
|
||||||
import org.jclouds.logging.Logger;
|
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.Address;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
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.Function;
|
||||||
import com.google.common.base.Predicate;
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Supplier;
|
import com.google.common.base.Supplier;
|
||||||
import com.google.common.cache.LoadingCache;
|
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.
|
* 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.operatingSystem(findOperatingSystemForServerOrNull(serverInZone));
|
||||||
builder.hardware(findHardwareForServerOrNull(serverInZone));
|
builder.hardware(findHardwareForServerOrNull(serverInZone));
|
||||||
builder.state(from.getStatus().getNodeState());
|
builder.state(from.getStatus().getNodeState());
|
||||||
builder.publicAddresses(getPublicAddresses(serverInZone));
|
builder.publicAddresses(filter(getPublicAddresses(serverInZone), isInet4Address));
|
||||||
builder.privateAddresses(Iterables.transform(from.getPrivateAddresses(),
|
builder.privateAddresses(filter(transform(from.getPrivateAddresses(),
|
||||||
AddressToStringTransformationFunction.INSTANCE));
|
AddressToStringTransformationFunction.INSTANCE), isInet4Address));
|
||||||
|
|
||||||
return builder.build();
|
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) {
|
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));
|
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,
|
public <T extends ComputeMetadata> T findObjectOfTypeForServerOrNull(Set<? extends T> supply, String type,
|
||||||
final String objectId, final ZoneAndId serverInZone) {
|
final String objectId, final ZoneAndId serverInZone) {
|
||||||
try {
|
try {
|
||||||
return Iterables.find(supply, new Predicate<T>() {
|
return find(supply, new Predicate<T>() {
|
||||||
@Override
|
@Override
|
||||||
public boolean apply(T input) {
|
public boolean apply(T input) {
|
||||||
return input.getId().equals(ZoneAndId.fromZoneAndId(serverInZone.getZone(), objectId).slashEncode());
|
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 javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
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.FloatingIP;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndId;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
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.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Provider;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.Constants;
|
import org.jclouds.Constants;
|
||||||
import org.jclouds.compute.config.CustomizationResponse;
|
import org.jclouds.compute.config.CustomizationResponse;
|
||||||
import org.jclouds.compute.domain.NodeMetadata;
|
import org.jclouds.compute.domain.NodeMetadata;
|
||||||
import org.jclouds.compute.domain.Template;
|
import org.jclouds.compute.domain.Template;
|
||||||
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
|
import org.jclouds.compute.strategy.CreateNodeWithGroupEncodedIntoName;
|
||||||
import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
import org.jclouds.compute.strategy.CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap;
|
||||||
import org.jclouds.compute.strategy.ListNodesStrategy;
|
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.NovaClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.compute.functions.AllocateAndAddFloatingIpToNode;
|
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.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.collect.Multimap;
|
||||||
|
import com.google.common.primitives.Ints;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -55,7 +65,9 @@ public class ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddT
|
||||||
CreateNodesWithGroupEncodedIntoNameThenAddToSet {
|
CreateNodesWithGroupEncodedIntoNameThenAddToSet {
|
||||||
|
|
||||||
private final AllocateAndAddFloatingIpToNode allocateAndAddFloatingIpToNode;
|
private final AllocateAndAddFloatingIpToNode allocateAndAddFloatingIpToNode;
|
||||||
|
private final LoadingCache<ZoneAndName, SecurityGroupInZone> securityGroupCache;
|
||||||
private final NovaClient novaClient;
|
private final NovaClient novaClient;
|
||||||
|
private final Provider<TemplateBuilder> templateBuilderProvider;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet(
|
protected ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet(
|
||||||
|
@ -64,9 +76,13 @@ public class ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddT
|
||||||
@Named("NAMING_CONVENTION") String nodeNamingConvention,
|
@Named("NAMING_CONVENTION") String nodeNamingConvention,
|
||||||
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
|
CustomizeNodeAndAddToGoodMapOrPutExceptionIntoBadMap.Factory customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory,
|
||||||
@Named(Constants.PROPERTY_USER_THREADS) ExecutorService executor,
|
@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,
|
super(addNodeWithTagStrategy, listNodesStrategy, nodeNamingConvention, executor,
|
||||||
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
|
customizeNodeAndAddToGoodMapOrPutExceptionIntoBadMapFactory);
|
||||||
|
this.templateBuilderProvider = checkNotNull(templateBuilderProvider, "templateBuilderProvider");
|
||||||
|
this.securityGroupCache = checkNotNull(securityGroupCache, "securityGroupCache");
|
||||||
this.allocateAndAddFloatingIpToNode = checkNotNull(allocateAndAddFloatingIpToNode,
|
this.allocateAndAddFloatingIpToNode = checkNotNull(allocateAndAddFloatingIpToNode,
|
||||||
"allocateAndAddFloatingIpToNode");
|
"allocateAndAddFloatingIpToNode");
|
||||||
this.novaClient = checkNotNull(novaClient, "novaClient");
|
this.novaClient = checkNotNull(novaClient, "novaClient");
|
||||||
|
@ -75,23 +91,38 @@ public class ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddT
|
||||||
@Override
|
@Override
|
||||||
public Map<?, Future<Void>> execute(String group, int count, Template template, Set<NodeMetadata> goodNodes,
|
public Map<?, Future<Void>> execute(String group, int count, Template template, Set<NodeMetadata> goodNodes,
|
||||||
Map<NodeMetadata, Exception> badNodes, Multimap<NodeMetadata, CustomizationResponse> customizationResponses) {
|
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:
|
// TODO: make NovaTemplateOptions with the following:
|
||||||
// security group, key pair
|
// 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()) {
|
if (templateOptions.shouldAutoAssignFloatingIp()) {
|
||||||
checkArgument(novaClient.getFloatingIPExtensionForZone(zone).isPresent(),
|
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) {
|
if (templateOptions.getSecurityGroupNames().size() > 0) {
|
||||||
checkArgument(novaClient.getSecurityGroupExtensionForZone(zone).isPresent(),
|
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
|
@Override
|
||||||
|
|
|
@ -27,20 +27,47 @@ import java.util.Set;
|
||||||
import org.jclouds.openstack.domain.Link;
|
import org.jclouds.openstack.domain.Link;
|
||||||
import org.jclouds.openstack.domain.Resource;
|
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.common.collect.Maps;
|
||||||
import com.google.gson.annotations.SerializedName;
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An image is a collection of files you use to create or rebuild a server.
|
* An image is a collection of files you use to create or rebuild a server. Operators provide
|
||||||
* Operators provide pre-built OS images by default. You may also create custom
|
* pre-built OS images by default. You may also create custom images.
|
||||||
* images.
|
|
||||||
*
|
*
|
||||||
* @author Jeremy Daggett
|
* @author Jeremy Daggett
|
||||||
* @see <a href=
|
* @see <a href= "http://docs.openstack.org/api/openstack-compute/1.1/content/Images-d1e4427.html"
|
||||||
* "http://docs.openstack.org/api/openstack-compute/1.1/content/Images-d1e4427.html"
|
|
||||||
* />
|
* />
|
||||||
*/
|
*/
|
||||||
public class Image extends Resource {
|
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() {
|
public static Builder builder() {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
}
|
}
|
||||||
|
@ -55,12 +82,12 @@ public class Image extends Resource {
|
||||||
private Date created;
|
private Date created;
|
||||||
private String tenantId;
|
private String tenantId;
|
||||||
private String userId;
|
private String userId;
|
||||||
private ImageStatus status;
|
private Status status;
|
||||||
private int progress;
|
private int progress;
|
||||||
private int minDisk;
|
private int minDisk;
|
||||||
private int minRam;
|
private int minRam;
|
||||||
private Resource server;
|
private Resource server;
|
||||||
private Map<String, String> metadata = Maps.newHashMap();
|
private Map<String, String> metadata = Maps.newLinkedHashMap();
|
||||||
|
|
||||||
public Builder updated(Date updated) {
|
public Builder updated(Date updated) {
|
||||||
this.updated = updated;
|
this.updated = updated;
|
||||||
|
@ -82,7 +109,7 @@ public class Image extends Resource {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder status(ImageStatus status) {
|
public Builder status(Status status) {
|
||||||
this.status = status;
|
this.status = status;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -118,8 +145,8 @@ public class Image extends Resource {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder fromImage(Image in) {
|
public Builder fromImage(Image in) {
|
||||||
return fromResource(in).status(in.getStatus()).updated(in.getUpdated()).created(in.getCreated())
|
return fromResource(in).status(in.getStatus()).updated(in.getUpdated()).created(in.getCreated()).progress(
|
||||||
.progress(in.getProgress()).server(in.getServer()).metadata(in.getMetadata());
|
in.getProgress()).server(in.getServer()).metadata(in.getMetadata());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,21 +182,21 @@ public class Image extends Resource {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Date updated;
|
private final Date updated;
|
||||||
private Date created;
|
private final Date created;
|
||||||
@SerializedName("tenant_id")
|
@SerializedName("tenant_id")
|
||||||
private String tenantId;
|
private final String tenantId;
|
||||||
@SerializedName("user_id")
|
@SerializedName("user_id")
|
||||||
private String userId;
|
private final String userId;
|
||||||
private ImageStatus status;
|
private final Status status;
|
||||||
private int progress;
|
private final int progress;
|
||||||
private int minDisk;
|
private final int minDisk;
|
||||||
private int minRam;
|
private final int minRam;
|
||||||
private Resource server;
|
private final Resource server;
|
||||||
private Map<String, String> metadata = Maps.newHashMap();
|
private final Map<String, String> metadata;
|
||||||
|
|
||||||
protected Image(String id, String name, Set<Link> links, Date updated, Date created, String tenantId, String userId,
|
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);
|
super(id, name, links);
|
||||||
this.updated = updated;
|
this.updated = updated;
|
||||||
this.created = created;
|
this.created = created;
|
||||||
|
@ -180,7 +207,7 @@ public class Image extends Resource {
|
||||||
this.minDisk = minDisk;
|
this.minDisk = minDisk;
|
||||||
this.minRam = minRam;
|
this.minRam = minRam;
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.metadata = metadata;
|
this.metadata = ImmutableMap.<String, String> copyOf(metadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getUpdated() {
|
public Date getUpdated() {
|
||||||
|
@ -199,7 +226,7 @@ public class Image extends Resource {
|
||||||
return this.userId;
|
return this.userId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ImageStatus getStatus() {
|
public Status getStatus() {
|
||||||
return this.status;
|
return this.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,15 +247,16 @@ public class Image extends Resource {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getMetadata() {
|
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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return toStringHelper("").add("id", id).add("name", name).add("links", links).add("updated", updated)
|
return toStringHelper("").add("id", id).add("name", name).add("links", links).add("updated", updated).add(
|
||||||
.add("created", created).add("tenantId", tenantId).add("userId", userId).add("status", status)
|
"created", created).add("tenantId", tenantId).add("userId", userId).add("status", status).add(
|
||||||
.add("progress", progress).add("minDisk", minDisk).add("minRam", minRam).add("server", server)
|
"progress", progress).add("minDisk", minDisk).add("minRam", minRam).add("server", server).add(
|
||||||
.add("metadata", metadata).toString();
|
"metadata", metadata).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,22 +26,19 @@ import java.util.Date;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.jclouds.compute.domain.NodeState;
|
||||||
import org.jclouds.javax.annotation.Nullable;
|
import org.jclouds.javax.annotation.Nullable;
|
||||||
import org.jclouds.openstack.domain.Link;
|
import org.jclouds.openstack.domain.Link;
|
||||||
import org.jclouds.openstack.domain.Resource;
|
import org.jclouds.openstack.domain.Resource;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.Address.Type;
|
import org.jclouds.openstack.nova.v1_1.domain.Address.Type;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.KeyPairClient;
|
||||||
import org.jclouds.util.InetAddresses2;
|
|
||||||
import org.jclouds.util.Multimaps2;
|
import org.jclouds.util.Multimaps2;
|
||||||
|
|
||||||
import com.google.common.base.Predicate;
|
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
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.LinkedHashMultimap;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
@ -57,6 +54,47 @@ import com.google.gson.annotations.SerializedName;
|
||||||
* />
|
* />
|
||||||
*/
|
*/
|
||||||
public class Server extends Resource {
|
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() {
|
public static Builder builder() {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
}
|
}
|
||||||
|
@ -74,7 +112,7 @@ public class Server extends Resource {
|
||||||
private String hostId;
|
private String hostId;
|
||||||
private String accessIPv4;
|
private String accessIPv4;
|
||||||
private String accessIPv6;
|
private String accessIPv6;
|
||||||
private ServerStatus status;
|
private Status status;
|
||||||
private String configDrive;
|
private String configDrive;
|
||||||
private Resource image;
|
private Resource image;
|
||||||
private Resource flavor;
|
private Resource flavor;
|
||||||
|
@ -151,7 +189,7 @@ public class Server extends Resource {
|
||||||
/**
|
/**
|
||||||
* @see Server#getStatus()
|
* @see Server#getStatus()
|
||||||
*/
|
*/
|
||||||
public Builder status(ServerStatus status) {
|
public Builder status(Status status) {
|
||||||
this.status = status;
|
this.status = status;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -309,7 +347,7 @@ public class Server extends Resource {
|
||||||
protected final String hostId;
|
protected final String hostId;
|
||||||
protected final String accessIPv4;
|
protected final String accessIPv4;
|
||||||
protected final String accessIPv6;
|
protected final String accessIPv6;
|
||||||
protected final ServerStatus status;
|
protected final Status status;
|
||||||
protected final Resource image;
|
protected final Resource image;
|
||||||
protected final Resource flavor;
|
protected final Resource flavor;
|
||||||
protected final String adminPass;
|
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,
|
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,
|
Date updated, Date created, @Nullable String hostId, @Nullable String accessIPv4,
|
||||||
@Nullable String accessIPv6, ServerStatus status, @Nullable String configDrive, Resource image,
|
@Nullable String accessIPv6, Status status, @Nullable String configDrive, Resource image, Resource flavor,
|
||||||
Resource flavor, String adminPass, @Nullable String keyName, Multimap<Address.Type, Address> addresses,
|
String adminPass, @Nullable String keyName, Multimap<Address.Type, Address> addresses,
|
||||||
Map<String, String> metadata) {
|
Map<String, String> metadata) {
|
||||||
super(id, name, links);
|
super(id, name, links);
|
||||||
this.uuid = uuid; // TODO: see what version this came up in
|
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);
|
return Strings.emptyToNull(this.accessIPv6);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerStatus getStatus() {
|
public Status getStatus() {
|
||||||
return this.status;
|
return this.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -408,7 +446,8 @@ public class Server extends Resource {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, String> getMetadata() {
|
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
|
* @return the ip addresses assigned to the server
|
||||||
*/
|
*/
|
||||||
public Multimap<Type, Address> getAddresses() {
|
public Multimap<Type, Address> getAddresses() {
|
||||||
ImmutableSetMultimap.Builder<Type, Address> returnMapBuilder = new ImmutableSetMultimap.Builder<Type, Address>();
|
return Multimaps2.fromOldSchool(addresses);
|
||||||
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* 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;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* 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;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
|
@ -26,15 +26,15 @@ import org.jclouds.openstack.nova.v1_1.domain.Image;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class ImageInZone extends ZoneAndId {
|
public class ImageInZone extends ZoneAndId {
|
||||||
protected final Image server;
|
protected final Image image;
|
||||||
|
|
||||||
public ImageInZone(Image server, String zoneId) {
|
public ImageInZone(Image image, String zoneId) {
|
||||||
super(zoneId, checkNotNull(server, "server").getId());
|
super(zoneId, checkNotNull(image, "image").getId());
|
||||||
this.server = server;
|
this.image = image;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Image getImage() {
|
public Image getImage() {
|
||||||
return server;
|
return image;
|
||||||
}
|
}
|
||||||
|
|
||||||
// superclass hashCode/equals are good enough, and help us use ZoneAndId and ImageInZone
|
// superclass hashCode/equals are good enough, and help us use ZoneAndId and ImageInZone
|
||||||
|
@ -42,7 +42,7 @@ public class ImageInZone extends ZoneAndId {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[server=" + server + ", zoneId=" + zoneId + "]";
|
return "[image=" + image + ", zoneId=" + zoneId + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* 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;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* 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;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* 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.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
|
@ -16,12 +16,13 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* 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.Objects.equal;
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
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.Objects;
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.google.common.base.Objects.ToStringHelper;
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
|
@ -33,6 +34,25 @@ import com.google.common.collect.Iterables;
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class ZoneAndName {
|
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) {
|
public static ZoneAndName fromSlashEncoded(String name) {
|
||||||
Iterable<String> parts = Splitter.on('/').split(checkNotNull(name, "name"));
|
Iterable<String> parts = Splitter.on('/').split(checkNotNull(name, "name"));
|
||||||
checkArgument(Iterables.size(parts) == 2, "name must be in format zoneId/name");
|
checkArgument(Iterables.size(parts) == 2, "name must be in format zoneId/name");
|
|
@ -16,29 +16,29 @@
|
||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* 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.Objects.equal;
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
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;
|
||||||
import com.google.common.base.Objects.ToStringHelper;
|
import com.google.common.base.Objects.ToStringHelper;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
public class ZoneSecurityGroupNameAndPorts extends ZoneAndName {
|
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);
|
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;
|
return ports;
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,8 @@ public class NovaErrorHandler implements HttpErrorHandler {
|
||||||
exception = new InsufficientResourcesException(message, exception);
|
exception = new InsufficientResourcesException(message, exception);
|
||||||
else if (message.indexOf("has no fixed_ips") != -1)
|
else if (message.indexOf("has no fixed_ips") != -1)
|
||||||
exception = new IllegalStateException(message, exception);
|
exception = new IllegalStateException(message, exception);
|
||||||
|
else if (message.indexOf("already exists") != -1)
|
||||||
|
exception = new IllegalStateException(message, exception);
|
||||||
break;
|
break;
|
||||||
case 401:
|
case 401:
|
||||||
case 403:
|
case 403:
|
||||||
|
|
|
@ -29,9 +29,9 @@ import javax.inject.Singleton;
|
||||||
|
|
||||||
import org.jclouds.logging.Logger;
|
import org.jclouds.logging.Logger;
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
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.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.extensions.SecurityGroupClient;
|
||||||
import org.jclouds.rest.ResourceNotFoundException;
|
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);
|
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
|
@Test
|
||||||
public void test400MakesInsufficientResourcesExceptionOnQuotaExceeded() {
|
public void test400MakesInsufficientResourcesExceptionOnQuotaExceeded() {
|
||||||
|
|
|
@ -29,8 +29,8 @@ import org.jclouds.compute.domain.Template;
|
||||||
import org.jclouds.compute.domain.TemplateBuilder;
|
import org.jclouds.compute.domain.TemplateBuilder;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
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.compute.options.NovaTemplateOptions;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ServerInZone;
|
||||||
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaComputeServiceContextExpectTest;
|
import org.jclouds.openstack.nova.v1_1.internal.BaseNovaComputeServiceContextExpectTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ import com.google.common.collect.ImmutableSet;
|
||||||
* @author Matt Stephenson
|
* @author Matt Stephenson
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", testName = "AllocateAndAddFloatingIpToNodeTest")
|
@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(
|
final Location provider = new LocationBuilder().scope(LocationScope.PROVIDER).id("openstack-nova").description(
|
||||||
"openstack-nova").build();
|
"openstack-nova").build();
|
||||||
final Location zone = new LocationBuilder().id("az-1.region-a.geo-1").description("az-1.region-a.geo-1").scope(
|
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.Location;
|
||||||
import org.jclouds.domain.LocationBuilder;
|
import org.jclouds.domain.LocationBuilder;
|
||||||
import org.jclouds.domain.LocationScope;
|
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.Flavor;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.FlavorInZone;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Supplier;
|
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.Location;
|
||||||
import org.jclouds.domain.LocationBuilder;
|
import org.jclouds.domain.LocationBuilder;
|
||||||
import org.jclouds.domain.LocationScope;
|
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.Image;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ImageInZone;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
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.Location;
|
||||||
import org.jclouds.domain.LocationBuilder;
|
import org.jclouds.domain.LocationBuilder;
|
||||||
import org.jclouds.domain.LocationScope;
|
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.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.ParseCreatedServerTest;
|
||||||
import org.jclouds.openstack.nova.v1_1.parse.ParseServerTest;
|
import org.jclouds.openstack.nova.v1_1.parse.ParseServerTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -134,8 +134,8 @@ public class ServerInZoneToNodeMetadataTest {
|
||||||
assertEquals(convertedNodeMetadata.getPrivateAddresses(), ImmutableSet.of("10.176.42.16"));
|
assertEquals(convertedNodeMetadata.getPrivateAddresses(), ImmutableSet.of("10.176.42.16"));
|
||||||
|
|
||||||
assertNotNull(convertedNodeMetadata.getPublicAddresses());
|
assertNotNull(convertedNodeMetadata.getPublicAddresses());
|
||||||
assertEquals(convertedNodeMetadata.getPublicAddresses(), ImmutableSet.of("67.23.10.132", "::babe:67.23.10.132",
|
// note jclouds doesn't yet support ipv6 b/c not tested yet
|
||||||
"67.23.10.131", "::babe:4317:0A83", "::babe:10.176.42.16"));
|
assertEquals(convertedNodeMetadata.getPublicAddresses(), ImmutableSet.of("67.23.10.132", "67.23.10.131"));
|
||||||
|
|
||||||
assertNotNull(convertedNodeMetadata.getUserMetadata());
|
assertNotNull(convertedNodeMetadata.getUserMetadata());
|
||||||
assertEquals(convertedNodeMetadata.getUserMetadata(), ImmutableMap.<String, String> of("Server Label",
|
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 static org.testng.AssertJUnit.assertFalse;
|
||||||
|
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
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.FloatingIP;
|
||||||
|
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.ZoneAndId;
|
||||||
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
import org.jclouds.openstack.nova.v1_1.extensions.FloatingIPClient;
|
||||||
import org.testng.annotations.Test;
|
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.Address;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.FloatingIP;
|
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.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.FlavorClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.features.ImageClient;
|
import org.jclouds.openstack.nova.v1_1.features.ImageClient;
|
||||||
import org.jclouds.openstack.nova.v1_1.features.ServerClient;
|
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 {
|
private void blockUntilServerActive(String serverId, ServerClient client) throws InterruptedException {
|
||||||
Server currentDetails = null;
|
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)) {
|
.getServer(serverId)) {
|
||||||
System.out.printf("blocking on status active%n%s%n", currentDetails);
|
System.out.printf("blocking on status active%n%s%n", currentDetails);
|
||||||
Thread.sleep(5 * 1000);
|
Thread.sleep(5 * 1000);
|
||||||
|
|
|
@ -25,9 +25,9 @@ import java.net.URI;
|
||||||
import org.jclouds.http.HttpRequest;
|
import org.jclouds.http.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
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.functions.CreateSecurityGroupIfNeeded;
|
||||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneSecurityGroupNameAndPorts;
|
import org.jclouds.openstack.nova.v1_1.domain.zonescoped.SecurityGroupInZone;
|
||||||
import org.jclouds.openstack.nova.v1_1.compute.functions.CreateSecurityGroupInZone;
|
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.internal.BaseNovaClientExpectTest;
|
||||||
import org.jclouds.openstack.nova.v1_1.parse.ParseComputeServiceTypicalSecurityGroupTest;
|
import org.jclouds.openstack.nova.v1_1.parse.ParseComputeServiceTypicalSecurityGroupTest;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
@ -35,22 +35,15 @@ import org.testng.annotations.Test;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableMultimap;
|
import com.google.common.collect.ImmutableMultimap;
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
import com.google.common.collect.ImmutableMap.Builder;
|
import com.google.common.collect.ImmutableMap.Builder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Adrian Cole
|
* @author Adrian Cole
|
||||||
*/
|
*/
|
||||||
@Test(groups = "unit", testName = "CreateSecurityGroupInZoneExpectTest")
|
@Test(groups = "unit", testName = "CreateSecurityGroupIfNeededTest")
|
||||||
public class CreateSecurityGroupInZoneExpectTest extends BaseNovaClientExpectTest {
|
public class CreateSecurityGroupIfNeededTest extends BaseNovaClientExpectTest {
|
||||||
|
|
||||||
public void testUpdateReferenceWhenSecurityGroupListContainsGroupName() 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(
|
HttpRequest createSecurityGroup = HttpRequest.builder().method("POST").endpoint(
|
||||||
URI.create("https://compute.north.host/v1.1/3456/os-security-groups")).headers(
|
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",
|
ImmutableMultimap.<String, String> builder().put("Accept", "application/json").put("X-Auth-Token",
|
||||||
|
@ -59,6 +52,13 @@ public class CreateSecurityGroupInZoneExpectTest extends BaseNovaClientExpectTes
|
||||||
payloadFromStringWithContentType(
|
payloadFromStringWithContentType(
|
||||||
"{\"security_group\":{\"name\":\"jclouds#mygroup\",\"description\":\"jclouds#mygroup\"}}",
|
"{\"security_group\":{\"name\":\"jclouds#mygroup\",\"description\":\"jclouds#mygroup\"}}",
|
||||||
"application/json")).build();
|
"application/json")).build();
|
||||||
|
|
||||||
|
public void testCreateNewGroup() throws Exception {
|
||||||
|
|
||||||
|
Builder<HttpRequest, HttpResponse> builder = ImmutableMap.<HttpRequest, HttpResponse>builder();
|
||||||
|
|
||||||
|
builder.put(keystoneAuthWithAccessKeyAndSecretKey, responseWithKeystoneAccess);
|
||||||
|
builder.put(extensionsOfNovaRequest, extensionsOfNovaResponse);
|
||||||
int groupId = 2769;
|
int groupId = 2769;
|
||||||
|
|
||||||
HttpResponse createSecurityGroupResponse = HttpResponse.builder().statusCode(200)
|
HttpResponse createSecurityGroupResponse = HttpResponse.builder().statusCode(200)
|
||||||
|
@ -119,16 +119,52 @@ public class CreateSecurityGroupInZoneExpectTest extends BaseNovaClientExpectTes
|
||||||
|
|
||||||
builder.put(getSecurityGroup, getSecurityGroupResponse);
|
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
|
// we can find it
|
||||||
assertEquals(fn.apply(
|
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(),
|
.toString(), new SecurityGroupInZone(new ParseComputeServiceTypicalSecurityGroupTest().expected(),
|
||||||
"az-1.region-a.geo-1").toString());
|
"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.HttpRequest;
|
||||||
import org.jclouds.http.HttpResponse;
|
import org.jclouds.http.HttpResponse;
|
||||||
import org.jclouds.openstack.nova.v1_1.NovaClient;
|
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.domain.zonescoped.SecurityGroupInZone;
|
||||||
import org.jclouds.openstack.nova.v1_1.compute.domain.ZoneAndName;
|
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.internal.BaseNovaClientExpectTest;
|
||||||
import org.jclouds.openstack.nova.v1_1.parse.ParseSecurityGroupListTest;
|
import org.jclouds.openstack.nova.v1_1.parse.ParseSecurityGroupListTest;
|
||||||
import org.jclouds.openstack.nova.v1_1.predicates.FindSecurityGroupWithNameAndReturnTrue;
|
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.domain.Link.Relation;
|
||||||
import org.jclouds.openstack.nova.v1_1.config.NovaParserModule;
|
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.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.jclouds.rest.annotations.SelectJson;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ public class ParseCreatedServerTest extends BaseItemParserTest<Server> {
|
||||||
.name("test-e92")
|
.name("test-e92")
|
||||||
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-03-19T06:21:13Z"))
|
.updated(new SimpleDateFormatDateService().iso8601SecondsDateParse("2012-03-19T06:21:13Z"))
|
||||||
.created(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")
|
.adminPass("ZWuHcmTMQ7eXoHeM")
|
||||||
.image(
|
.image(
|
||||||
Resource
|
Resource
|
||||||
|
|
|
@ -27,11 +27,11 @@ import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
import org.jclouds.json.BaseItemParserTest;
|
import org.jclouds.json.BaseItemParserTest;
|
||||||
import org.jclouds.json.config.GsonModule;
|
import org.jclouds.json.config.GsonModule;
|
||||||
import org.jclouds.openstack.domain.Link;
|
import org.jclouds.openstack.domain.Link;
|
||||||
import org.jclouds.openstack.domain.Link.Relation;
|
|
||||||
import org.jclouds.openstack.domain.Resource;
|
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.config.NovaParserModule;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.Image;
|
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.jclouds.rest.annotations.SelectJson;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ public class ParseImageTest extends BaseItemParserTest<Image> {
|
||||||
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2010-08-10T12:00:00Z"))
|
.created(new SimpleDateFormatDateService().iso8601SecondsDateParse("2010-08-10T12:00:00Z"))
|
||||||
.tenantId("12345")
|
.tenantId("12345")
|
||||||
.userId("joe")
|
.userId("joe")
|
||||||
.status(ImageStatus.SAVING)
|
.status(Status.SAVING)
|
||||||
.progress(80)
|
.progress(80)
|
||||||
.minDisk(5)
|
.minDisk(5)
|
||||||
.minRam(256)
|
.minRam(256)
|
||||||
|
|
|
@ -27,12 +27,12 @@ import org.jclouds.date.internal.SimpleDateFormatDateService;
|
||||||
import org.jclouds.json.BaseItemParserTest;
|
import org.jclouds.json.BaseItemParserTest;
|
||||||
import org.jclouds.json.config.GsonModule;
|
import org.jclouds.json.config.GsonModule;
|
||||||
import org.jclouds.openstack.domain.Link;
|
import org.jclouds.openstack.domain.Link;
|
||||||
import org.jclouds.openstack.domain.Link.Relation;
|
|
||||||
import org.jclouds.openstack.domain.Resource;
|
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.config.NovaParserModule;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.Address;
|
import org.jclouds.openstack.nova.v1_1.domain.Address;
|
||||||
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
import org.jclouds.openstack.nova.v1_1.domain.Server;
|
||||||
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.jclouds.rest.annotations.SelectJson;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ public class ParseServerTest extends BaseItemParserTest<Server> {
|
||||||
.hostId("e4d909c290d0fb1ca068ffaddf22cbd0")
|
.hostId("e4d909c290d0fb1ca068ffaddf22cbd0")
|
||||||
.accessIPv4("67.23.10.132")
|
.accessIPv4("67.23.10.132")
|
||||||
.accessIPv6("::babe:67.23.10.132")
|
.accessIPv6("::babe:67.23.10.132")
|
||||||
.status(ServerStatus.BUILD)
|
.status(Status.BUILD)
|
||||||
.image(
|
.image(
|
||||||
Resource
|
Resource
|
||||||
.builder()
|
.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